From fd2fb69f0fda19c25808a702d824e7f3759e5490 Mon Sep 17 00:00:00 2001 From: "renovate-rancher[bot]" <119870437+renovate-rancher[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 08:17:57 +0000 Subject: [PATCH] Update module github.com/go-openapi/spec to v0.22.5 --- go.mod | 18 +- go.sum | 48 +-- .../go-openapi/jsonpointer/.cliff.toml | 181 --------- .../go-openapi/jsonpointer/.gitignore | 1 - .../go-openapi/jsonpointer/CONTRIBUTORS.md | 7 +- .../github.com/go-openapi/jsonpointer/NOTICE | 2 +- .../go-openapi/jsonpointer/README.md | 54 +-- .../go-openapi/jsonpointer/errors.go | 26 +- .../go-openapi/jsonpointer/ifaces.go | 47 +++ .../go-openapi/jsonpointer/options.go | 86 +++++ .../go-openapi/jsonpointer/pointer.go | 348 ++++++++++++++---- vendor/github.com/go-openapi/spec/.gitignore | 1 - .../go-openapi/spec/CONTRIBUTORS.md | 6 +- vendor/github.com/go-openapi/spec/README.md | 2 +- .../swag/jsonname/go_name_provider.go | 286 ++++++++++++++ .../go-openapi/swag/jsonname/ifaces.go | 14 + .../go-openapi/swag/jsonname/name_provider.go | 2 + vendor/modules.txt | 36 +- 18 files changed, 820 insertions(+), 345 deletions(-) delete mode 100644 vendor/github.com/go-openapi/jsonpointer/.cliff.toml create mode 100644 vendor/github.com/go-openapi/jsonpointer/ifaces.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/options.go create mode 100644 vendor/github.com/go-openapi/swag/jsonname/go_name_provider.go create mode 100644 vendor/github.com/go-openapi/swag/jsonname/ifaces.go diff --git a/go.mod b/go.mod index 0a93718e4..62af8c859 100644 --- a/go.mod +++ b/go.mod @@ -69,24 +69,24 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.24.3 // indirect github.com/go-openapi/errors v0.22.7 // indirect - github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonpointer v0.23.1 // indirect github.com/go-openapi/jsonreference v0.21.5 // indirect github.com/go-openapi/loads v0.23.3 // indirect github.com/go-openapi/runtime v0.29.3 // indirect - github.com/go-openapi/spec v0.22.4 // indirect + github.com/go-openapi/spec v0.22.5 // indirect github.com/go-openapi/strfmt v0.26.1 // indirect github.com/go-openapi/swag v0.25.5 // indirect github.com/go-openapi/swag/cmdutils v0.25.5 // indirect - github.com/go-openapi/swag/conv v0.25.5 // indirect + github.com/go-openapi/swag/conv v0.26.0 // indirect github.com/go-openapi/swag/fileutils v0.25.5 // indirect - github.com/go-openapi/swag/jsonname v0.25.5 // indirect - github.com/go-openapi/swag/jsonutils v0.25.5 // indirect - github.com/go-openapi/swag/loading v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.26.0 // indirect + github.com/go-openapi/swag/jsonutils v0.26.0 // indirect + github.com/go-openapi/swag/loading v0.26.0 // indirect github.com/go-openapi/swag/mangling v0.25.5 // indirect github.com/go-openapi/swag/netutils v0.25.5 // indirect - github.com/go-openapi/swag/stringutils v0.25.5 // indirect - github.com/go-openapi/swag/typeutils v0.25.5 // indirect - github.com/go-openapi/swag/yamlutils v0.25.5 // indirect + github.com/go-openapi/swag/stringutils v0.26.0 // indirect + github.com/go-openapi/swag/typeutils v0.26.0 // indirect + github.com/go-openapi/swag/yamlutils v0.26.0 // indirect github.com/go-openapi/validate v0.25.2 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect diff --git a/go.sum b/go.sum index e307fe795..6e705dde6 100644 --- a/go.sum +++ b/go.sum @@ -200,48 +200,48 @@ github.com/go-openapi/analysis v0.24.3 h1:a1hrvMr8X0Xt69KP5uVTu5jH62DscmDifrLzNg github.com/go-openapi/analysis v0.24.3/go.mod h1:Nc+dWJ/FxZbhSow5Yh3ozg5CLJioB+XXT6MdLvJUsUw= github.com/go-openapi/errors v0.22.7 h1:JLFBGC0Apwdzw3484MmBqspjPbwa2SHvpDm0u5aGhUA= github.com/go-openapi/errors v0.22.7/go.mod h1://QW6SD9OsWtH6gHllUCddOXDL0tk0ZGNYHwsw4sW3w= -github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= -github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonpointer v0.23.1 h1:1HBACs7XIwR2RcmItfdSFlALhGbe6S92p0ry4d1GWg4= +github.com/go-openapi/jsonpointer v0.23.1/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= github.com/go-openapi/loads v0.23.3 h1:g5Xap1JfwKkUnZdn+S0L3SzBDpcTIYzZ5Qaag0YDkKQ= github.com/go-openapi/loads v0.23.3/go.mod h1:NOH07zLajXo8y55hom0omlHWDVVvCwBM/S+csCK8LqA= github.com/go-openapi/runtime v0.29.3 h1:h5twGaEqxtQg40ePiYm9vFFH1q06Czd7Ot6ufdK0w/Y= github.com/go-openapi/runtime v0.29.3/go.mod h1:8A1W0/L5eyNJvKciqZtvIVQvYO66NlB7INMSZ9bw/oI= -github.com/go-openapi/spec v0.22.4 h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ= -github.com/go-openapi/spec v0.22.4/go.mod h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ= +github.com/go-openapi/spec v0.22.5 h1:KhO7RBlKQfonUWX2WzQCoLIXVA6AcNqDGZ3a1Dutdlo= +github.com/go-openapi/spec v0.22.5/go.mod h1:vxpOtMya5TXtENXKE5bKqv5NjocVhyhxHrlZfvKnZ74= github.com/go-openapi/strfmt v0.26.1 h1:7zGCHji7zSYDC2tCXIusoxYQz/48jAf2q+sF6wXTG+c= github.com/go-openapi/strfmt v0.26.1/go.mod h1:Zslk5VZPOISLwmWTMBIS7oiVFem1o1EI6zULY8Uer7Y= github.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU= github.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA= github.com/go-openapi/swag/cmdutils v0.25.5 h1:yh5hHrpgsw4NwM9KAEtaDTXILYzdXh/I8Whhx9hKj7c= github.com/go-openapi/swag/cmdutils v0.25.5/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= -github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= -github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= +github.com/go-openapi/swag/conv v0.26.0 h1:5yGGsPYI1ZCva93U0AoKi/iZrNhaJEjr324YVsiD89I= +github.com/go-openapi/swag/conv v0.26.0/go.mod h1:tpAmIL7X58VPnHHiSO4uE3jBeRamGsFsfdDeDtb5ECE= github.com/go-openapi/swag/fileutils v0.25.5 h1:B6JTdOcs2c0dBIs9HnkyTW+5gC+8NIhVBUwERkFhMWk= github.com/go-openapi/swag/fileutils v0.25.5/go.mod h1:V3cT9UdMQIaH4WiTrUc9EPtVA4txS0TOmRURmhGF4kc= -github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= -github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= -github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= -github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo= -github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= -github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= +github.com/go-openapi/swag/jsonname v0.26.0 h1:gV1NFX9M8avo0YSpmWogqfQISigCmpaiNci8cGECU5w= +github.com/go-openapi/swag/jsonname v0.26.0/go.mod h1:urBBR8bZNoDYGr653ynhIx+gTeIz0ARZxHkAPktJK2M= +github.com/go-openapi/swag/jsonutils v0.26.0 h1:FawFML2iAXsPqmERscuMPIHmFsoP1tOqWkxBaKNMsnA= +github.com/go-openapi/swag/jsonutils v0.26.0/go.mod h1:2VmA0CJlyFqgawOaPI9psnjFDqzyivIqLYN34t9p91E= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.26.0 h1:apqeINu/ICHouqiRZbyFvuDge5jCmmLTqGQ9V95EaOM= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.26.0/go.mod h1:AyM6QT8uz5IdKxk5akv0y6u4QvcL9GWERt0Jx/F/R8Y= +github.com/go-openapi/swag/loading v0.26.0 h1:Apg6zaKhCJurpJer0DCxq99qwmhFddBhaMX7kilDcko= +github.com/go-openapi/swag/loading v0.26.0/go.mod h1:dBxQ/6V2uBaAQdevN18VELE6xSpJWZxLX4txe12JwDg= github.com/go-openapi/swag/mangling v0.25.5 h1:hyrnvbQRS7vKePQPHHDso+k6CGn5ZBs5232UqWZmJZw= github.com/go-openapi/swag/mangling v0.25.5/go.mod h1:6hadXM/o312N/h98RwByLg088U61TPGiltQn71Iw0NY= github.com/go-openapi/swag/netutils v0.25.5 h1:LZq2Xc2QI8+7838elRAaPCeqJnHODfSyOa7ZGfxDKlU= github.com/go-openapi/swag/netutils v0.25.5/go.mod h1:lHbtmj4m57APG/8H7ZcMMSWzNqIQcu0RFiXrPUara14= -github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= -github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= -github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= -github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= -github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= -github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= -github.com/go-openapi/testify/enable/yaml/v2 v2.4.1 h1:NZOrZmIb6PTv5LTFxr5/mKV/FjbUzGE7E6gLz7vFoOQ= -github.com/go-openapi/testify/enable/yaml/v2 v2.4.1/go.mod h1:r7dwsujEHawapMsxA69i+XMGZrQ5tRauhLAjV/sxg3Q= -github.com/go-openapi/testify/v2 v2.4.1 h1:zB34HDKj4tHwyUQHrUkpV0Q0iXQ6dUCOQtIqn8hE6Iw= -github.com/go-openapi/testify/v2 v2.4.1/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-openapi/swag/stringutils v0.26.0 h1:qZQngLxs5s7SLijc3N2ZO+fUq2o8LjuWAASSrJuh+xg= +github.com/go-openapi/swag/stringutils v0.26.0/go.mod h1:sWn5uY+QIIspwPhvgnqJsH8xqFT2ZbYcvbcFanRyhFE= +github.com/go-openapi/swag/typeutils v0.26.0 h1:2kdEwdiNWy+JJdOvu5MA2IIg2SylWAFuuyQIKYybfq4= +github.com/go-openapi/swag/typeutils v0.26.0/go.mod h1:oovDuIUvTrEHVMqWilQzKzV4YlSKgyZmFh7AlfABNVE= +github.com/go-openapi/swag/yamlutils v0.26.0 h1:H7O8l/8NJJQ/oiReEN+oMpnGMyt8G0hl460nRZxhLMQ= +github.com/go-openapi/swag/yamlutils v0.26.0/go.mod h1:1evKEGAtP37Pkwcc7EWMF0hedX0/x3Rkvei2wtG/TbU= +github.com/go-openapi/testify/enable/yaml/v2 v2.5.1 h1:q9NtHwK4qHF7yZziBPvZyv7zWAIk8ok88Gh2mR6Jpc8= +github.com/go-openapi/testify/enable/yaml/v2 v2.5.1/go.mod h1:JW0MXIotCYps/XsgJnG3a8Q7rE5xAiBwoOD5OfaIQBk= +github.com/go-openapi/testify/v2 v2.5.1 h1:TMdhCaw8fUNraVSf3Omoob1dO/AzBfhtFAPW0an6sBo= +github.com/go-openapi/testify/v2 v2.5.1/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/go-openapi/validate v0.25.2 h1:12NsfLAwGegqbGWr2CnvT65X/Q2USJipmJ9b7xDJZz0= github.com/go-openapi/validate v0.25.2/go.mod h1:Pgl1LpPPGFnZ+ys4/hTlDiRYQdI1ocKypgE+8Q8BLfY= github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA= diff --git a/vendor/github.com/go-openapi/jsonpointer/.cliff.toml b/vendor/github.com/go-openapi/jsonpointer/.cliff.toml deleted file mode 100644 index 702629f5d..000000000 --- a/vendor/github.com/go-openapi/jsonpointer/.cliff.toml +++ /dev/null @@ -1,181 +0,0 @@ -# git-cliff ~ configuration file -# https://git-cliff.org/docs/configuration - -[changelog] -header = """ -""" - -footer = """ - ------ - -**[{{ remote.github.repo }}]({{ self::remote_url() }}) license terms** - -[![License][license-badge]][license-url] - -[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg -[license-url]: {{ self::remote_url() }}/?tab=Apache-2.0-1-ov-file#readme - -{%- macro remote_url() -%} - https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} -{%- endmacro -%} -""" - -body = """ -{%- if version %} -## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/tree/{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }} -{%- else %} -## [unreleased] -{%- endif %} -{%- if message %} - {%- raw %}\n{% endraw %} -{{ message }} - {%- raw %}\n{% endraw %} -{%- endif %} -{%- if version %} - {%- if previous.version %} - -**Full Changelog**: <{{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }}> - {%- endif %} -{%- else %} - {%- raw %}\n{% endraw %} -{%- endif %} - -{%- if statistics %}{% if statistics.commit_count %} - {%- raw %}\n{% endraw %} -{{ statistics.commit_count }} commits in this release. - {%- raw %}\n{% endraw %} -{%- endif %}{% endif %} ------ - -{%- for group, commits in commits | group_by(attribute="group") %} - {%- raw %}\n{% endraw %} -### {{ group | upper_first }} - {%- raw %}\n{% endraw %} - {%- for commit in commits %} - {%- if commit.remote.pr_title %} - {%- set commit_message = commit.remote.pr_title %} - {%- else %} - {%- set commit_message = commit.message %} - {%- endif %} -* {{ commit_message | split(pat="\n") | first | trim }} - {%- if commit.remote.username %} -{%- raw %} {% endraw %}by [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }}) - {%- endif %} - {%- if commit.remote.pr_number %} -{%- raw %} {% endraw %}in [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) - {%- endif %} -{%- raw %} {% endraw %}[...]({{ self::remote_url() }}/commit/{{ commit.id }}) - {%- endfor %} -{%- endfor %} - -{%- if github %} -{%- raw %}\n{% endraw -%} - {%- set all_contributors = github.contributors | length %} - {%- if github.contributors | filter(attribute="username", value="dependabot[bot]") | length < all_contributors %} ------ - -### People who contributed to this release - {% endif %} - {%- for contributor in github.contributors | filter(attribute="username") | sort(attribute="username") %} - {%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %} -* [@{{ contributor.username }}](https://github.com/{{ contributor.username }}) - {%- endif %} - {%- endfor %} - - {% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %} ------ - {%- raw %}\n{% endraw %} - -### New Contributors - {%- endif %} - - {%- for contributor in github.contributors | filter(attribute="is_first_time", value=true) %} - {%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %} -* @{{ contributor.username }} made their first contribution - {%- if contributor.pr_number %} - in [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \ - {%- endif %} - {%- endif %} - {%- endfor %} -{%- endif %} - -{%- raw %}\n{% endraw %} - -{%- macro remote_url() -%} - https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} -{%- endmacro -%} -""" -# Remove leading and trailing whitespaces from the changelog's body. -trim = true -# Render body even when there are no releases to process. -render_always = true -# An array of regex based postprocessors to modify the changelog. -postprocessors = [ - # Replace the placeholder with a URL. - #{ pattern = '', replace = "https://github.com/orhun/git-cliff" }, -] -# output file path -# output = "test.md" - -[git] -# Parse commits according to the conventional commits specification. -# See https://www.conventionalcommits.org -conventional_commits = false -# Exclude commits that do not match the conventional commits specification. -filter_unconventional = false -# Require all commits to be conventional. -# Takes precedence over filter_unconventional. -require_conventional = false -# Split commits on newlines, treating each line as an individual commit. -split_commits = false -# An array of regex based parsers to modify commit messages prior to further processing. -commit_preprocessors = [ - # Replace issue numbers with link templates to be updated in `changelog.postprocessors`. - #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, - # Check spelling of the commit message using https://github.com/crate-ci/typos. - # If the spelling is incorrect, it will be fixed automatically. - #{ pattern = '.*', replace_command = 'typos --write-changes -' } -] -# Prevent commits that are breaking from being excluded by commit parsers. -protect_breaking_commits = false -# An array of regex based parsers for extracting data from the commit message. -# Assigns commits to groups. -# Optionally sets the commit's scope and can decide to exclude commits from further processing. -commit_parsers = [ - { message = "^[Cc]hore\\([Rr]elease\\): prepare for", skip = true }, - { message = "(^[Mm]erge)|([Mm]erge conflict)", skip = true }, - { field = "author.name", pattern = "dependabot*", group = "Updates" }, - { message = "([Ss]ecurity)|([Vv]uln)", group = "Security" }, - { body = "(.*[Ss]ecurity)|([Vv]uln)", group = "Security" }, - { message = "([Cc]hore\\(lint\\))|(style)|(lint)|(codeql)|(golangci)", group = "Code quality" }, - { message = "(^[Dd]oc)|((?i)readme)|(badge)|(typo)|(documentation)", group = "Documentation" }, - { message = "(^[Ff]eat)|(^[Ee]nhancement)", group = "Implemented enhancements" }, - { message = "(^ci)|(\\(ci\\))|(fixup\\s+ci)|(fix\\s+ci)|(license)|(example)", group = "Miscellaneous tasks" }, - { message = "^test", group = "Testing" }, - { message = "(^fix)|(panic)", group = "Fixed bugs" }, - { message = "(^refact)|(rework)", group = "Refactor" }, - { message = "(^[Pp]erf)|(performance)", group = "Performance" }, - { message = "(^[Cc]hore)", group = "Miscellaneous tasks" }, - { message = "^[Rr]evert", group = "Reverted changes" }, - { message = "(upgrade.*?go)|(go\\s+version)", group = "Updates" }, - { message = ".*", group = "Other" }, -] -# Exclude commits that are not matched by any commit parser. -filter_commits = false -# An array of link parsers for extracting external references, and turning them into URLs, using regex. -link_parsers = [] -# Include only the tags that belong to the current branch. -use_branch_tags = false -# Order releases topologically instead of chronologically. -topo_order = false -# Order releases topologically instead of chronologically. -topo_order_commits = true -# Order of commits in each group/release within the changelog. -# Allowed values: newest, oldest -sort_commits = "newest" -# Process submodules commits -recurse_submodules = false - -#[remote.github] -#owner = "go-openapi" diff --git a/vendor/github.com/go-openapi/jsonpointer/.gitignore b/vendor/github.com/go-openapi/jsonpointer/.gitignore index 885dc27ab..d8f4186fe 100644 --- a/vendor/github.com/go-openapi/jsonpointer/.gitignore +++ b/vendor/github.com/go-openapi/jsonpointer/.gitignore @@ -3,4 +3,3 @@ .idea .env .mcp.json -.claude/ diff --git a/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md b/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md index 2ebebedc1..9990f4a35 100644 --- a/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md @@ -4,11 +4,11 @@ | Total Contributors | Total Contributions | | --- | --- | -| 12 | 101 | +| 13 | 111 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | -| @fredbi | 54 | | +| @fredbi | 63 | | | @casualjim | 33 | | | @magodo | 3 | | | @youyuanwu | 3 | | @@ -18,7 +18,8 @@ | @ianlancetaylor | 1 | | | @mfleader | 1 | | | @Neo2308 | 1 | | +| @alexandear | 1 | | | @olivierlemasle | 1 | | | @testwill | 1 | | - _this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_ + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/jsonpointer/NOTICE b/vendor/github.com/go-openapi/jsonpointer/NOTICE index f3b51939a..201908d2f 100644 --- a/vendor/github.com/go-openapi/jsonpointer/NOTICE +++ b/vendor/github.com/go-openapi/jsonpointer/NOTICE @@ -18,7 +18,7 @@ It ships with copies of other software which license terms are recalled below. The original software was authored on 25-02-2013 by sigu-399 (https://github.com/sigu-399, sigu.399@gmail.com). -github.com/sigh-399/jsonpointer +github.com/sigu-399/jsonpointer =========================== // SPDX-FileCopyrightText: Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) diff --git a/vendor/github.com/go-openapi/jsonpointer/README.md b/vendor/github.com/go-openapi/jsonpointer/README.md index c52803e2e..24fbe1bf6 100644 --- a/vendor/github.com/go-openapi/jsonpointer/README.md +++ b/vendor/github.com/go-openapi/jsonpointer/README.md @@ -16,17 +16,25 @@ An implementation of JSON Pointer for golang, which supports go `struct`. ## Announcements -* **2025-12-19** : new community chat on discord - * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** - -You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] - -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] +* **2026-04-15** : added support for trailing "-" for arrays (v0.23.0) + * this brings full support of [RFC6901][RFC6901] + * this is supported for types relying on the reflection-based implemented + * API semantics remain essentially unaltered. Exception: `Pointer.Set(document any,value any) (document any, err error)` + can only perform a best-effort to mutate the input document in place. In the case of adding elements to an array with a + trailing "-", either pass a mutable array (`*[]T`) as the input document, or use the returned updated document instead. + * types that implement the `JSONSetable` interface may not implement the mutation implied by the trailing "-" + +* **2026-04-15** : added support for optional alternate JSON name providers + * for struct support the defaults might not suit all situations: there are known limitations + when it comes to handle untagged fields or embedded types. + * the default name provider in use is not fully aligned with go JSON stdlib + * exposed an option (or global setting) to change the provider that resolves a struct into json keys + * the default behavior is not altered + * a new alternate name provider is added (imported from `go-openapi/swag/jsonname`), aligned with JSON stdlib behavior ## Status -API is stable. +API is stable and feature-complete. ## Import this library in your project @@ -88,7 +96,7 @@ See -also known as [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) +also known as [RFC6901][RFC6901]. ## Licensing @@ -99,19 +107,19 @@ on top of which it has been built. ## Limitations -The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, -the reference token MUST contain either...' is not implemented. - -That is because our implementation of the JSON pointer only supports explicit references to array elements: -the provision in the spec to resolve non-existent members as "the last element in the array", -using the special trailing character "-" is not implemented. +* [RFC6901][RFC6901] is now fully supported, including trailing "-" semantics for arrays (for `Set` operations). +* Default behavior: JSON name detection in go `struct`s + - Unlike go standard marshaling, untagged fields do not default to the go field name and are ignored. + - anonymous fields are not traversed if untagged + - the above limitations may be overcome by calling `UseGoNameProvider()` at initialization time. + - alternatively, users may inject the desired custom behavior for naming fields as an option. ## Other documentation * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -142,11 +150,8 @@ Maintainers can cut a new release by either: [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer [godoc-url]: http://pkg.go.dev/github.com/go-openapi/jsonpointer -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue -[discord-url]: https://discord.gg/twZ9BwT3 +[discord-url]: https://discord.gg/FfnFYaC3k5 [license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg @@ -156,3 +161,8 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/jsonpointer/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/jsonpointer [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/jsonpointer/latest +[RFC6901]: https://www.rfc-editor.org/rfc/rfc6901 + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/jsonpointer/errors.go b/vendor/github.com/go-openapi/jsonpointer/errors.go index 8c50dde8b..8813474d4 100644 --- a/vendor/github.com/go-openapi/jsonpointer/errors.go +++ b/vendor/github.com/go-openapi/jsonpointer/errors.go @@ -16,12 +16,24 @@ const ( ErrPointer pointerError = "JSON pointer error" // ErrInvalidStart states that a JSON pointer must start with a separator ("/"). - ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator + ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator + `"` // ErrUnsupportedValueType indicates that a value of the wrong type is being set. ErrUnsupportedValueType pointerError = "only structs, pointers, maps and slices are supported for setting values" + + // ErrDashToken indicates use of the RFC 6901 "-" reference token + // in a context where it cannot be resolved. + // + // Per RFC 6901 §4 the "-" token refers to the (nonexistent) element + // after the last array element. It may only be used as the terminal + // token of a [Pointer.Set] against a slice, where it means "append". + // Any other use (get, offset, intermediate traversal, non-slice target) + // is an error condition that wraps this sentinel. + ErrDashToken pointerError = `the "-" array token cannot be resolved here` //nolint:gosec // G101 false positive: this is a JSON Pointer reference token, not a credential. ) +const dashToken = "-" + func errNoKey(key string) error { return fmt.Errorf("object has no key %q: %w", key, ErrPointer) } @@ -33,3 +45,15 @@ func errOutOfBounds(length, idx int) error { func errInvalidReference(token string) error { return fmt.Errorf("invalid token reference %q: %w", token, ErrPointer) } + +func errDashOnGet() error { + return fmt.Errorf("cannot resolve %q token on get: %w: %w", dashToken, ErrDashToken, ErrPointer) +} + +func errDashIntermediate() error { + return fmt.Errorf("the %q token may only appear as the terminal token of a pointer: %w: %w", dashToken, ErrDashToken, ErrPointer) +} + +func errDashOnOffset() error { + return fmt.Errorf("cannot compute offset for %q token (nonexistent element): %w: %w", dashToken, ErrDashToken, ErrPointer) +} diff --git a/vendor/github.com/go-openapi/jsonpointer/ifaces.go b/vendor/github.com/go-openapi/jsonpointer/ifaces.go new file mode 100644 index 000000000..1e56ac044 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/ifaces.go @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonpointer + +import "reflect" + +// JSONPointable is an interface for structs to implement, +// when they need to customize the json pointer process or want to avoid the use of reflection. +type JSONPointable interface { + // JSONLookup returns a value pointed at this (unescaped) key. + JSONLookup(key string) (any, error) +} + +// JSONSetable is an interface for structs to implement, +// when they need to customize the json pointer process or want to avoid the use of reflection. +// +// # Handling of the RFC 6901 "-" token +// +// When a type implementing JSONSetable is the terminal parent of a [Pointer.Set] +// call, the library passes the raw reference token to JSONSet without +// interpretation. In particular, the RFC 6901 "-" token (which conventionally +// means "append" for arrays, per RFC 6902) is forwarded verbatim as the key +// argument. Implementations that model an array-like container are expected +// to give "-" the append semantics; implementations that do not should return +// an error wrapping [ErrDashToken] (or [ErrPointer]) for clarity. +// +// Implementations are responsible for any in-place mutation: the library does +// not attempt to rebind the result of JSONSet into a parent container. +type JSONSetable interface { + // JSONSet sets the value pointed at the (unescaped) key. + // + // The key may be the RFC 6901 "-" token when the pointer targets a + // slice-like member; see the interface documentation for details. + JSONSet(key string, value any) error +} + +// NameProvider knows how to resolve go struct fields into json names. +// +// The default provider is brought by [github.com/go-openapi/swag/jsonname.DefaultJSONNameProvider]. +type NameProvider interface { + // GetGoName gets the go name for a json property name + GetGoName(subject any, name string) (string, bool) + + // GetGoNameForType gets the go name for a given type for a json property name + GetGoNameForType(tpe reflect.Type, name string) (string, bool) +} diff --git a/vendor/github.com/go-openapi/jsonpointer/options.go b/vendor/github.com/go-openapi/jsonpointer/options.go new file mode 100644 index 000000000..d52caab22 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/options.go @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonpointer + +import ( + "sync" + + "github.com/go-openapi/swag/jsonname" +) + +// Option to tune the behavior of a JSON [Pointer]. +type Option func(*options) + +var ( + //nolint:gochecknoglobals // package level defaults are provided as a convenient, backward-compatible way to adopt options. + defaultOptions = options{ + provider: jsonname.DefaultJSONNameProvider, + } + //nolint:gochecknoglobals // guards defaultOptions against concurrent SetDefaultNameProvider / read races (testing) + defaultOptionsMu sync.RWMutex +) + +// SetDefaultNameProvider sets the [NameProvider] as a package-level default. +// +// By default, the default provider is [jsonname.DefaultJSONNameProvider]. +// +// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], +// [GetForToken] and [SetForToken]. The typical usage is to call it once +// at initialization time. +// +// A nil provider is ignored. +func SetDefaultNameProvider(provider NameProvider) { + if provider == nil { + return + } + + defaultOptionsMu.Lock() + defer defaultOptionsMu.Unlock() + + defaultOptions.provider = provider +} + +// UseGoNameProvider sets the [NameProvider] as a package-level default +// to the alternative provider [jsonname.GoNameProvider], that covers a few areas +// not supported by the default name provider. +// +// This implementation supports untagged exported fields and embedded types in go struct. +// It follows strictly the behavior of the JSON standard library regarding field naming conventions. +// +// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], +// [GetForToken] and [SetForToken]. The typical usage is to call it once +// at initialization time. +func UseGoNameProvider() { + SetDefaultNameProvider(jsonname.NewGoNameProvider()) +} + +// DefaultNameProvider returns the current package-level [NameProvider]. +func DefaultNameProvider() NameProvider { //nolint:ireturn // returning the interface is the point — callers pick their own implementation. + defaultOptionsMu.RLock() + defer defaultOptionsMu.RUnlock() + + return defaultOptions.provider +} + +// WithNameProvider injects a custom [NameProvider] to resolve json names from go struct types. +func WithNameProvider(provider NameProvider) Option { + return func(o *options) { + o.provider = provider + } +} + +type options struct { + provider NameProvider +} + +func optionsWithDefaults(opts []Option) options { + var o options + o.provider = DefaultNameProvider() + + for _, apply := range opts { + apply(&o) + } + + return o +} diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go index 7df49af3b..2369c1827 100644 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go @@ -11,8 +11,6 @@ import ( "reflect" "strconv" "strings" - - "github.com/go-openapi/swag/jsonname" ) const ( @@ -20,20 +18,6 @@ const ( pointerSeparator = `/` ) -// JSONPointable is an interface for structs to implement, -// when they need to customize the json pointer process or want to avoid the use of reflection. -type JSONPointable interface { - // JSONLookup returns a value pointed at this (unescaped) key. - JSONLookup(key string) (any, error) -} - -// JSONSetable is an interface for structs to implement, -// when they need to customize the json pointer process or want to avoid the use of reflection. -type JSONSetable interface { - // JSONSet sets the value pointed at the (unescaped) key. - JSONSet(key string, value any) error -} - // Pointer is a representation of a json pointer. // // Use [Pointer.Get] to retrieve a value or [Pointer.Set] to set a value. @@ -41,7 +25,7 @@ type JSONSetable interface { // It works with any go type interpreted as a JSON document, which means: // // - if a type implements [JSONPointable], its [JSONPointable.JSONLookup] method is used to resolve [Pointer.Get] -// - if a type implements [JSONSetable], its [JSONPointable.JSONSet] method is used to resolve [Pointer.Set] +// - if a type implements [JSONSetable], its [JSONSetable.JSONSet] method is used to resolve [Pointer.Set] // - a go map[K]V is interpreted as an object, with type K assignable to a string // - a go slice []T is interpreted as an array // - a go struct is interpreted as an object, with exported fields interpreted as keys @@ -71,16 +55,35 @@ func New(jsonPointerString string) (Pointer, error) { // Get uses the pointer to retrieve a value from a JSON document. // // It returns the value with its type as a [reflect.Kind] or an error. -func (p *Pointer) Get(document any) (any, reflect.Kind, error) { - return p.get(document, jsonname.DefaultJSONNameProvider) +func (p *Pointer) Get(document any, opts ...Option) (any, reflect.Kind, error) { + o := optionsWithDefaults(opts) + + return p.get(document, o.provider) } // Set uses the pointer to set a value from a data type // that represent a JSON document. // -// It returns the updated document. -func (p *Pointer) Set(document any, value any) (any, error) { - return document, p.set(document, value, jsonname.DefaultJSONNameProvider) +// # Mutation contract +// +// Set mutates the provided document in place whenever Go's type system allows +// it: when document is a map, a pointer, or when the targeted value is reached +// through an addressable ancestor (e.g. a struct field traversed via a pointer, +// a slice element). Callers that rely on this in-place behavior may continue +// to ignore the returned document. +// +// The returned document is only load-bearing when Set cannot mutate in place. +// This happens in one specific case: appending to a top-level slice passed by +// value (e.g. document of type []T rather than *[]T) via the RFC 6901 "-" +// terminal token. reflect.Append produces a new slice header that the library +// cannot rebind into the caller's variable; the updated document is returned +// instead. Pass *[]T if you want in-place rebind for that case as well. +// +// See [ErrDashToken] for the semantics of the "-" token. +func (p *Pointer) Set(document any, value any, opts ...Option) (any, error) { + o := optionsWithDefaults(opts) + + return p.set(document, value, o.provider) } // DecodedTokens returns the decoded (unescaped) tokens of this JSON pointer. @@ -109,6 +112,46 @@ func (p *Pointer) String() string { return pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator) } +// Offset returns the byte offset, in the raw JSON text of document, of the +// location referenced by this pointer's terminal token. +// +// Unlike [Pointer.Get] and [Pointer.Set], which operate on a decoded Go value, +// Offset operates directly on the textual JSON source. It drives an +// [encoding/json.Decoder] over the string and stops at the terminal token, +// returning the position at which the decoder was about to read that token. +// +// It is primarily intended for tooling that needs to map a pointer back to a +// region of the original source: reporting line/column for validation or +// parse diagnostics, extracting a sub-document by slicing the raw bytes, or +// highlighting the referenced span in an editor. +// +// # Offset semantics +// +// The meaning of the returned offset depends on whether the terminal token +// addresses an object property or an array element: +// +// - Object property: the offset points to the first byte of the key (its +// opening quote character), not to the associated value. For example, +// pointer "/foo/bar" against {"foo": {"bar": 21}} returns 9, the index of +// the opening quote of "bar". +// - Array element: the offset points to the first byte of the value at that +// index. For example, pointer "/0/1" against [[1,2], [3,4]] returns 4, +// the index of the digit 2. +// +// # Errors +// +// Offset returns an error in any of these cases: +// +// - document is not syntactically valid JSON; +// - the structure of document does not match the pointer (e.g. traversing +// into a scalar, or a token that is neither a valid key nor a valid +// numeric index); +// - a referenced key or index does not exist in document; +// - the pointer's terminal token is the RFC 6901 "-" array token, which +// designates a nonexistent element and therefore has no offset in the +// source. The returned error wraps [ErrDashToken]. +// +// All errors wrap [ErrPointer]. func (p *Pointer) Offset(document string) (int64, error) { dec := json.NewDecoder(strings.NewReader(document)) var offset int64 @@ -137,7 +180,35 @@ func (p *Pointer) Offset(document string) (int64, error) { return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) } } - return offset, nil + return skipJSONSeparator(document, offset), nil +} + +// skipJSONSeparator advances offset past trailing JSON whitespace and at most +// one value separator (comma) in document, so the result points at the first +// byte of the next JSON token. +// +// The streaming decoder's InputOffset sits right after the most recently +// consumed token, which between values is the comma (or whitespace) — not +// the following token. Normalizing here keeps Offset's contract uniform: +// for both object keys and array elements, and regardless of position within +// the parent container, the returned offset always points at the first byte +// of the addressed token. +func skipJSONSeparator(document string, offset int64) int64 { + n := int64(len(document)) + for offset < n && isJSONWhitespace(document[offset]) { + offset++ + } + if offset < n && document[offset] == ',' { + offset++ + } + for offset < n && isJSONWhitespace(document[offset]) { + offset++ + } + return offset +} + +func isJSONWhitespace(c byte) bool { + return c == ' ' || c == '\t' || c == '\n' || c == '\r' } // "Constructor", parses the given string JSON pointer. @@ -157,9 +228,9 @@ func (p *Pointer) parse(jsonPointerString string) error { return nil } -func (p *Pointer) get(node any, nameProvider *jsonname.NameProvider) (any, reflect.Kind, error) { +func (p *Pointer) get(node any, nameProvider NameProvider) (any, reflect.Kind, error) { if nameProvider == nil { - nameProvider = jsonname.DefaultJSONNameProvider + nameProvider = defaultOptions.provider } kind := reflect.Invalid @@ -185,50 +256,130 @@ func (p *Pointer) get(node any, nameProvider *jsonname.NameProvider) (any, refle return node, kind, nil } -func (p *Pointer) set(node, data any, nameProvider *jsonname.NameProvider) error { +func (p *Pointer) set(node, data any, nameProvider NameProvider) (any, error) { knd := reflect.ValueOf(node).Kind() if knd != reflect.Pointer && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { - return errors.Join( + return node, errors.Join( fmt.Errorf("unexpected type: %T", node), //nolint:err113 // err wrapping is carried out by errors.Join, not fmt.Errorf. ErrUnsupportedValueType, ErrPointer, ) } - l := len(p.referenceTokens) - // full document when empty - if l == 0 { - return nil + if len(p.referenceTokens) == 0 { + return node, nil } if nameProvider == nil { - nameProvider = jsonname.DefaultJSONNameProvider + nameProvider = defaultOptions.provider } - var decodedToken string - lastIndex := l - 1 + return p.setAt(node, p.referenceTokens, data, nameProvider) +} - if lastIndex > 0 { // skip if we only have one token in pointer - for _, token := range p.referenceTokens[:lastIndex] { - decodedToken = Unescape(token) - next, err := p.resolveNodeForToken(node, decodedToken, nameProvider) - if err != nil { - return err - } +// setAt recursively walks the token list, setting the data at the terminal +// token and rebinding any new child reference (e.g. a slice header returned +// by an "-" append) into its parent on the way back up. +// +// Returning the (possibly new) node at each level is what makes append work +// at any depth without requiring the caller to pass a pointer to the +// containing slice: the new slice header propagates up and each parent +// rebinds it via the appropriate kind-specific setter. +func (p *Pointer) setAt(node any, tokens []string, data any, nameProvider NameProvider) (any, error) { + decodedToken := Unescape(tokens[0]) + + if len(tokens) == 1 { + return setSingleImpl(node, data, decodedToken, nameProvider) + } - node = next - } + child, err := p.resolveNodeForToken(node, decodedToken, nameProvider) + if err != nil { + return node, err + } + + newChild, err := p.setAt(child, tokens[1:], data, nameProvider) + if err != nil { + return node, err } - // last token - decodedToken = Unescape(p.referenceTokens[lastIndex]) + return rebindChild(node, decodedToken, newChild, nameProvider) +} + +// rebindChild writes newChild back into node at decodedToken. +// +// For cases where the child was already mutated in place (pointer aliasing, +// addressable slice elements) the rebind is a safe no-op. For cases where +// the child was returned by value (map entries holding a slice, slices +// reached through a non-addressable ancestor), the rebind propagates the +// new value into the parent. +// +// Parents implementing [JSONPointable] are left alone: they took ownership +// of the child via JSONLookup and did not opt into a JSONSet-based rebind +// on intermediate tokens. +func rebindChild(node any, decodedToken string, newChild any, nameProvider NameProvider) (any, error) { + if _, ok := node.(JSONPointable); ok { + return node, nil + } + + rValue := reflect.Indirect(reflect.ValueOf(node)) + + switch rValue.Kind() { + case reflect.Struct: + nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) + if !ok { + return node, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) + } + fld := rValue.FieldByName(nm) + if !fld.CanSet() { + return node, nil + } + assignReflectValue(fld, newChild) + return node, nil + + case reflect.Map: + rValue.SetMapIndex(reflect.ValueOf(decodedToken), reflect.ValueOf(newChild)) + return node, nil + + case reflect.Slice: + if decodedToken == dashToken { + return node, errDashIntermediate() + } + idx, err := strconv.Atoi(decodedToken) + if err != nil { + return node, errors.Join(err, ErrPointer) + } + elem := rValue.Index(idx) + if !elem.CanSet() { + return node, nil + } + assignReflectValue(elem, newChild) + return node, nil + + default: + return node, errInvalidReference(decodedToken) + } +} - return setSingleImpl(node, data, decodedToken, nameProvider) +// assignReflectValue assigns src into dst, unwrapping a pointer when dst +// expects the pointee type. This tolerates the pointer-wrapping performed +// by [typeFromValue] for addressable fields. +func assignReflectValue(dst reflect.Value, src any) { + nv := reflect.ValueOf(src) + if !nv.IsValid() { + return + } + if nv.Type().AssignableTo(dst.Type()) { + dst.Set(nv) + return + } + if nv.Kind() == reflect.Pointer && nv.Elem().Type().AssignableTo(dst.Type()) { + dst.Set(nv.Elem()) + } } -func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvider *jsonname.NameProvider) (next any, err error) { +func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvider NameProvider) (next any, err error) { // check for nil during traversal if isNil(node) { return nil, fmt.Errorf("cannot traverse through nil value at %q: %w", decodedToken, ErrPointer) @@ -272,6 +423,9 @@ func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvide return typeFromValue(mv), nil case reflect.Slice: + if decodedToken == dashToken { + return nil, errDashIntermediate() + } tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { return nil, errors.Join(err, ErrPointer) @@ -312,16 +466,23 @@ func typeFromValue(v reflect.Value) any { } // GetForToken gets a value for a json pointer token 1 level deep. -func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) { - return getSingleImpl(document, decodedToken, jsonname.DefaultJSONNameProvider) +func GetForToken(document any, decodedToken string, opts ...Option) (any, reflect.Kind, error) { + o := optionsWithDefaults(opts) + + return getSingleImpl(document, decodedToken, o.provider) } // SetForToken sets a value for a json pointer token 1 level deep. -func SetForToken(document any, decodedToken string, value any) (any, error) { - return document, setSingleImpl(document, value, decodedToken, jsonname.DefaultJSONNameProvider) +// +// See [Pointer.Set] for the mutation contract, in particular the handling of +// the RFC 6901 "-" token on slices. +func SetForToken(document any, decodedToken string, value any, opts ...Option) (any, error) { + o := optionsWithDefaults(opts) + + return setSingleImpl(document, value, decodedToken, o.provider) } -func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NameProvider) (any, reflect.Kind, error) { +func getSingleImpl(node any, decodedToken string, nameProvider NameProvider) (any, reflect.Kind, error) { rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() if isNil(node) { @@ -361,6 +522,9 @@ func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NamePro return nil, kind, errNoKey(decodedToken) case reflect.Slice: + if decodedToken == dashToken { + return nil, kind, errDashOnGet() + } tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { return nil, kind, errors.Join(err, ErrPointer) @@ -378,14 +542,14 @@ func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NamePro } } -func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.NameProvider) error { +func setSingleImpl(node, data any, decodedToken string, nameProvider NameProvider) (any, error) { // check for nil to prevent panic when calling rValue.Type() if isNil(node) { - return fmt.Errorf("cannot set field %q on nil value: %w", decodedToken, ErrPointer) + return node, fmt.Errorf("cannot set field %q on nil value: %w", decodedToken, ErrPointer) } if ns, ok := node.(JSONSetable); ok { - return ns.JSONSet(decodedToken, data) + return node, ns.JSONSet(decodedToken, data) } rValue := reflect.Indirect(reflect.ValueOf(node)) @@ -394,12 +558,12 @@ func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.N case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { - return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) + return node, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) } fld := rValue.FieldByName(nm) if !fld.CanSet() { - return fmt.Errorf("can't set struct field %s to %v: %w", nm, data, ErrPointer) + return node, fmt.Errorf("can't set struct field %s to %v: %w", nm, data, ErrPointer) } value := reflect.ValueOf(data) @@ -407,33 +571,51 @@ func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.N assignedType := fld.Type() if !valueType.AssignableTo(assignedType) { - return fmt.Errorf("can't set value with type %T to field %s with type %v: %w", data, nm, assignedType, ErrPointer) + return node, fmt.Errorf("can't set value with type %T to field %s with type %v: %w", data, nm, assignedType, ErrPointer) } fld.Set(value) - return nil + return node, nil case reflect.Map: kv := reflect.ValueOf(decodedToken) rValue.SetMapIndex(kv, reflect.ValueOf(data)) - return nil + return node, nil case reflect.Slice: + if decodedToken == dashToken { + // RFC 6901 §4 / RFC 6902 append semantics: terminal "-" appends + // the value to the slice. We rebind in place when the slice is + // reachable via an addressable ancestor; otherwise we return the + // new slice header for the parent (or the public Set) to rebind. + value := reflect.ValueOf(data) + elemType := rValue.Type().Elem() + if !value.Type().AssignableTo(elemType) { + return node, fmt.Errorf("can't append value of type %T to slice of %v: %w", data, elemType, ErrPointer) + } + newSlice := reflect.Append(rValue, value) + if rValue.CanSet() { + rValue.Set(newSlice) + return node, nil + } + return newSlice.Interface(), nil + } + tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { - return errors.Join(err, ErrPointer) + return node, errors.Join(err, ErrPointer) } sLength := rValue.Len() if tokenIndex < 0 || tokenIndex >= sLength { - return errOutOfBounds(sLength, tokenIndex) + return node, errOutOfBounds(sLength, tokenIndex) } elem := rValue.Index(tokenIndex) if !elem.CanSet() { - return fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer) + return node, fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer) } value := reflect.ValueOf(data) @@ -441,15 +623,15 @@ func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.N assignedType := elem.Type() if !valueType.AssignableTo(assignedType) { - return fmt.Errorf("can't set value with type %T to slice element %d with type %v: %w", data, tokenIndex, assignedType, ErrPointer) + return node, fmt.Errorf("can't set value with type %T to slice element %d with type %v: %w", data, tokenIndex, assignedType, ErrPointer) } elem.Set(value) - return nil + return node, nil default: - return errInvalidReference(decodedToken) + return node, errInvalidReference(decodedToken) } } @@ -460,24 +642,27 @@ func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { if err != nil { return 0, err } - switch tk := tk.(type) { - case json.Delim: - switch tk { - case '{': - if err = drainSingle(dec); err != nil { - return 0, err - } - case '[': + key, ok := tk.(string) + if !ok { + return 0, fmt.Errorf("invalid key token %#v: %w", tk, ErrPointer) + } + if key == decodedToken { + return offset, nil + } + + // Consume the associated value. Scalars are fully read by a single + // Token() call; composite values must be drained. + tk, err = dec.Token() + if err != nil { + return 0, err + } + if delim, isDelim := tk.(json.Delim); isDelim { + switch delim { + case '{', '[': if err = drainSingle(dec); err != nil { return 0, err } } - case string: - if tk == decodedToken { - return offset, nil - } - default: - return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) } } @@ -485,6 +670,9 @@ func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { } func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) { + if decodedToken == dashToken { + return 0, errDashOnOffset() + } idx, err := strconv.Atoi(decodedToken) if err != nil { return 0, fmt.Errorf("token reference %q is not a number: %w: %w", decodedToken, err, ErrPointer) diff --git a/vendor/github.com/go-openapi/spec/.gitignore b/vendor/github.com/go-openapi/spec/.gitignore index 885dc27ab..d8f4186fe 100644 --- a/vendor/github.com/go-openapi/spec/.gitignore +++ b/vendor/github.com/go-openapi/spec/.gitignore @@ -3,4 +3,3 @@ .idea .env .mcp.json -.claude/ diff --git a/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md b/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md index 2967e3ced..0f533c016 100644 --- a/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/spec/CONTRIBUTORS.md @@ -4,12 +4,12 @@ | Total Contributors | Total Contributions | | --- | --- | -| 38 | 392 | +| 38 | 396 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | | @casualjim | 191 | | -| @fredbi | 90 | | +| @fredbi | 94 | | | @pytlesk4 | 26 | | | @kul-amr | 10 | | | @keramix | 10 | | @@ -47,4 +47,4 @@ | @ChandanChainani | 1 | | | @bvwells | 1 | | - _this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_ + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/spec/README.md b/vendor/github.com/go-openapi/spec/README.md index 134809fd7..405002b81 100644 --- a/vendor/github.com/go-openapi/spec/README.md +++ b/vendor/github.com/go-openapi/spec/README.md @@ -136,7 +136,7 @@ Maintainers can cut a new release by either: [slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM [slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue -[discord-url]: https://discord.gg/twZ9BwT3 +[discord-url]: https://discord.gg/FfnFYaC3k5 [license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg diff --git a/vendor/github.com/go-openapi/swag/jsonname/go_name_provider.go b/vendor/github.com/go-openapi/swag/jsonname/go_name_provider.go new file mode 100644 index 000000000..adc442687 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonname/go_name_provider.go @@ -0,0 +1,286 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonname + +import ( + "reflect" + "strings" + "sync" +) + +var _ providerIface = (*GoNameProvider)(nil) + +// GoNameProvider resolves json property names to go struct field names following +// the same rules as the standard library's [encoding/json] package. +// +// Contrary to [NameProvider], it considers exported fields without a json tag, +// and promotes fields from anonymous embedded struct types. +// +// Rules (aligned with encoding/json): +// +// - unexported fields are ignored; +// - a field tagged `json:"-"` is ignored; +// - a field tagged `json:"-,"` is kept under the json name "-" (stdlib quirk); +// - a field tagged `json:""` or with no json tag at all keeps its Go name as json name; +// - anonymous struct fields without an explicit json tag have their fields +// promoted into the parent, following breadth-first depth rules: +// a shallower field wins over a deeper one; at equal depth, a conflict +// discards all conflicting fields unless exactly one has an explicit json tag. +// +// This type is safe for concurrent use. +type GoNameProvider struct { + lock sync.Mutex + index map[reflect.Type]nameIndex +} + +// NewGoNameProvider creates a new [GoNameProvider]. +func NewGoNameProvider() *GoNameProvider { + return &GoNameProvider{ + index: make(map[reflect.Type]nameIndex), + } +} + +// GetJSONNames gets all the json property names for a type. +func (n *GoNameProvider) GetJSONNames(subject any) []string { + n.lock.Lock() + defer n.lock.Unlock() + + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + names := n.nameIndexFor(tpe) + + res := make([]string, 0, len(names.jsonNames)) + for k := range names.jsonNames { + res = append(res, k) + } + + return res +} + +// GetJSONName gets the json name for a go property name. +func (n *GoNameProvider) GetJSONName(subject any, name string) (string, bool) { + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + + return n.GetJSONNameForType(tpe, name) +} + +// GetJSONNameForType gets the json name for a go property name on a given type. +func (n *GoNameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) { + n.lock.Lock() + defer n.lock.Unlock() + + names := n.nameIndexFor(tpe) + nme, ok := names.goNames[name] + + return nme, ok +} + +// GetGoName gets the go name for a json property name. +func (n *GoNameProvider) GetGoName(subject any, name string) (string, bool) { + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + + return n.GetGoNameForType(tpe, name) +} + +// GetGoNameForType gets the go name for a given type for a json property name. +func (n *GoNameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) { + n.lock.Lock() + defer n.lock.Unlock() + + names := n.nameIndexFor(tpe) + nme, ok := names.jsonNames[name] + + return nme, ok +} + +func (n *GoNameProvider) nameIndexFor(tpe reflect.Type) nameIndex { + if names, ok := n.index[tpe]; ok { + return names + } + + names := buildGoNameIndex(tpe) + n.index[tpe] = names + + return names +} + +// fieldEntry captures a candidate field discovered while walking a struct +// along with the indirection path from the root type (used to resolve conflicts +// by depth in the same way encoding/json does). +type fieldEntry struct { + goName string + jsonName string + index []int + tagged bool +} + +func buildGoNameIndex(tpe reflect.Type) nameIndex { + fields := collectGoFields(tpe) + + idx := make(map[string]string, len(fields)) + reverseIdx := make(map[string]string, len(fields)) + for _, f := range fields { + idx[f.jsonName] = f.goName + reverseIdx[f.goName] = f.jsonName + } + + return nameIndex{jsonNames: idx, goNames: reverseIdx} +} + +// collectGoFields walks tpe breadth-first along anonymous struct fields, +// reproducing the field selection performed by encoding/json.typeFields. +func collectGoFields(tpe reflect.Type) []fieldEntry { + if tpe.Kind() != reflect.Struct { + return nil + } + + type queued struct { + typ reflect.Type + index []int + } + + current := []queued{} + next := []queued{{typ: tpe}} + visited := map[reflect.Type]bool{tpe: true} + + var ( + candidates []fieldEntry + count = map[string]int{} + nextCount = map[string]int{} + ) + + for len(next) > 0 { + current, next = next, current[:0] + count, nextCount = nextCount, count + for k := range nextCount { + delete(nextCount, k) + } + + for _, q := range current { + for i := 0; i < q.typ.NumField(); i++ { + sf := q.typ.Field(i) + + if sf.Anonymous { + ft := sf.Type + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + if !sf.IsExported() && ft.Kind() != reflect.Struct { + continue + } + } else if !sf.IsExported() { + continue + } + + tag := sf.Tag.Get("json") + if tag == "-" { + continue + } + jsonName, _ := parseJSONTag(tag) + tagged := jsonName != "" + + ft := sf.Type + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + + if sf.Anonymous && ft.Kind() == reflect.Struct && !tagged { + if visited[ft] { + continue + } + visited[ft] = true + + index := make([]int, len(q.index)+1) + copy(index, q.index) + index[len(q.index)] = i + next = append(next, queued{typ: ft, index: index}) + + continue + } + + name := jsonName + if name == "" { + name = sf.Name + } + + index := make([]int, len(q.index)+1) + copy(index, q.index) + index[len(q.index)] = i + + candidates = append(candidates, fieldEntry{ + goName: sf.Name, + jsonName: name, + index: index, + tagged: tagged, + }) + nextCount[name]++ + } + } + } + + return dominantFields(candidates) +} + +// dominantFields applies the Go encoding/json conflict resolution rules: +// at each JSON name, the shallowest field wins; at equal depth, a uniquely +// tagged candidate wins; otherwise all candidates for that name are dropped. +func dominantFields(candidates []fieldEntry) []fieldEntry { + byName := make(map[string][]fieldEntry, len(candidates)) + for _, c := range candidates { + byName[c.jsonName] = append(byName[c.jsonName], c) + } + + out := make([]fieldEntry, 0, len(byName)) + for _, group := range byName { + if len(group) == 1 { + out = append(out, group[0]) + + continue + } + + minDepth := len(group[0].index) + for _, c := range group[1:] { + if len(c.index) < minDepth { + minDepth = len(c.index) + } + } + + var shallow []fieldEntry + for _, c := range group { + if len(c.index) == minDepth { + shallow = append(shallow, c) + } + } + + if len(shallow) == 1 { + out = append(out, shallow[0]) + + continue + } + + var tagged []fieldEntry + for _, c := range shallow { + if c.tagged { + tagged = append(tagged, c) + } + } + if len(tagged) == 1 { + out = append(out, tagged[0]) + } + } + + return out +} + +// parseJSONTag returns the name component of a json struct tag and whether +// it carried any non-name option (kept for future-proofing, e.g. "omitempty"). +func parseJSONTag(tag string) (string, string) { + if tag == "" { + return "", "" + } + if idx := strings.IndexByte(tag, ','); idx >= 0 { + return tag[:idx], tag[idx+1:] + } + + return tag, "" +} diff --git a/vendor/github.com/go-openapi/swag/jsonname/ifaces.go b/vendor/github.com/go-openapi/swag/jsonname/ifaces.go new file mode 100644 index 000000000..812ace563 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonname/ifaces.go @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonname + +import "reflect" + +// providerIface is an unexported compile-time contract that every name provider +// in this package is expected to satisfy. +// It mirrors the interface declared by the main consumer of this module: [github.com/go-openapi/jsonpointer.NameProvider]. +type providerIface interface { + GetGoName(subject any, name string) (string, bool) + GetGoNameForType(tpe reflect.Type, name string) (string, bool) +} diff --git a/vendor/github.com/go-openapi/swag/jsonname/name_provider.go b/vendor/github.com/go-openapi/swag/jsonname/name_provider.go index 8eaf1bece..9f5da7a01 100644 --- a/vendor/github.com/go-openapi/swag/jsonname/name_provider.go +++ b/vendor/github.com/go-openapi/swag/jsonname/name_provider.go @@ -12,6 +12,8 @@ import ( // DefaultJSONNameProvider is the default cache for types. var DefaultJSONNameProvider = NewNameProvider() +var _ providerIface = (*NameProvider)(nil) + // NameProvider represents an object capable of translating from go property names // to json property names. // diff --git a/vendor/modules.txt b/vendor/modules.txt index 0c3a77d7a..ca64c42a3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -295,8 +295,8 @@ github.com/go-openapi/analysis/internal/flatten/sortref # github.com/go-openapi/errors v0.22.7 ## explicit; go 1.24.0 github.com/go-openapi/errors -# github.com/go-openapi/jsonpointer v0.22.5 -## explicit; go 1.24.0 +# github.com/go-openapi/jsonpointer v0.23.1 +## explicit; go 1.25.0 github.com/go-openapi/jsonpointer # github.com/go-openapi/jsonreference v0.21.5 ## explicit; go 1.24.0 @@ -316,8 +316,8 @@ github.com/go-openapi/runtime/middleware/header github.com/go-openapi/runtime/middleware/untyped github.com/go-openapi/runtime/security github.com/go-openapi/runtime/yamlpc -# github.com/go-openapi/spec v0.22.4 -## explicit; go 1.24.0 +# github.com/go-openapi/spec v0.22.5 +## explicit; go 1.25.0 github.com/go-openapi/spec # github.com/go-openapi/strfmt v0.26.1 ## explicit; go 1.24.0 @@ -329,23 +329,23 @@ github.com/go-openapi/swag # github.com/go-openapi/swag/cmdutils v0.25.5 ## explicit; go 1.24.0 github.com/go-openapi/swag/cmdutils -# github.com/go-openapi/swag/conv v0.25.5 -## explicit; go 1.24.0 +# github.com/go-openapi/swag/conv v0.26.0 +## explicit; go 1.25.0 github.com/go-openapi/swag/conv # github.com/go-openapi/swag/fileutils v0.25.5 ## explicit; go 1.24.0 github.com/go-openapi/swag/fileutils -# github.com/go-openapi/swag/jsonname v0.25.5 -## explicit; go 1.24.0 +# github.com/go-openapi/swag/jsonname v0.26.0 +## explicit; go 1.25.0 github.com/go-openapi/swag/jsonname -# github.com/go-openapi/swag/jsonutils v0.25.5 -## explicit; go 1.24.0 +# github.com/go-openapi/swag/jsonutils v0.26.0 +## explicit; go 1.25.0 github.com/go-openapi/swag/jsonutils github.com/go-openapi/swag/jsonutils/adapters github.com/go-openapi/swag/jsonutils/adapters/ifaces github.com/go-openapi/swag/jsonutils/adapters/stdlib/json -# github.com/go-openapi/swag/loading v0.25.5 -## explicit; go 1.24.0 +# github.com/go-openapi/swag/loading v0.26.0 +## explicit; go 1.25.0 github.com/go-openapi/swag/loading # github.com/go-openapi/swag/mangling v0.25.5 ## explicit; go 1.24.0 @@ -353,14 +353,14 @@ github.com/go-openapi/swag/mangling # github.com/go-openapi/swag/netutils v0.25.5 ## explicit; go 1.24.0 github.com/go-openapi/swag/netutils -# github.com/go-openapi/swag/stringutils v0.25.5 -## explicit; go 1.24.0 +# github.com/go-openapi/swag/stringutils v0.26.0 +## explicit; go 1.25.0 github.com/go-openapi/swag/stringutils -# github.com/go-openapi/swag/typeutils v0.25.5 -## explicit; go 1.24.0 +# github.com/go-openapi/swag/typeutils v0.26.0 +## explicit; go 1.25.0 github.com/go-openapi/swag/typeutils -# github.com/go-openapi/swag/yamlutils v0.25.5 -## explicit; go 1.24.0 +# github.com/go-openapi/swag/yamlutils v0.26.0 +## explicit; go 1.25.0 github.com/go-openapi/swag/yamlutils # github.com/go-openapi/validate v0.25.2 ## explicit; go 1.24.0