diff --git a/.github/ISSUE_TEMPLATE/clarification.yml b/.github/ISSUE_TEMPLATE/clarification.yml new file mode 100644 index 00000000..22530974 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/clarification.yml @@ -0,0 +1,33 @@ +name: 🧹 Clarification Needed +description: Something in the specification is unclear +title: "🧹 Clarification: " +labels: ["🧹 Clarification", "Status: Triage"] +body: +- type: textarea + attributes: + label: Specification section + description: Which specification document needs clarification? Which section? + placeholder: | + [Core | Validation], Section: ? + validations: + required: true +- type: textarea + attributes: + label: What is unclear? + description: Please quote the current text and explain why it's unclear. + validations: + required: true +- type: textarea + attributes: + label: Proposal + description: Do you have an idea to make the text more clear? + validations: + required: true +- type: dropdown + attributes: + label: Do you think this work might require an [Architectural Decision Record (ADR)]? (significant or noteworthy) + options: + - 'Yes' + - 'No' + validations: + required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/proposal.yml b/.github/ISSUE_TEMPLATE/proposal.yml new file mode 100644 index 00000000..a4947178 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/proposal.yml @@ -0,0 +1,29 @@ +name: ⭐️ Proposal +description: Suggest an idea for a new feature +title: "✨ Proposal: " +labels: ["proposal", "Status: Triage"] +body: +- type: textarea + attributes: + label: Describe the inspiration for your proposal + description: Does the proposal address a problem you're facing? + validations: + required: true +- type: textarea + attributes: + label: Describe the proposal + description: Please be as clear as possible and use examples. + validations: + required: true +- type: textarea + attributes: + label: Describe alternatives you've considered + description: Can the functionality you're proposal be achieved with the features available today? + validations: + required: false +- type: textarea + attributes: + label: Additional context + description: Is there anything else related to your proposal that you'd like to cover? + validations: + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..eecb49d8 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ + + + + + + + +### What kind of change does this PR introduce? + + + +### Issue & Discussion References + + +- Closes #___ +- Related to #___ +- Others? + +### Summary + + + +### Does this PR introduce a breaking change? + + diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000..8b847267 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,24 @@ +# Reporting Security Issues + +The JSON Schema project does not house any implementation of JSON Schema itself. +If you have found a security issue in any implementation of JSON Schema, please +contact the appropriate maintainers, per the projects security reporting +guidelines, if any. + +To report a security issue, please use the GitHub Security Advisory +"" +tab. + +If you find a security issue in relation to the JSON Schema specification or +another repository within this GitHub organization, please use the above. + +The JSON Schema project TSC will review and respond to all security reports. +Please follow [coordinated disclosure](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/about-coordinated-disclosure-of-security-vulnerabilities). + +If you are a maintainer of an implementation, please consider [adding a security +policy](https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository). +If you need assistance in understanding a report, or remediation of a confirmed +issue, please feel free to reach out to us on our Slack server, in the +`#implementations` channel, and ask for a temporary private channel to discuss +your situation or concerns. + diff --git a/.github/config.yaml b/.github/config.yaml new file mode 100644 index 00000000..8d492766 --- /dev/null +++ b/.github/config.yaml @@ -0,0 +1,4 @@ +helpr: + opened: 'Status: RP Review Required' + merged: 'Status: PR Merged' + rejected: 'Status: PR Revision Required' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..08e5a0b2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,35 @@ +name: JSON Schema +on: + - push + - pull_request + +jobs: + specs-markdown: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: latest + cache: npm + - run: npm ci + - run: npm run lint + - run: npm run build -- specs + + specs-ietf: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.10" + - run: pip install --requirement requirements.txt + - run: xml2rfc --version + - run: make all + - uses: actions/upload-artifact@v4 + with: + name: specification-docs + path: | + *.html + *.txt + !requirements.txt diff --git a/.github/workflows/minimum-open-time.yml b/.github/workflows/minimum-open-time.yml new file mode 100644 index 00000000..0dfa1255 --- /dev/null +++ b/.github/workflows/minimum-open-time.yml @@ -0,0 +1,20 @@ +name: PR Policy +on: + pull_request: + workflow_dispatch: + # scheduling only on PRs is not directly supported. See https://github.com/orgs/community/discussions/49960 + schedule: + - cron: '0 0 * * *' # once daily + +jobs: + require-minimum-open-time: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + name: Require Minimum Open Time + steps: + - uses: actions/checkout@v2 + - uses: gregsdennis/minimum-open-time@main + with: + time: 2w # see below for options + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/pr-dependencies.yml b/.github/workflows/pr-dependencies.yml new file mode 100644 index 00000000..34a231dc --- /dev/null +++ b/.github/workflows/pr-dependencies.yml @@ -0,0 +1,12 @@ +name: Check PR Dependencies + +on: pull_request + +jobs: + check_dependencies: + runs-on: ubuntu-latest + name: Check Dependencies + steps: + - uses: gregsdennis/dependencies-action@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2e2169f7..7007b640 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,18 @@ -jsonschema-*.html -jsonschema-*.txt +# Markdown builds +web/ + +# IETF builds +json-schema-use-cases.html +json-schema-use-cases.pdf +json-schema-use-cases.txt relative-json-pointer.html +relative-json-pointer.pdf relative-json-pointer.txt + +# For the Python enviornment +.venv + +# For the node-based build tools +node_modules/ + +.env diff --git a/.remarkrc-lint.js b/.remarkrc-lint.js new file mode 100644 index 00000000..1e60073f --- /dev/null +++ b/.remarkrc-lint.js @@ -0,0 +1,22 @@ +import remarkValidateLinks from "remark-validate-links"; +import remarkPresetLintConsistent from "remark-preset-lint-consistent"; +import remarkPresetLintRecommended from "remark-preset-lint-recommended"; +import remarkPresetLintMarkdownStyleGuide from "remark-preset-lint-markdown-style-guide"; +import remarkLintListItemIndent from "remark-lint-list-item-indent"; +import remarkLintListItemSpacing from "remark-lint-list-item-spacing"; +import remarkLintNoFileNameMixedCase from "remark-lint-no-file-name-mixed-case"; +import remarkLintNoFileNameIrregularCharacters from "remark-lint-no-file-name-irregular-characters"; + + +export default { + plugins: [ + remarkValidateLinks, + remarkPresetLintConsistent, + remarkPresetLintRecommended, + remarkPresetLintMarkdownStyleGuide, + [remarkLintListItemIndent, "one"], + [remarkLintListItemSpacing, { checkBlanks: true }], + [remarkLintNoFileNameMixedCase, false], + [remarkLintNoFileNameIrregularCharacters, false] + ] +}; diff --git a/.remarkrc.js b/.remarkrc.js new file mode 100644 index 00000000..95040a50 --- /dev/null +++ b/.remarkrc.js @@ -0,0 +1,10 @@ +import remarkGfm from "remark-gfm"; +import lintPreset from "./.remarkrc-lint.js"; + + +export default { + plugins: [ + remarkGfm, + lintPreset + ] +}; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 25b47f85..00000000 --- a/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: python -install: -- pip install "xml2rfc<2.10" -before_script: -- TAG=$(git tag -l --points-at HEAD) -script: -- xml2rfc jsonschema-core.xml --basename=jsonschema-core-$TAG --text --html -- xml2rfc jsonschema-validation.xml --basename=jsonschema-validation-$TAG --text --html -- xml2rfc jsonschema-hyperschema.xml --basename=jsonschema-hyperschema-$TAG --text --html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 44e9bed2..a2fa14aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,45 +1,72 @@ # Guidelines for contributing to the JSON Schema project -## Issues +## Contributing to JSON Schema Specification -Issues should identify an problem, enhancement, or use case; and propose some course of action for the draft. For alternate support channels, [see the json-schema.org website](http://json-schema.org/) or the [jsonschema tag on stackoverflow](https://stackoverflow.com/tags/jsonschema). +Thanks for taking the time to contribute! 🎉👍 -## Milestones +JSON Schema is an evolving language. This repository contains the specification +text as well as Pull Requests with suggested improvements and contributions. -Each milestone is an estimation of the work that will be done for the next draft. Milestones are typically named after the meta-schema draft number, and the *open* milestone with the lowest draft number is the current active project. +Contributions that do not change the interpretation of the spec but instead +improve legibility, fix editorial errors, clear up ambiguity and improve +examples are encouraged and are often merged by a spec editor with little +process. -Issues may be removed from a milestoned due to lack of consensus, lack of anyone with the correct expertise to make a PR, or simply because we wish to publish a draft and defer the remaining issues to the next draft. +However, contributions that *do* meaningfully change the interpretation of the +spec must follow the [Specification Development Process](./PROCESS.md). -Numbered milestones other than the lowest-numbered one are used to tentatively organize future work, but may be completely reorganized once work on that draft actually begins. +## Issues -The `draft-future` milestone is for issues for which there is an agreement that they should be addressed, but no specific timeline. +Issues should identify a problem, enhancement, or use case; and propose some +course of action for the draft. For alternate support channels, see the +[SUPPORT.md](https://github.com/json-schema-org/.github/blob/main/SUPPORT.md). -## Pull requests +## Pull Requests -We welcome pull requests, both for editorial suggestions and to resolve open issues. +We welcome pull requests, both for editorial suggestions and to resolve open +issues. -If the pull request would solve a particular issue, reference the issue in the pull request description. +If the pull request would solve a particular issue, reference the issue in the +pull request description. -Changes that would affect implementation behavior should typically be opened as an issue first. +Changes that would affect implementation behavior should typically be opened as +an issue first. -Pull requests should be made to master. +Generally, pull requests should be made to the `main` branch unless it is a +patch update and we are in a patch phase. In that case there will be a branch +named something like `2020-12-patch` that the PR should target instead. -Most PRs, including all PRs that impact implementation behavior, will be left open for a minimum of 14 days. Minor wording fixes may be merged more quickly once approved by a project member. +Most PRs, including all PRs that impact implementation behavior, will be left +open for a minimum of 14 days. Minor wording fixes may be merged more quickly +once approved by a project member. + +## Milestones -## Internet-Drafts and meta-schemas +Each milestone is an estimation of the work that will be done for the next +draft. Milestones are typically named after the meta-schema draft number, and +the *open* milestone with the lowest draft number is the current active project. -An Internet-Draft (I-D) publication replaces previous documents in their entirety. +Issues may be removed from a milestoned due to lack of consensus, lack of anyone +with the correct expertise to make a PR, or simply because we wish to publish a +draft and defer the remaining issues to the next draft. -I-D updates that are purely editorial bug fixes (with no implementation-impacting changes) will continue to use the same meta-schemas as the version that they fix. +Numbered milestones other than the lowest-numbered one are used to tentatively +organize future work, but may be completely reorganized once work on that draft +actually begins. -I-D updates that impact behavior, whether as a bug fix or a new, changed, or removed feature, will have new meta-schemas published along with them. +The `draft-future` milestone is for issues for which there is an agreement that +they should be addressed, but no specific timeline. -The meta-schema URI is used to differentiate between different vocabularies (currently only Validation and Hyper-Schema). +## Code of Conduct -The authority on JSON Schema behavior is the respective specification document, not the JSON meta-schema; the JSON version of the meta-schema is maintained in an informative capacity only. +All official channels including the mailing list, GitHub organization and Slack +server, follow our +[Code of Conduct](https://github.com/json-schema-org/.github/blob/main/CODE_OF_CONDUCT.md). -As an informative document, bugs in the meta-schema may be fixed in place to align them with the normative specification. Examples of in-place fixes include adding an accidentally omitted keyword or fixing an incorrect type. By definition, no correct schema should fail validation against the meta-schema after a bug fix, although previously validating incorrect schemas may start to (correctly) fail validation. +## Have Questions? -## Conduct +You can join the `#specification` channel in our +[Slack workspace](https://json-schema.org/slack) to interact with other +community members involved in the Specification development, share new ideas and +ask questions. -All official channels including the mailing list, GitHub organization, and Freenode channel, follow the IETF Guidelines for Conduct as specified in [RFC7154](https://tools.ietf.org/html/rfc7154). diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..7d4605f1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,213 @@ +Copyright (c) 2022 JSON Schema Specification Authors + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + +This Academic Free License (the "License") applies to any original work +of authorship (the "Original Work") whose owner (the "Licensor") has +placed the following licensing notice adjacent to the copyright notice +for the Original Work: + +Licensed under the Academic Free License version 3.0 + +1) Grant of Copyright License. Licensor grants You a worldwide, +royalty-free, non-exclusive, sublicensable license, for the duration of +the copyright, to do the following: + +a) to reproduce the Original Work in copies, either alone or as part of +a collective work; + +b) to translate, adapt, alter, transform, modify, or arrange the +Original Work, thereby creating derivative works ("Derivative Works") +based upon the Original Work; + +c) to distribute or communicate copies of the Original Work and +Derivative Works to the public, under any license of your choice that +does not contradict the terms and conditions, including Licensor's +reserved rights and remedies, in this Academic Free License; + +d) to perform the Original Work publicly; and + +e) to display the Original Work publicly. + +2) Grant of Patent License. Licensor grants You a worldwide, +royalty-free, non-exclusive, sublicensable license, under patent claims +owned or controlled by the Licensor that are embodied in the Original +Work as furnished by the Licensor, for the duration of the patents, to +make, use, sell, offer for sale, have made, and import the Original Work +and Derivative Works. + +3) Grant of Source Code License. The term "Source Code" means the +preferred form of the Original Work for making modifications to it +and all available documentation describing how to modify the Original +Work. Licensor agrees to provide a machine-readable copy of the Source +Code of the Original Work along with each copy of the Original Work +that Licensor distributes. Licensor reserves the right to satisfy this +obligation by placing a machine-readable copy of the Source Code in an +information repository reasonably calculated to permit inexpensive and +convenient access by You for as long as Licensor continues to distribute +the Original Work. + +4) Exclusions From License Grant. Neither the names of Licensor, nor +the names of any contributors to the Original Work, nor any of their +trademarks or service marks, may be used to endorse or promote products +derived from this Original Work without express prior permission of the +Licensor. Except as expressly stated herein, nothing in this License +grants any license to Licensor's trademarks, copyrights, patents, trade +secrets or any other intellectual property. No patent license is granted +to make, use, sell, offer for sale, have made, or import embodiments +of any patent claims other than the licensed claims defined in Section +2. No license is granted to the trademarks of Licensor even if such +marks are included in the Original Work. Nothing in this License shall +be interpreted to prohibit Licensor from licensing under terms different +from this License any Original Work that Licensor otherwise would have a +right to license. + +5) External Deployment. The term "External Deployment" means the use, +distribution, or communication of the Original Work or Derivative +Works in any way such that the Original Work or Derivative Works may +be used by anyone other than You, whether those works are distributed +or communicated to those persons or made available as an application +intended for use over a network. As an express condition for the grants +of license hereunder, You must treat any External Deployment by You of +the Original Work or a Derivative Work as a distribution under section +1(c). + +6) Attribution Rights. You must retain, in the Source Code of any +Derivative Works that You create, all copyright, patent, or trademark +notices from the Source Code of the Original Work, as well as any +notices of licensing and any descriptive text identified therein as an +"Attribution Notice." You must cause the Source Code for any Derivative +Works that You create to carry a prominent Attribution Notice reasonably +calculated to inform recipients that You have modified the Original +Work. + +7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants +that the copyright in and to the Original Work and the patent rights +granted herein by Licensor are owned by the Licensor or are sublicensed +to You under the terms of this License with the permission of the +contributor(s) of those copyrights and patent rights. Except as +expressly stated in the immediately preceding sentence, the Original +Work is provided under this License on an "AS IS" BASIS and WITHOUT +WARRANTY, either express or implied, including, without limitation, +the warranties of non-infringement, merchantability or fitness for a +particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL +WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential +part of this License. No license to the Original Work is granted by this +License except under this disclaimer. + +8) Limitation of Liability. Under no circumstances and under no legal +theory, whether in tort (including negligence), contract, or otherwise, +shall the Licensor be liable to anyone for any indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or the use of the Original Work including, +without limitation, damages for loss of goodwill, work stoppage, +computer failure or malfunction, or any and all other commercial damages +or losses. This limitation of liability shall not apply to the extent +applicable law prohibits such limitation. + +9) Acceptance and Termination. If, at any time, You expressly +assented to this License, that assent indicates your clear and +irrevocable acceptance of this License and all of its terms and +conditions. If You distribute or communicate copies of the Original +Work or a Derivative Work, You must make a reasonable effort under the +circumstances to obtain the express assent of recipients to the terms +of this License. This License conditions your rights to undertake +the activities listed in Section 1, including your right to create +Derivative Works based upon the Original Work, and doing so without +honoring these terms and conditions is prohibited by copyright law and +international treaty. Nothing in this License is intended to affect +copyright exceptions and limitations (including "fair use" or "fair +dealing"). This License shall terminate immediately and You may no +longer exercise any of the rights granted to You by this License upon +your failure to honor the conditions in Section 1(c). + +10) Termination for Patent Action. This License shall terminate +automatically and You may no longer exercise any of the rights granted +to You by this License as of the date You commence an action, including +a cross-claim or counterclaim, against Licensor or any licensee +alleging that the Original Work infringes a patent. This termination +provision shall not apply for an action alleging patent infringement by +combinations of the Original Work with other software or hardware. + +11) Jurisdiction, Venue and Governing Law. Any action or suit relating +to this License may be brought only in the courts of a jurisdiction +wherein the Licensor resides or in which Licensor conducts its primary +business, and under the laws of that jurisdiction excluding its +conflict-of-law provisions. The application of the United Nations +Convention on Contracts for the International Sale of Goods is +expressly excluded. Any use of the Original Work outside the scope +of this License or after its termination shall be subject to the +requirements and penalties of copyright or patent law in the appropriate +jurisdiction. This section shall survive the termination of this +License. + +12) Attorneys' Fees. In any action to enforce the terms of this License +or seeking damages relating thereto, the prevailing party shall +be entitled to recover its costs and expenses, including, without +limitation, reasonable attorneys' fees and costs incurred in connection +with such action, including any appeal of such action. This section +shall survive the termination of this License. + +13) Miscellaneous. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. + +14) Definition of "You" in This License. "You" throughout this License, +whether in upper or lower case, means an individual or a legal entity +exercising rights under, and complying with all of the terms of, this +License. For legal entities, "You" includes any entity that controls, +is controlled by, or is under common control with you. For purposes of +this definition, "control" means (i) the power, direct or indirect, to +cause the direction or management of such entity, whether by contract +or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +15) Right to Use. You may use the Original Work in all ways not +otherwise restricted or conditioned by this License or by law, and +Licensor promises not to interfere with or be responsible for such uses +by You. + +16) Modification of This License. This License is Copyright © +2005 Lawrence Rosen. Permission is granted to copy, distribute, or +communicate this License without modification. Nothing in this License +permits You to modify this License as applied to the Original Work or +to Derivative Works. However, You may modify the text of this License +and copy, distribute or communicate your modified version (the "Modified +License") and apply it to other original works of authorship subject +to the following conditions: (i) You may not indicate in any way that +your Modified License is the "Academic Free License" or "AFL" and you +may not use those names in the name of your Modified License; (ii) You +must replace the notice specified in the first paragraph above with +the notice "Licensed under " or with a +notice of your own that is not confusingly similar to the notice in +this License; and (iii) You may not claim that your original works are +open source software unless your Modified License has been approved by +Open Source Initiative (OSI) and You comply with its license review and +certification process. diff --git a/Makefile b/Makefile index 3699d8f1..f5b21217 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,37 @@ -XML2RFC=xml2rfc +XML2RFC ?= xml2rfc +VENV ?= .venv OUT = \ - jsonschema-core.html jsonschema-core.txt \ - jsonschema-validation.html jsonschema-validation.txt \ - jsonschema-hyperschema.html jsonschema-hyperschema.txt \ relative-json-pointer.html relative-json-pointer.txt - -all: $(OUT) +all: $(VENV) $(OUT) -%.txt: %.xml +%.txt: specs/%.xml $(XML2RFC) --text $< -o $@ -%.html: %.xml +%.pdf: specs/%.xml + $(XML2RFC) --pdf $< -o $@ + +%.html: specs/%.xml $(XML2RFC) --html $< -o $@ json-schema.tar.gz: $(OUT) + test ! -e json-schema mkdir json-schema git clone . json-schema (cd json-schema && make) tar -czf json-schema.tar.gz --exclude '.*' json-schema rm -rf json-schema -clean: +$(VENV): requirements.txt + python -m venv $@ + $@/bin/python -m pip install --upgrade pip + $@/bin/python -m pip install -r $< + +spec-clean: rm -f $(OUT) json-schema.tar.gz -.PHONY: clean +clean: spec-clean + rm -rf $(VENV) + +.PHONY: spec-clean clean all diff --git a/PROCESS.md b/PROCESS.md new file mode 100644 index 00000000..b0a06cb0 --- /dev/null +++ b/PROCESS.md @@ -0,0 +1,261 @@ + +# JSON Schema Specification Development and Publication Process + +## Purpose + +This document describes the development and publication process for the JSON +Schema specifications contained within this repository. + +- [JSON Schema Core](./specs/jsonschema-core.md) +- [JSON Schema Validation](./specs/jsonschema-validation.md) + +## Definitions + +### Defined Behavior + +Some behaviors within JSON Schema may be explicitly or implicitly undefined by +the specifications for various reasons. How to handle these behaviors is +generally left to implementations. + +A defined behavior is one that is fully and unambiguously defined by the +specifications. + +An undefined behavior is said to have an "indeterminate" validation result since +implementations may resolve the behavior in different ways. + +### Stability and Breaking Changes + +Stability is defined using the level of compatibility between sequential +releases. If all schemas which are written to one release produce the same +defined behavior under the following release, then those releases are +compatible, and the specification is said to be stable between them. + +If an existing schema under the new release exhibits defined behavior that is +contrary to defined behavior under the previous release, the new release is said +to contain breaking changes and the specification is unstable between those +releases. + +If a new release fully defines a previously undefined (or under-defined) +behavior, the new release is still considered compatible, even if it contradicts +the decision of any particular implementation. + +For reference, this table shows the validation results of a hypothetical schema +and instance across two consecutive releases to illustrate the compatibility of +those releases: + +| *Next* ➡️
⬇️ *Current* | pass | fail | indeterminate | +| :-----------------------: | :--: | :--: | :-----------: | +| **pass** | ✅ | ❌ | ❌ | +| **fail** | ❌ | ✅ | ❌ | +| **indeterminate** | ✅ | ✅ | ✅ | + +### Release + +A release is any single publication of the JSON Schema specifications (as a +group). + +### Version + +Consecutive releases which maintain compatibility with each other comprise a +version. + +## Release and Version + +The JSON Schema specification will aim to publish annually on or about the First +of January each year. Releases are identified by the year they are published. + +When a new release contains breaking changes, that release begins a new version +of JSON Schema. + +The version will be identified as an integer, starting with `1` and incrementing +as needed. + +Stability will be prioritized when making changes to the specification. Breaking +changes are undesired and should be avoided when possible. + +## Publication + +### Specifications + +The specifications will be published on the JSON Schema website, +, using a path comprised of the version, year, and +document name. For example, + +- `https://json-schema.org/1/2025/core.html` +- `https://json-schema.org/1/2025/validation.html` + +Once a specification document has been published, neither the document (save for +minor errata such as spelling mistakes) nor its publication URL may change. If +the TSC elects to alter the above URL scheme, the new scheme only applies to +future publications and are not retroactive. + +### Meta-schemas + +A release meta-schema will be published under the same path using `schema.json` +as the file name. + +- `https://json-schema.org/1/2025/schema.json` + +The website will also be configured to: + +- serve the meta-schema from its release folder: + `https://json-schema.org/1/2025/` +- serve the meta-schema for the latest release in a version from its version + folder: `https://json-schema.org/1/` + +The latest-release meta-schemas will be updated with proposals as indicated by +the [Proposal section](#proposal) of this document. + +> \[!IMPORTANT] +> These are only publication and availability URLs. The specification will +> define the `$id` values for the meta-schemas. + +## Feature Life Cycle + +New features will progress through a sequence of stages before being added to +the specification, and existing stable features must be formally deprecated +before being removed. The stages of the life cycle, in order, are: + +- Concept +- Proposal +- Experimentation +- Stable +- Deprecated +- Removed + +The flow through these stages is depicted below: + +```mermaid +stateDiagram-v2 + direction LR + Concept --> Proposal + state Development { + Proposal --> Experimentation + Experimentation --> Proposal + } + Development --> Stable + Stable --> Deprectated + Deprectated --> Removed +``` + +### Concept + +The feature life cycle begins with an idea expressed in a GitHub issue in this +repository. Initial discussion may occur in Slack or another space, but the life +cycle does not formally begin until a GitHub issue is created. + +The discussion should cover how the feature could work, use cases, syntax, +alternatives, whether it’s a breaking change, etc., with a goal of deciding +rough requirements. + +During this stage, members of the Core Team will implement private prototypes of +the ideas expressed in the issue to get a feel for how it integrates with the +stable features. Questions to address may include: + +- Does the idea operate within the confines of existing JSON Schema evaluation + processes, or does it define something new? +- Is the idea merely a shortcut for some existing functionality (syntactic + sugar), or does it solve a previously unsolvable problem? +- What is the expected complexity for implementing the feature? + +At least two (2) Core Team members must have implemented prototypes before the +concept can continue to the formal proposal process. + +### Proposal + +Once a rough consensus for the idea has been reached, a formal proposal will be +written, separate from the specification, with the goal of precisely defining +specification changes. + +The proposal will use the [Proposal +Template](./specs/proposals/proposal-template.md) and be stored in this +repository's `proposals` folder. + +Additionally, a draft ADR will be included using the file name of the proposal +document with an `-adr` suffix: `{proposal-file-name}-adr.md`. This ADR will +include additional information from the "Concept" discussion. + +Proposed keywords will be added to the appropriate vocabulary meta-schemas in: + +- latest published release and +- the `main` branch of this repository. + +The subschema for the proposed keyword will contain only a `$comment` keyword +indicating that the feature is experimental and containing a link to the +proposal document. Aside from the `$comment` keyword, the subschema will be +empty. + +> \[!NOTE] +> This is done so that a proposed keyword is allowed but not validated as its +> syntax may change during the proposal/experimentation process. It also permits +> different implementations to support different variations of each proposal +> separately throughout this process. It will be up to the implementation to +> validate these keywords in accordance with their support. + +Tests for the proposal are added to the JSON Schema Test Suite. + +```diff +@@ TODO: Identify a location within the test suite for proposals. @@ +``` + +Once an initial draft of the proposal has been completed and published, the +feature moves into Experimentation. + +### Experimentation + +Implementations may begin to support the new feature. + +Feedback from implementers and users are expected to result in refinements to +the proposal, which will then be updated in the implementations. + +Breaking changes to a proposed feature MAY occur, but are highly discouraged. + +In order to proceed to the next stage ([Stable](#stable)): + +- at least five (5) implementations support the feature +- there is sufficient evidence of use +- no changes are requested for a period of six (6) weeks + +```diff +@@ TODO: Determine usage metrics. @@ +``` + +Experimental features are not considered to be interoperable across +implementations. + +If a proposal cannot advance to the next stage, it may be removed. The proposal +document is moved to an `archive` subfolder, the keyword is removed from the +meta-schemas, and any tests are moved to an `archive` subfolder. The removal of +a feature which has not reached the stable state is not considered a breaking +change. + +### Stable + +The feature is incorporated into the specification in the `main` branch as +specified by the proposal document, and the feature will be required as of the +next release. + +The draft ADR is completed, dated, and moved to the `adr` folder. + +The appropriate vocabulary meta-schema in the `main` branch is updated to +include a subschema that validates the feature's syntax requirements. This will +be made available with the next release. + +Upon publication of the new release, the meta-schema for the lapsed release will +have the keyword removed. + +The appropriate tests are incorporated into the main suite. + +### Deprecated + +If a feature is no longer useful, e.g. it has been replaced, it may be +deprecated by indicating it as such in the specification. + +Implementations must support deprecated features. + +### Removed + +A feature must have been published as deprecated for at least one release before +it can be considered for removal. + +Feature removal is considered a breaking change. diff --git a/README.md b/README.md index 1bafd11d..0f2c950d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,15 @@ # Welcome to JSON Schema +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/json-schema-org/.github/blob/main/CODE_OF_CONDUCT.md) +[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Financial Contributors on Open Collective](https://opencollective.com/json-schema/all/badge.svg?label=financial+contributors)](https://opencollective.com/json-schema) -JSON Schema is a vocabulary that allows you to validate, annotate, and manipulate JSON documents. +JSON Schema is a vocabulary that allows you to validate, annotate, and +manipulate JSON documents. -This repository contains the sources for the **work in progress** of the next set of JSON Schema IETF Internet Draft (I-D) documents. -For the latest released I-Ds, please see the [Specification page](http://json-schema.org/documentation.html) on the website. +This repository contains the sources for the **work in progress** of the next +set of JSON Schema IETF Internet Draft (I-D) documents. For the latest released +I-Ds, please see the +[Specification page](http://json-schema.org/specification.html) on the website. ## Call for contributions and feedback @@ -11,37 +17,120 @@ Reviews, comments and suggestions are most welcome! Please read our [guidelines for contributing](CONTRIBUTING.md). ## Status -For the current status of issues and pull requests, please see the following labels -[![Available](https://img.shields.io/waffle/label/json-schema-org/json-schema-spec/Status:%20Available.svg?style=flat)](https://github.com/json-schema-org/json-schema-spec/issues?q=is%3Aopen+is%3Aissue+label%3A%22Status%3A+Available%22) [![In Progress](https://img.shields.io/waffle/label/json-schema-org/json-schema-spec/Status:%20In%20Progress.svg?style=flat)](https://github.com/json-schema-org/json-schema-spec/labels/Status:%20In%20Progress) [![Review Needed](https://img.shields.io/waffle/label/json-schema-org/json-schema-spec/Status:%20Review%20Needed.svg?style=flat)](https://github.com/json-schema-org/json-schema-spec/labels/Status%3A%20Review%20Needed) - -[![Critical](https://img.shields.io/waffle/label/json-schema-org/json-schema-spec/Priority:%20Critical.svg?style=flat -)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20Critical) [![High](https://img.shields.io/waffle/label/json-schema-org/json-schema-spec/Priority:%20High.svg?style=flat)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20High) [![Medium](https://img.shields.io/waffle/label/json-schema-org/json-schema-spec/Priority:%20Medium.svg?style=flat)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20Medium) [![Low](https://img.shields.io/waffle/label/json-schema-org/json-schema-spec/Priority:%20Low.svg?style=flat)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20Low) - -Labels are assigned based on [Sensible Github Labels](https://github.com/Relequestual/sensible-github-labels). - -## Contents - -* Makefile - scripts to build the Internet-Draft txt/html -* _Internet-Draft sources_ - * jsonschema-core.xml - source for JSON Schema's "core" I-D - * jsonschema-validation.xml - source for the validation vocabulary I-D - * jsonschema-hyperschema.xml - source for the hyper-schema vocabulary I-D - * relative-json-pointer.xml - source for the Relative JSON Pointer I-D -* _meta-schemas and recommended output formats_ - * schema.json - JSON Schema "core" and Validation meta-schema - * hyper-schema.json - JSON Hyper-Schema meta-schema - * links.json - JSON Hyper-Schema's Link Description Object meta-schema - * hyper-schema-output.json - The recommended output format for JSON Hyper-Schema links - -Type "make" at a shell to build the .txt and .html spec files. +For the current status of issues and pull requests, please see the following +labels + +[![Available](https://img.shields.io/github/issues/json-schema-org/json-schema-spec/Status:%20Available.svg?color=brightgreen)](https://github.com/json-schema-org/json-schema-spec/issues?q=is%3Aopen+is%3Aissue+label%3A%22Status%3A+Available%22) +[![In Progress](https://img.shields.io/github/issues/json-schema-org/json-schema-spec/Status:%20In%20Progress.svg)](https://github.com/json-schema-org/json-schema-spec/labels/Status:%20In%20Progress) +[![Review Needed](https://img.shields.io/github/issues/json-schema-org/json-schema-spec/Status:%20Review%20Needed.svg)](https://github.com/json-schema-org/json-schema-spec/labels/Status%3A%20Review%20Needed) +[![Critical](https://img.shields.io/github/issues/json-schema-org/json-schema-spec/Priority:%20Critical.svg?color=critical +)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20Critical) +[![High](https://img.shields.io/github/issues/json-schema-org/json-schema-spec/Priority:%20High.svg?color=important)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20High) +[![Medium](https://img.shields.io/github/issues/json-schema-org/json-schema-spec/Priority:%20Medium.svg)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20Medium) +[![Low](https://img.shields.io/github/issues/json-schema-org/json-schema-spec/Priority:%20Low.svg)](https://github.com/json-schema-org/json-schema-spec/labels/Priority%3A%20Low) + +Labels are assigned based on +[Sensible Github Labels](https://github.com/Relequestual/sensible-github-labels). + +## Authoring and Building + +### Specification +To build all the spec files to HTML from the Markdown sources, run `npm run +build -- specs`. You can also build each individually with `npm run build -- +specs/filename.md` (Example: `npm run build -- specs/jsonschema-core.md`). You +can also use wildcards to build multiple specs at the same time: `npm run build +-- specs/jsonschema-*.md`. The HTML files will be available in the `web` folder. + +The spec is built using [Remark](https://remark.js.org/), a markdown engine with +good support for plugins and lots of existing plugins we can use. Remark also +has a [language server](https://github.com/remarkjs/remark-language-server) and +a [VSCode extension](https://github.com/remarkjs/vscode-remark) we can use to +get linting an link checking while developing the spec. + +#### Plugins + +The following is a not-necessarily-complete list of configured plugins and the +features they make available to you. + +- [remark-lint](https://github.com/remarkjs/remark-lint) -- Enforce markdown + styles guide. +- [remark-validate-links](https://github.com/remarkjs/remark-validate-links) -- + Check for broken links. +- [remark-gfm](https://github.com/remarkjs/remark-gfm) -- Adds support for + Github Flavored Markdown specific markdown features such as autolink literals, + footnotes, strikethrough, tables, and tasklists. +- [remark-heading-id](https://github.com/imcuttle/remark-heading-id) -- Adds + support for `{#my-anchor}` syntax to add an `id` to an element so it can be + referenced using URI fragment syntax. +- [remark-headings](./remark/remark-headings.js) + -- A collection of enhancements for headings. + - Adds hierarchical section numbers to headings. + - Use the `%appendix%` prefix on headings that should be numbered as an + appendix. + - Adds id anchors to headers that don't have one + - Example: `#section-2-13` + - Example: `#appendix-a` + - Makes the heading a link utilizing its anchor +- [remark-reference-links](./remark/remark-reference-links.js) + -- Adds new syntax for referencing a section of the spec using the section + number as the link text. + - Example: + ```markdown + ## Foo {#foo} + ## Bar + This is covered in {{foo}} // --> Renders to "This is covered in [Section 2.3](#foo)" + - Link text will use "Section" or "Appendix" as needed + ``` +- [remark-table-of-contents](./remark/remark-table-of-contents.js) + -- Adds a table of contents in a section with a header called "Table of + Contents". +- [remark-code-titles](./remark/remark-code-titles.js) + -- Add titles to code blocks + - Example: + ```markdown + \`\`\`jsonschema "My Fun Title" + { "type": "string" } + \`\`\` + ``` + - The languages `jsonschema` and `json` have special styling + - The title will be parsed as a JSON string, but you have to double escape + escaped characters. So, to get `My "quoted" title`, you would need to be + `"My \\\\"quoted\\\\" title"`. +- [rehype-highlight](https://github.com/rehypejs/rehype-highlight) -- + Syntax highlighting. +- [rehype-highlight-code-lines](https://github.com/ipikuka/rehype-highlight-code-lines) + -- Adds line numbers to code blocks. Supports ranges. +- [remark-flexible-containers](https://github.com/ipikuka/remark-flexible-containers) + -- Add a callout box using the following syntax. Supported container types are + `warning`, `note`, and `experimental`. + ```markdown + ::: {type} {title} + {content} + ::: + ``` + +### Internet-Drafts + +To build components that are being maintained as IETF Internet-Drafts, run +`make`. The Makefile will create the necessary Python venv for you as part of +the regular make target. + +`make clean` will remove all output including the venv. To clean just the spec +output and keep the venv, use `make spec-clean`. + +If you want to run `xml2rfc` manually after running make for the first time, you +will need to activate the virtual environment: `source .venv/bin/activate`. + +The version of "xml2rfc" that this project uses is updated by modifying +`requirements.in` and running `pip-compile requirements.in`. Descriptions of the xml2rfc, I-D documents, and RFC processes: -* https://xml2rfc.tools.ietf.org/authoring/draft-mrose-writing-rfcs.html -* https://www.ietf.org/tao.html -* https://www.ietf.org/ietf-ftp/1id-guidelines.html -* https://www.rfc-editor.org/rfc/rfc7322.txt +- +- +- +- ## Test suites @@ -50,10 +139,41 @@ Conformance tests for JSON Schema and its vocabularies may be found ## The website -The JSON Schema web site is at http://json-schema.org/ +The JSON Schema web site is at + +The source for the website is [maintained in a separate repository](https://github.com/json-schema-org/website). + +## Contributors + +### Code Contributors + +This project exists thanks to all the people who contribute. \[[Contribute](CONTRIBUTING.md)]. + + +### Financial Contributors + +Become a financial contributor and help us sustain our community. \[[Contribute](https://opencollective.com/json-schema/contribute)] + +#### Sponsors + +Here are our top sponsors. You could be next! \[[Become a sponsor](https://opencollective.com/json-schema#sponsor)] + + + + + + + + + + + + +#### Individuals -The source for the website is [maintained in a separate repository](https://github.com/json-schema-org/json-schema-org.github.io). + ## License -The source material in this repository is licensed under the AFL or BSD license. +The contents of this repository are [licensed under](./LICENSE) either the BSD +3-clause license *or* the Academic Free License v3.0. diff --git a/adr/2022-04-08-cref-for-ambiguity-and-fix-later-gh-spec-issue-1172.md b/adr/2022-04-08-cref-for-ambiguity-and-fix-later-gh-spec-issue-1172.md new file mode 100644 index 00000000..548b5b86 --- /dev/null +++ b/adr/2022-04-08-cref-for-ambiguity-and-fix-later-gh-spec-issue-1172.md @@ -0,0 +1,115 @@ + +# Acknowledge ambiguity in additionalProperties behaviour and fix after patch release + +- Status: accepted +- Deciders: @relequestual @gregsdennis, @jdesrosiers, @karenetheridge +- Date: 2022-05-19 + +Related... + +Issue: + +Discussion: + +Pull Request: + +## Context and Problem Statement + +When we changed the specification to use annotations as the context in which +some keywords behave, we included a clause that allowed implementations which +didn't use annotations to optimize the processing of `additionalProperties` in +another way which produces the same effect as the prior behaviour. This section +created an ambiguity in terms of the resulting output format, but not +validation. + +We needed to decide on how to proceed for the patch release of the 2020-12 +version of the specification. + +The two above links are to a GitHub Discussion and a GitHub Issue detailing the +problems. Details with an example of the problem can be seen in the Discussion's +opening post specifically. + +## Decision Drivers + +- The "patch release" should not change anything functionally +- Annotations as they are, are confusing to users, implementers, and + specification editors alike +- Patch release is behind schedule +- There are currently no tests for the output format +- It's hard to see any immediate consensus on changing the annotation based + behaviour + +## Considered Options + +- [Leaving it "as is" and do nothing](https://github.com/json-schema-org/community/discussions/57#discussioncomment-1413777) +- [Pick one](https://github.com/json-schema-org/community/discussions/57#discussioncomment-1416683) + of the behaviours +- [Revert back to draft-07 behaviour](https://github.com/json-schema-org/community/discussions/57#discussioncomment-1453723) +- [Reinterpret how we understand annotation collection](https://github.com/json-schema-org/json-schema-spec/issues/1172#issuecomment-1049686478) + to allow reading annotations within the same schema object regardless of + assertion results +- [Acknowledge and accept that two approaches and results are allowable](https://github.com/json-schema-org/community/issues/161#issue-1173742930) +- Redefine annotation collection behaviour and/or how `additionalProperties` + works + +## Decision Outcome + +Chosen option: "Acknowledge and accept that two approaches and results are +allowable", because + +- Leaving it "as is" will continue to cause confusion +- The change is non-functional which is required for the patch release +- The patch release is behind schedule +- Finding consensus of other solutions proved to be difficult +- There's no test suite for the output format, so it's not easy to see + unintended consequences of a functional change +- We need to properly re-evaluate annotation collection and how annotations are + used by other keywords + +### Positive Consequences + +- Patch release can move forward +- Validation result is not impacted +- Confusion is at least seen and acknowledged +- Implementations which pick either approach are seen to be compliant + +### Negative Consequences + +- May have an impact for downstream tools which process full output data +- A test suite (not yet developed) which covers this situation needs to allow + for multiple valid answers + +## Pros and Cons of the Options + +### Leaving it "as is" and do nothing + +Agree to do nothing and hope for the best. There isn't any downstream tooling +yet anyway. + +- Good, because no functional change +- Good, because no impact on downstream tooling +- Bad, because leaves a known ambiguity in the specification + + +### Pick one / Revert to draft-07 behaviour / Reinterpret annotation collection + +- Good, because ambiguity is removed +- Good, because not many tools will be effected +- Bad, because it can be seen as a functional change (not really allowed for the + patch release) +- Bad, because it can break existing implementations and downstream tools +- Bad, because without a test suite it's hard to see unexpected consequences + +## Links + +- Issue: [Ambiguous behaviour of additionalProperties when invalid](https://github.com/json-schema-org/json-schema-spec/issues/1172) +- Discussion: [The meaning of "additionalProperties" has changed](https://github.com/json-schema-org/community/discussions/57) +- Resolving Pull Request: [Add CREF about ambiguous behaviour of additionalProperties](https://github.com/json-schema-org/json-schema-spec/pull/1203) +- Alternative solution proposal: [Resolve contradictions in the described + behaviour of "additionalProperties" and "items"](https://github.com/json-schema-org/json-schema-spec/pull/1154) +- [Result of discussing](https://github.com/json-schema-org/json-schema-spec/issues/1172#issuecomment-1063962900) + on an Open Community Working Meeting call - @jdesrosiers proposed a less + controversial and more agreeable solution to add a comment that both are + allowable +- [Related GitHub Discussion](https://github.com/json-schema-org/community/discussions/67) + on alternative behaviour for `unevaluated*` keywords diff --git a/adr/2022-09-decouple-from-ietf.md b/adr/2022-09-decouple-from-ietf.md new file mode 100644 index 00000000..6ec72ff2 --- /dev/null +++ b/adr/2022-09-decouple-from-ietf.md @@ -0,0 +1,168 @@ +# Decoupling from IETF + +- Status: accepted +- Deciders: @jdesrosiers @relequestual @awwright @handrews @gregsdennis +- Date: 2022-09-27 + +Related Issues: +- - This issue is about + dropping the "draft" prefix from our releases. This ADR doesn't cover that, + but much of the discussion about whether or not to decouple from IETF is in + that discussion. +- This topic has been discussed in many other places as well that are difficult + to link to here including Slack, Twitter, OCWMs, and conference discussions. + +## Context and Problem Statement + +Currently JSON Schema loosely follows the IETF Internet-Draft (I-D) process for +spec development and releases but isn't associated with any IETF working group. +JSON Schema is an individual draft. That means it isn't on a standards track +with IETF and IETF is not involved nor supports the spec in any way other than +hosting the canonical version of our I-Ds. Our perceived involvement with IETF +causes confusion and misunderstanding within our community in the cases were our +practices and the realities of our situation deviate from a typical IETF I-D +lifecycle. The thing that makes our situation different than a typical I-D is +that our "drafts" are intended for use in production. + +## Decision Drivers + +- IETF's draft versioning system doesn't work for JSON Schema and we stopped + using it to version our releases a while ago. We now use date based versioning + and even have more than one draft submission per release (the initial release + and the patch release). +- The IETF process is optimized for working on a draft until it's done and then + disbanding. In some cases, the RFC may be revisited and revised in the future, + but this is rare and generally contains little more than clarifications and + reference updates. JSON Schema is not like that. JSON Schema is more like a + programming language. When it stops evolving, it will lose its relevance. + When we finish a release of JSON Schema, we don't disband, we start work on + the next release. +- Since the project resumed activity after the gap following draft-04, every one + of our releases is expected to be used in production and will be depended on + for many years forward. This is not consistent with normal IETF drafts. Even + if we don't publicly use the term "draft", we're still using the IETF I-D + system in a way that's not intended. +- Under IETF, JSON Schema fits under the category of "draft". The community has + repeatedly told us that they perceive this to meant that JSON Schema + "incomplete" and not "not ready for production use". This is the wrong message + for us to be sending as all of our releases are intended to be used in + production. This ADR doesn't decide whether or not to drop the "draft" from + our releases, but decoupling from IETF gives us that option. +- Several members of the JSON Schema team have interacted with JSON-related IETF + working groups. Some of these interactions demonstrated an indifference or + hostility to JSON Schema, and a preference for projects taking a different + approach. Equally important was a lack of any active interest or constructive + engagement. Finally, we were informed that any schema project for JSON would + not necessarily start from JSON Schema as a base, indicating that a "JSON + Schema" working group would quite likely not involve JSON Schema itself. This + impression has been reinforced by observing the amount of change introduced to + JSON Path as a consequence of its adoption by an IETF working group. While we + have a good relationship with the relatively new HTTPAPIs working group, the + combination of these other experiences with other mismatches between our + project and the IETF process contributes to our reluctance to move forward + through the iETF. + +## Considered Options + +1. Continue to submit I-Ds, while using our customized process with no intention + of pursing standards track RFC status. +1. Go all-in with IETF and pursue a standards track RFC with the IETF. The + approach would be to describe the essential characteristics of evaluating a + JSON Schema: the keywords that everybody is guaranteed to support, and any + extension mechanisms. +1. Join W3C and pursue a standards track with them using their process. +1. Decouple completely from any standards organization and come up with our own + specification development lifecycle (SDLC) model inspired by well established + projects with an SDLC that more closely meets or needs. + +## Decision Outcome + +Our decision is to go with Option 4 and decouple from standards organizations +that don't fit our needs. We don't currently have a plan for what to replace +IETF with, but we are currently investigating how other established projects do +their SDLC and will likely choose one to emulate and adapt to our needs. +Although we don't have a replacement solution in place yet, we are confident +that continuing to abuse the IETF I-D process or conforming to a standards +organization process that doesn't fit our needs is not the way to go. + +However, we still plan to use the IETF process to register the media types +defined by JSON Schema with IANA. This effort is currently in progress with the +HTTPAPIs working group. + +The decision to not use IETF applies only to the main specification documents +and not necessarily supporting components we have defined or will define in the +future. Currently our only such component is Relative JSON Pointer, but there +could be others in the future. These components will be examined on a case by +case basis and we may choose an IETF standards path for those components if it +makes sense. + +Option 2 and 3 are still on the table if we feel it makes sense when we get to a +more stable place in the future. The main concern is the pain this process is +causing while we are in this unusual phase of simultaneous unstable growth and +production use. Standardization isn't out of the question, it's just not +productive for us to be developing JSON Schema within the constraints of a +standards organizations procedures. + +Option 1 was rejected because it ignores the problems we've been facing and +provides no solution. No one wants this. + +Option 2 was rejected for several reasons. If we go all in with IETF, we would +have to join a working group and treat JSON Schema like a normal I-D. That means +we would have to start treating drafts as drafts, which means not recommending +production use until we are ready for RFC and not releasing a new +production-ready version of JSON Schema until we've reached RFC status. Most of +the core contributors don't believe that we are close enough to an RFC-ready +release that we want to commit to not being able to issue another release until +that happens. + +There are other concerns including skepticism that even with an extension +mechanism that the RFC wouldn't need regular updates, which is not normal +practice for an RFC and would require significant effort to issue a replacing +RFC. Without a concrete proposal on the scope of the RFC and the extension +mechanisms, it's hard to commit to this path. + +Additionally, many of the core contributors have found working with the IETF +unproductive and have concerns about JSON Schema getting deeper involved without +compelling enough reason. Most agree that the reasons are not sufficiently +compelling at this point. + +Option 3 was rejected because it has the same problems as Option 2 except that +we don't have the same unpleasant history with W3C than we do with IETF. +Additionally, the W3C is a "pay to play" standards organization. Organizations +must pay to contribute to specifications the W3C publish, which doesn't match +the JSON Schema Org's open ethos. + +Ben Hutton has had multiple calls with various individuals at different levels +within the W3C, and has a friendly contact should we wish to investigate again +at a later point. The W3C does have an "invited expert" solution for when +a persons employer doesn't want to be a paying member, however this is supposed +to be an exception to the rule, and not frequently used. + +### Positive Consequences + +- Decoupling from IETF allows us to distance ourselves from the assumptions that + people make about JSON Schema because they assume it works like a typical I-D. +- Decoupling from IETF allows us to customize our SDLC model to what works best + for JSON Schema. + +### Negative Consequences + +- If we don't go the standardization route with IETF or W3C, we lose access to + their expert review process. +- Not being associated with a recognized standards organization such as IETF, + W3C, or IEEE reduces the credibility of JSON Schema in the eyes of some. + However, we have received feedback that our membership with OpenJS/Linux + Foundation provides the credibility that we need. +- One of the benefits of an RFC is other standards can normatively reference it, + and use JSON Schema to define their JSON-based syntaxes. However, we have + received feedback from people involved in standards development that told us + that they were comfortable referencing OpenAPI's self published specification + in their standards and that OpenAPI's membership with the Linux Foundation was + an important aspect of what makes them comfortable doing so. JSON Schema is a + member of the OpenJS Foundation, which is a sub-group of the Linux Foundation, + so we expect standards developers to be just as comfortable referencing JSON + Schema as they are referencing OpenAPI. +- Defining our own SLDC process will be a lot of work and none of us have + expertise in defining such a process. However, we can take inspiration from + existing well established projects and we would have the freedom to update our + process as we learn what works and what doesn't. diff --git a/adr/2022-11-stable-spec.md b/adr/2022-11-stable-spec.md new file mode 100644 index 00000000..0fa8b47a --- /dev/null +++ b/adr/2022-11-stable-spec.md @@ -0,0 +1,194 @@ +# Selecting a new specification development process + +- Status: accepted +- Deciders: @jdesrosiers @relequestual @awwright @handrews @gregsdennis +- Date: 2022-11-02 + +## Context and Problem Statement + +We've chosen to decouple our process from IETF, so we need to choose a new +specification development process to replace it. + +## Decision Drivers + +- Dropping the "draft" label is an important driver of this change. It's mostly + an artifact of the IETF process and has proven to be confusing for the + community. +- The community wants a stable version of JSON Schema. +- There is a need for JSON Schema to continue to evolve to meet evolving + needs. +- There is a demand for custom keywords/vocabularies/dialects and we want to + continue to support those use cases. +- There is a need to ease the burden of implementations supporting multiple + versions of JSON Schema. + +## Considered Options + +There have been two proposals put forward. Both address the goal of a stable +specification with the ability to evolve. The third option represents sticking +with the status quo. + +### Option 1 - TC-39 Inspired + +The spec would be converted from I-D XML to Markdown, but can otherwise be +structured however we choose. A system would be put in place to allow us to flag +the stability level of any feature in the spec. There would be only one version +of the spec and that version can change at any time, but changes to stable +features must follow strict backward and forward compatibility requirements. + +New features must go through a hardening process to ensure that they are very +unlikely to change before they are considered stable and subject to +compatibility requirements. This process will impose strict requirements +including tests, implementations, documentation, and real world vetting before a +feature or new keyword can be made stable in the spec. + +Since the spec is constantly evolving, a "release" is just a matter of promoting +unstable features to "stable" status. Releases would happen once a year and be +designated by the year they were released. + +### Option 2 - IETF Inspired + +The spec would be reorganized into two parts: "Core Semantics" and "Standard +Extensions". Changes to either spec are subject to strict backward and forward +compatibility requirements and would be released as a new spec that replaces and +obsoletes past versions of the spec. + +The "Core Semantics" spec would contain the bare minimum rules that must be +implemented for validators to not produce inaccurate results regardless of +future revisions or extensions. Among other necessities, this would include a +core set of keywords necessary to fully support structural validation and an +extension mechanism. This spec should rarely change. New features would be added +through additional specifications that define extensions to the "Core Semantics" +spec. + +The "Standard Extensions" spec is an example of one of these extension +specifications. This spec would be authored by the JSON Schema Org, but +extension specifications could be authored by anyone. The "Standard Extensions" +spec would include everything from the current spec that isn't included in the +"Core Semantics" spec. Features and keywords included in this spec are so +ubiquitous that they should be considered essential for implementations to +support. + +### Option 3 - Minimal Change + +Option 3 represents the minimal amount of change to our process from what we +have been doing. The spec would need to be converted from I-D XML to a Markdown +version that would be served on the website, but otherwise we would continue to +work the way we have been. We would aim for new version releases every year with +patch releases mid-cycle. Each release is a distinct version of JSON Schema and +has no compatibility guarantees between versions. + +## Decision Outcome + +The decision is to go with Option 1 while leaving discussion open for aspects of +Option 2 that could be adopted within the constraints of Option 1. + +Option 2 uses an immutable spec where each release replaces the last while +Option 1 uses a mutable spec. The outcome of having only one current version of +the spec is achieved with either option, but the mutable spec allows us to +remove some unnecessary roadblocks in our development processes and allows us to +release a stable spec much sooner. + +Option 2's restructuring of the spec into "Core Semantics" and "Standard +Extensions" isn't specifically ruled out, but spec evolution is expected to be +done primarily through mutation of the spec guided by the stability process +rather than through extension. Option 1 puts no constraint on the structure of +the spec and restructuring is allowed at any time as long as it doesn't break +compatibility requirements. + +## Pros and Cons of the Options + +The biggest benefit is shared between Option 1 and Option 2. Both approaches +result in a stable spec. This will have benefits for both implementers and +users. Because of the compatibility requirements, whenever you write a schema, +you will never need to change it just to keep up with changes to JSON Schema. +This is also better for implementers because they don't have to maintain +separate code with different semantics in different versions. They just need to +code for the current release and they will automatically have support for past +releases (not including "draft" releases). + + +### Option 1 - TC-39 Inspired + +The two things that make this option stand out are the stability model governing +spec evolution and the mutability of the spec document. + +Having a mutable spec allows us to make clarifications and bug fixes immediately +rather than having to wait months or years for the next release to go out. It +also allows us to iterate faster on unstable features which would allow us to +get them to a stable state much sooner. For example, we have changes to dynamic +references that have been agreed upon and ready to go for over a year, but users +can't benefit from the change until we can get the next full release published. +With this model, the change could have been made available for over a year now +and we would have a years worth of feedback on it's use. Having a mutable spec +also allows us to introduce new features without having to wait for a release. +For example, the `propertyDependencies` keyword has also been waiting for months +for a release. Users could have been benefiting from it for months and providing +feedback. + +The downside of a mutable spec is that it can be more difficult for implementers +and users to track when changes happen. We will need to be better at +communicating changes in blog posts or equivalent. + +The stability model allows us to ensure we don't make incompatible changes to +stable features, but it also allows us to introduce new features and get real +world feedback without committing to full compatibility requirements. This makes +it much more likely that we don't get stuck with something that doesn't work out +or could be done better. + +The stability model also makes it clear to users which features are stable and +how likely a feature is to change in the future. Whether they prefer to stick +with stable features or want to use a new keyword, users have the information +they need to make that decision. + +The stability model sets a very high barrier for a feature to make it into +stable status. This is on purpose so we can be very sure features won't change +once they are stable, but this process can take a long time. It would typically +take two years for a feature to reach stability which could be a long time to +wait for users who need to stick to the stable feature set but could benefit +greatly from a new feature. + + +### Option 2 - IETF Inspired + +The benefit of this approach is that it's compatible with the IETF process +without imposing some of the constraints and perception issues that we had with +our previous process. We can pursue an RFC in the future if we choose to without +significant changes or spec restructuring. + +With this proposal, releases are done as a new document that replaces the +previous documents. Compared to the constantly evolving spec in Option 1, +changes from non-functional clarifications and bug fixes to adding and evolving +new features takes much longer if you have to wait for the next release to make +a change. This lengthens the feedback loop slowing spec development progress. + +The main downside of this approach compared to Option 1 is that it will likely +take quite a while to get to a stable release. The spec restructuring is +controversial and it proposes several new keywords that are also controversial. +Discussing, achieving consensus, specifying, and implementing these changes will +take time. Introducing new features and keywords is much more risky with the new +compatibility requirements, so we have to go extra slow to make sure we get it +right. + +### Option 3 - Minimal Changes + +The benefit of this solution is that we don't have the overhead of defining +and/or learning a new process. In the short term, we can put more effort into +improving JSON Schema if we don't have the distraction of defining a whole new +process. The problem with this approach is that it doesn't solve the problem +with the "draft" label and doesn't provide the stability the community is +looking for. + +## Links +- + \- The ADR for the decision to decouple from IETF +- - Proposal submitted + by @jdesrosiers for a process to replace the IETF based process we'd been + using. +- - @awwright's vision + for JSON Schema including how it can continue to evolve while still having a + stable core. +- - When we first + started talking about forward compatibility and a stable spec. + - - User friendly + comments on decoupling from the IETF. diff --git a/adr/2023-04-sva-prefix.md b/adr/2023-04-sva-prefix.md new file mode 100644 index 00000000..97bdca83 --- /dev/null +++ b/adr/2023-04-sva-prefix.md @@ -0,0 +1,121 @@ +# Supporting Single-Value Annotations via a Defined Prefix + +- Status: accepted +- Deciders: @relequestual, @gregsdennis, @jdesrosiers, @karenetheridge, + @awwright, @julian +- Date: 2023-04-04 + +Related: + +- Discussions: + - Disallow Unknown Keywords - + - Support SVAs - +- PRs: + - (proposal) + +## Context and Problem Statement + +Dropping support for unknown keywords was a necessary step toward providing +stability guarantees. However, the community's reaction to this news was not +encouraging. How can we still support keywords that are merely collected as +annotations and provide no functionality (single-value annotations, or SVAs)? + +## Decision Drivers + +- Future-proofing - We want to ensure that we can still add keywords to the spec + without breaking existing schemas. +- Implementation supportability - Is the proposal feasible to implement? +- Community preference + +## Considered Options + +1. A defined prefix or other convention for SVAs + 1. Optionally defined by a new `$sigil` keyword +1. Inlined vocabularies that can define SVAs +1. A new core keyword that lists SVAs, e.g. `$ignored` +1. A defined configuration option to allow/forbid unknown keywords +1. A new core keyword designed for "extra" data + +## Decision Outcome + +Chosen option: A defined prefix or other convention. + +This option was chosen because it solves the problem in a clean way that can be +easily implemented. It was also the favorite solution among the team members as +well as the community. + +Specifically, the prefix `x-` has been selected. + +### Positive Consequences + +- It solves the problem by allowing users to include custom data in their + schemas. +- Many developers will be familiar with using `x-` for custom data. +- It's a simple way to differentiate SVAs from other keywords. + +### Negative Consequences + +- Some people preferred a different prefix as `x-` in some other contexts + denotes "experimental" behavior. + +## Pros and Cons of the Options + +### Option 1 - A defined prefix or other convention for SVAs + +[Discussion](https://github.com/orgs/json-schema-org/discussions/329#discussioncomment-4988859) + +- Good, because it's simple and easy to understand. +- Good, because `x-` specifically is familiar to many developers as an + identifying prefix for custom data. +- Good, because it's easily supportable by the meta-schema (i.e. + `patternProperties`) +- Bad, because `x-` in some other contexts can denote "experimental" behavior, + which is not our meaning. + +#### Option 1a - Optionally defined by a new `$sigil` keyword + +[Discussion](https://github.com/orgs/json-schema-org/discussions/329#discussioncomment-5357549) + +- Good, because it can give users flexibility for the prefix that they want to + use. +- Bad, because it cannot be supported by the meta-schema without other changes, + which may be difficult to define and/or implement. + +High level of effort + +### Option 2 - Inlined vocabularies that can define SVAs + +[Discussion](https://github.com/orgs/json-schema-org/discussions/329#discussioncomment-4988882) + +- Good, because it defines the SVAs in a vocabulary which means they are + regarded as "known." +- Bad, because we don't have any support for inlined vocabularies at the moment + and would have to build that. + +### Option 3 - A new core keyword that lists SVAs, e.g. `$ignored` + +[Discussion](https://github.com/orgs/json-schema-org/discussions/329#discussioncomment-4988904) + +- Good, because it provides a way to define SVAs. +- Bad, because it cannot be supported by the meta-schema without other changes, + which may be difficult to define and/or implement. + +High level of effort + + +### Option 4 - A defined configuration option to allow/forbid unknown keywords + +[Discussion](https://github.com/orgs/json-schema-org/discussions/329#discussioncomment-4999789) + +- Good, because it returns previous functionality (i.e. allowing unknown + keywords) to the user. +- Bad, because that previous functionality removes/circumvents stability + guarantees. + +### Option 5 - A new core keyword designed for "extra" data + +[Discussion](https://github.com/orgs/json-schema-org/discussions/329#discussioncomment-5374873) + +- Good, because it provides a place for users to add extra data. +- Bad, because it's an extra depth level that users need to create. +- Bad, because it can only generate a single annotation instead of multiple. diff --git a/adr/2024-02-object-contains.md b/adr/2024-02-object-contains.md new file mode 100644 index 00000000..ab6d5e16 --- /dev/null +++ b/adr/2024-02-object-contains.md @@ -0,0 +1,142 @@ +# `contains` and JSON Objects + +- Status: Proposed, accepted, reconsidered, and ultimately reverted. +- Deciders: @gregsdennis, @jdesrosiers, @handrews, @awwright, @karenetheridge, + @relequestual (with input from a couple non-core members) +- Date: 2023-11-14 (documented 2024-02-09) + +Technical Story: + +- Original proposal + [#1077](https://github.com/json-schema-org/json-schema-spec/issues/1077) and + [PR](https://github.com/json-schema-org/json-schema-spec/pull/1092) +- Reversion discussion + [#1358](https://github.com/json-schema-org/json-schema-spec/issues/1358) and + [PR](https://github.com/json-schema-org/json-schema-spec/pull/1452) + +## Context and Problem Statement + +\[2021-02] +The original proposal was for `contains` to apply to objects as well as arrays +since there was no functionality to do so. The discussion covered the options of +modifying `contains` or introducing a new `objectContains` (or similar) keyword +set (also needs separate min/max). The decision was voted on and modifying +`contains` won. + +\[2021-06] +A change was applied. + +\[2022-12] +With the team shifting focus to stability between spec releases, the question +was raised again with the argument that allowing `contains` to apply to objects +is a breaking change. It was conceded that the better approach would be to +retain `contains` only for arrays and introduce a new keyword set to apply to +objects. + +\[2023-11] +The change was applied (reverted to previous behavior). + +## Decision Drivers + +- The original decision to allow `contains` to apply to objects was driven by + the fact that no such functionality existed. +- The decision to revert was driven by a desire to not break current usages of + `contains`. + +## Considered Options + +- `contains` could be modified to apply to objects. +- a new keyword set (e.g. `objectContains` along with associated min/max) could + be added. + +## Decision Outcome + +Ultimately, `contains` will continue to apply to only arrays. New keywords will +need to be introduced to apply to objects. (Such a proposal has not yet been +made.) + +### Positive Consequences + +- Schemas which currently use `contains` without a `type: array` specifier will + not suddenly start applying to objects also. + +### Negative Consequences + +- The functionality of `contains` as applied to objects is still unsupported. + +## Pros and Cons of the Options + +### Change `contains` + +(Example provided recently by a user in [Slack](https://json-schema.slack.com/archives/C5CF75URH/p1707258032879409)) + +The requirement is that an object may contain any number of properties, but one +and only one of them must contain an object with a `title` property. + +✔️ valid +```json +{ + "foo": { "title": "a title" }, + "bar": { "baz": 42 } +} +``` + +❌ invalid +```json +{ + "foo": { "quux": false }, + "bar": { "baz": 42 } +} +``` + +❌ invalid +```json +{ + "foo": { "title": "a title" }, + "bar": { "title": "a title" } +} +``` + +Currently, this is impossible since there is no way to conditionally count +property values. However, with `contains` applying to objects, the following is +possible: + +```json +{ + "type": "object", + "contains": { + "type": "object", + "required": ["title"] + }, + "minContains": 1, + "maxContains": 1 +} +``` + +- Good, because it provides functionality that previously did not exist +- Bad, because is can potentially break some schemas +- ... + +### New keywords + +Same examples as [changing `contains`](#change-contains), except we use new +keywords instead. + +The schema would be something like this instead: + +```json +{ + "type": "object", + "objectContains": { + "type": "object", + "required": ["title"] + }, + "objectMinContains": 1, + "objectMaxContains": 1 +} +``` + +- Good, because it provides functionality that previously did not exist +- Good, because it doesn't break anyone +- Bad, because we have to introduce three new keywords +- ... diff --git a/adr/2024-05-08-extract-unstable-keywords.md b/adr/2024-05-08-extract-unstable-keywords.md new file mode 100644 index 00000000..f4bc53bc --- /dev/null +++ b/adr/2024-05-08-extract-unstable-keywords.md @@ -0,0 +1,69 @@ +# Extract Unstable Features for Initial Release + +- Status: accepted +- Deciders: @gregsdennis @jdesrosiers @bhutton +- Date: 2024-05-08 + +Technical Story: + +@gregsdennis [proposed](https://github.com/json-schema-org/json-schema-spec/issues/1443#issuecomment-2099427543) +that an ADR be created to document that unstable features be extracted before +the stable release. + +Also the [SDLC proposal](https://github.com/orgs/json-schema-org/discussions/671) +which lists features that need to be put into the proposal process. + +## Context and Problem Statement + +In creating a stable spec release, it's important that all included features are +well-developed and their behaviors are finalized. As such, the following +features will be extracted before the stable release. + +- `$vocabulary` - This feature is still in development. +- Output formats - This feature is being extracted to its own spec anyway. (See + [PR](https://github.com/json-schema-org/json-schema-spec/pull/1429) for more + info and link to discussion.) +- `propertyDependencies` - This feature is not technically in the spec and + should go through the proposal process. + +## Decision Drivers + +We can't publish a stable spec that contains unstable features. Thus we need to +remove them. + +## Considered Options + +1. Extract unfinished features and put them through the proposal process. +1. Complete the features before releasing the spec. + +## Decision Outcome + +Chosen option: Extract unfinished features and put them through the proposal +process. + +This allows us to release a stable version of the specification while continuing +to develop these features. + +### Positive Consequences + +- We can release a spec earlier that fulfills our users' needs. +- We can continue to develop these features. + +### Negative Consequences + +- These feature will be considered experimental until their proposals are +accepted. This may be a hindrance to adoption. + +## Pros and Cons of the Options + + +### Extract unfinished features and put them through the proposal process + +- Good, because we can release a spec earlier that fulfills our users' needs. +- Good, because we can continue to develop these features. +- Bad, because these features are experimental now. + +### Complete the features before releasing the spec + +- Good, because the features will be ready to use when the spec releases. +- Bad, because the spec may not release if we can't finalize the features. diff --git a/adr/2024-11-2-assertion-format.md b/adr/2024-11-2-assertion-format.md new file mode 100644 index 00000000..9546197d --- /dev/null +++ b/adr/2024-11-2-assertion-format.md @@ -0,0 +1,101 @@ +# `format` as an assertion + +- Status: proposed + +- Deciders: @gregsdennis @jdesrosiers @julian @jviotti @mwadams @karenetheridge + @relequestual +- Date: 2024-11-02 +- Technical Story: +- Voting issue: + - For - @gregsdennis @jdesrosiers @jviotti @mwadams @karenetheridge + - Neutral - @relequestual + - Against - @julian + +## Context and Problem Statement + +There's a long and sticky history around format. + +1. Going back all the way to Draft 01, format has never required validation. +1. Whether to support format validation has always been the decision of the + implementation. +1. The extent to which formats are validated has also been the decision of the + implementation. + +The result of all of this is that implementation support for validation has been +spotty at best. Despite the JSON Schema specs referencing very concretely +defined formats (by referencing other specs), implementations that do support +validation don't all support each format equally. This has been the primary +driving force behind keeping format as an opt-in validation. + +With 2019-09, we decided that it was time to give the option of format +validation to the schema author. They could enable validation by using a +meta-schema which listed the Format Vocabulary with a true value, which meant, +"format validation is required to process this schema." + +In 2020-12, we further refined this by offering two separate vocabularies, one +that treats the keyword as an annotation and one that treats it as an assertion. +The argument was that the behavior of a keyword shouldn't change based on +whether the vocabulary was required or not. + +However, the fact remains that our users consistently report (via questions in +Slack, GitHub, and StackOverflow) that they expect format to validate. (The most +recent case I can think of was only last week, in .Net's effort to build a +short-term solution for schema generation from types.) + +Due to this consistency in user expectations, we have decided to: + +1. make format an assertion keyword, and +1. strictly enforce it by moving the appropriate tests into the required section + of the Test Suite and building them more completely. + +## Decision Drivers + +- User expectation +- Current behavior +- Historical context +- Disparity of current implementation support vs the proposed requirements + +## Considered Options + +### `format` remains an annotation keyword by default + +This is the current state. The primary benefit is that we don't need to make a +breaking change. + +The primary downside is that the current system of (1) configuring the tool or +(2) incluing the `format-assertion` vocab[^1] is confusing for many and doesn't +align with user expectations. + +### `format` becomes an assertion keyword by default + +We change the spec to require `format` validation. Furthermore: + +- Implementations SHOULD support `format` with the defined values +- Implementations MAY support others, but only by explicit config +- Implementations MUST refuse to process a schema that contains an unsupported + format + +## Decision Outcome + +The TSC has decided via vote (see voting issue above) that we should change +`format` to act as an assertion by default, in line with option (2). + +### Positive Consequences + +- Aligns with user expectations. +- Users are still able to have purely annotative behavior through use of + something like `x-format`. +- Increased consistency for `format` validation across implementations. + +### Negative Consequences + +- This is a breaking change, which means that we will likely have to re-educate + the users who correctly treat it as an annotation. +- Older schemas which do not specify a version (`$schema`) may change their + validation outcome. +- The burden on implementations will be greater since format validation was + previously optional. + +[^1]: The `format-assertion` vocabulary will no longer be an option since we +have demoted vocabularies to a proposal for the stable release. This leaves tool +configuration as the only option to enable `format` validation. diff --git a/adr/README.md b/adr/README.md new file mode 100644 index 00000000..223275a3 --- /dev/null +++ b/adr/README.md @@ -0,0 +1,17 @@ +# Architectural Decision Log + +This log lists the architectural decisions for the JSON Schema specification. + + + +- [ADR-2022-04-08](2022-04-08-cref-for-ambiguity-and-fix-later-gh-spec-issue-1172.md) + \- Acknowledge ambiguity in additionalProperties behaviour and fix after patch + release + + + +You can find the ADR for using ADRs in our [community repo ADR log](https://github.com/json-schema-org/community/tree/HEAD/docs/adr). + +For new ADRs, please use [template.md](template.md) as basis. More information +on MADR is available at . General information about +architectural decision records is available at . diff --git a/adr/template.md b/adr/template.md new file mode 100644 index 00000000..6da4169a --- /dev/null +++ b/adr/template.md @@ -0,0 +1,70 @@ +# \[short title of solved problem and solution] + +- Status: \[proposed | rejected | accepted | deprecated | ... | superseded by + \[ADR-0005](0005-example.md)] +- Deciders: \[list everyone involved in the decision] +- Date: \[YYYY-MM-DD when the decision was last updated] + +Technical Story: \[description | ticket/issue URL] + +## Context and Problem Statement + +\[Describe the context and problem statement, e.g., in free form using two to +three sentences. You may want to articulate the problem in form of a question.] + +## Decision Drivers + +- \[driver 1, e.g., a force, facing concern, ...] +- \[driver 2, e.g., a force, facing concern, ...] +- … + +## Considered Options + +### \[option 1] + +\[example | description | pointer to more information | ...] + +- Good, because \[argument a] +- Good, because \[argument b] +- Bad, because \[argument c] +- … + +### \[option 2] + +\[example | description | pointer to more information | ...] + +- Good, because \[argument a] +- Good, because \[argument b] +- Bad, because \[argument c] +- … + +### \[option 3] + +\[example | description | pointer to more information | ...] + +- Good, because \[argument a] +- Good, because \[argument b] +- Bad, because \[argument c] +- … + +## Decision Outcome + +"\[option 1]" was chosen because \[justification. e.g., only option, which meets +k.o. criterion decision driver | which resolves force force | ... | comes out +best (see below)]. + +### Positive Consequences + +- \[e.g., improvement of quality attribute satisfaction, follow-up decisions + required, ...] +- ... + +### Negative Consequences + +- \[e.g., compromising quality attribute, follow-up decisions required, ...] +- ... + +## Links + +- \[Link type] \[Link to ADR] +- ... diff --git a/applicator.json b/applicator.json deleted file mode 100644 index de770dd2..00000000 --- a/applicator.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-08/schema#", - "$id": "https://json-schema.org/draft-08/applicator", - "$recursiveAnchor": true, - "$vocabulary": { - "https://json-schema.org/draft-08/vocabularies/core": true, - "https://json-schema.org/draft-08/vocabularies/applicator": true - }, - - "title": "Applicator vocabulary meta-schema", - "$defs": { - "schemaArray": { - "type": "array", - "minItems": 1, - "items": { "$recursiveRef": "#" } - } - }, - "properties": { - "additionalItems": { "$recursiveRef": "#" }, - "unevaluatedItems": { "$recursiveRef": "#" }, - "items": { - "anyOf": [ - { "$recursiveRef": "#" }, - { "$ref": "#/$defs/schemaArray" } - ] - }, - "contains": { "$recursiveRef": "#" }, - "additionalProperties": { "$recursiveRef": "#" }, - "unevaluatedProperties": { - "type": "object", - "additionalProperties": { - "$recursiveRef": "#" - } - }, - "properties": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "default": {} - }, - "patternProperties": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "propertyNames": { "format": "regex" }, - "default": {} - }, - "dependentSchemas": { - "type": "object", - "additionalProperties": { - "$recursiveRef": "#" - } - }, - "propertyNames": { "$recursiveRef": "#" }, - "if": { "$recursiveRef": "#" }, - "then": { "$recursiveRef": "#" }, - "else": { "$recursiveRef": "#" }, - "allOf": { "$ref": "#/$defs/schemaArray" }, - "anyOf": { "$ref": "#/$defs/schemaArray" }, - "oneOf": { "$ref": "#/$defs/schemaArray" }, - "not": { "$recursiveRef": "#" } - } -} diff --git a/core.json b/core.json deleted file mode 100644 index d845b3dd..00000000 --- a/core.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-08/schema#", - "$id": "https://json-schema.org/draft-08/core", - "$recursiveAnchor": true, - "$vocabulary": { - "https://json-schema.org/draft-08/vocabularies/core": true - }, - - "title": "Core vocabulary meta-schema", - "type": ["object", "boolean"], - "properties": { - "$id": { - "type": "string", - "format": "uri-reference" - }, - "$schema": { - "type": "string", - "format": "uri" - }, - "$ref": { - "type": "string", - "format": "uri-reference" - }, - "$recursiveRef": { - "type": "string", - "format": "uri-reference" - }, - "$recursiveAnchor": { - "type": "boolean", - "const": true, - "default": false - }, - "$vocabulary": { - "type": "object", - "propertyNames": { - "type": "string", - "format": "uri" - }, - "additionalProperties": { - "type": "boolean" - } - }, - "$comment": { - "type": "string" - }, - "$defs": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "default": {} - } - } -} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..4d6e6a80 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,46 @@ +import js from "@eslint/js"; +import globals from "globals"; +import stylistic from "@stylistic/eslint-plugin"; +import importPlugin from "eslint-plugin-import"; + + +export default [ + js.configs.recommended, + importPlugin.flatConfigs.recommended, + stylistic.configs.customize({ + arrowParens: true, + braceStyle: "1tbs", + commaDangle: "never", + flat: true, + jsx: false, + quotes: "double", + semi: true + }), + { + languageOptions: { + ecmaVersion: "latest", + globals: { + ...globals.node + } + }, + settings: { + "import/resolver": { + node: {} + } + }, + rules: { + "no-unused-vars": ["error", { caughtErrorsIgnorePattern: "^_" }], + "no-empty-function": "off", + "no-console": ["error"], + + // Imports + "import/extensions": ["error", "ignorePackages"], + "import/newline-after-import": ["error", { count: 2, exactCount: false, considerComments: true }], + + // Stylistic + "@stylistic/yield-star-spacing": ["error", "after"], + "@stylistic/multiline-ternary": "off", + "@stylistic/no-multiple-empty-lines": ["error", { max: 2, maxEOF: 0, maxBOF: 0 }] // Allow max=2 for imports + } + } +]; diff --git a/hyper-schema-output.json b/hyper-schema-output.json deleted file mode 100644 index 53593fa2..00000000 --- a/hyper-schema-output.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-08/schema#", - "$id": "http://json-schema.org/draft-08/hyper-schema-output", - "title": "JSON Hyper-Schema Output", - "type": "array", - "items": { - "allOf": [ - {"$ref": "http://json-schema.org/draft-08/links#/$defs/noRequiredFields" } - ], - "type": "object", - "required": [ - "contextUri", - "contextPointer", - "rel", - "attachmentPointer" - ], - "if": { "required": [ "hrefSchema" ] }, - "then": { "required": [ "hrefInputTemplates", "hrefPrepopulatedInput" ] }, - "else": { "required": [ "targetUri" ] }, - "properties": { - "contextUri": { - "$comment": "The fully resolved URI of the link context, including a fragment if it is possible to construct one for the given media type and instance", - "type": "string", - "format": "uri" - }, - "contextPointer": { - "$comment": "The absolute JSON Pointer to the location in the instance that is the context of the link. If the context resource supports JSON Pointer fragments, this will the string form of the identical JSON Pointer", - "type": "string", - "format": "json-pointer" - }, - "rel": { - "type": "string" - }, - "targetUri": { - "$comment": "The fully resolved target URI", - "type": "string", - "format": "uri" - }, - "hrefInputTemplates": { - "$comment": "The list of partially resolved URI Templates, starting with \"href\", followed by applicable \"base\" values from nearest to furthest.", - "type": "array", - "items": { - "type": "string", - "format": "uri-template" - } - }, - "hrefPrepopulatedInput": { - "$comment": "The initial data set to be presented with the input form when URI Tempalte input is accepted.", - "type": "object", - "propertyNames": { - "$comment": "These are all URI Template variable names, specifically the 'varname' production from RFC 6570, Section 2.3", - "pattern": "^(?:\\w|(?:%[a-f\\d]{2}))+(?:\\.(?:\\w|(?:%[a-f\\d]{2})))*$" - } - }, - "attachmentPointer": { - "$comment": "The absolute JSON Pointer, in string form, of the position to which this resolved link applies", - "type": "string", - "format": "json-pointer" - } - } - } -} diff --git a/hyper-schema.json b/hyper-schema.json deleted file mode 100644 index 5d72a263..00000000 --- a/hyper-schema.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-08/hyper-schema#", - "$id": "http://json-schema.org/draft-08/hyper-schema", - "$recursiveAnchor": true, - - "title": "JSON Hyper-Schema", - "$ref": "http://json-schema.org/draft-08/schema", - "properties": { - "base": { - "type": "string", - "format": "uri-template" - }, - "links": { - "type": "array", - "items": { - "$ref": "http://json-schema.org/draft-08/links" - } - } - }, - "links": [ - { - "rel": "self", - "href": "{+%24id}" - } - ] -} diff --git a/jsonschema-core.xml b/jsonschema-core.xml deleted file mode 100644 index d67b3d1e..00000000 --- a/jsonschema-core.xml +++ /dev/null @@ -1,3302 +0,0 @@ - - - - - - - - - - - -]> - - - - - - - - - - - JSON Schema: A Media Type for Describing JSON Documents - - -
- aaa@bzfx.net -
-
- - -
- - - San Francisco - CA - USA - - henry@cloudflare.com -
-
- - - Wellcome Sanger Institute -
- bh7@sanger.ac.uk -
-
- - -
- - - Auckland - - NZ - - gregsdennis@yahoo.com -
-
- - - Internet Engineering Task Force - JSON - Schema - Hyper Schema - Hypermedia - - - - JSON Schema defines the media type "application/schema+json", a JSON-based format - for describing the structure of JSON data. - JSON Schema asserts what a JSON document must look like, - ways to extract information from it, - and how to interact with it. - The "application/schema-instance+json" media type provides additional - feature-rich integration with "application/schema+json" beyond what can be offered - for "application/json" documents. - - - - - The issues list for this draft can be found at - . - - - For additional information, see . - - - To provide feedback, use this issue tracker, the communication methods listed on the - homepage, or email the document editors. - - -
- - -
- - JSON Schema is a JSON media type for defining the structure of JSON data. JSON Schema - is intended to define validation, documentation, hyperlink navigation, and interaction - control of JSON data. - - - This specification defines JSON Schema core terminology and mechanisms, including - pointing to another JSON Schema by reference, - dereferencing a JSON Schema reference, - specifying the vocabulary being used, - and defining the expected output. - - - Other specifications define the vocabularies that perform assertions about validation, - linking, annotation, navigation, and interaction. - -
- -
- - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", - "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be - interpreted as described in RFC 2119. - - - - The terms "JSON", "JSON text", "JSON value", "member", "element", "object", "array", - "number", "string", "boolean", "true", "false", and "null" in this document are to - be interpreted as defined in RFC 8259. - -
- -
- - This document proposes a new media type "application/schema+json" to identify a JSON - Schema for describing JSON data. - It also proposes a further optional media type, "application/schema-instance+json", - to provide additional integration features. - JSON Schemas are themselves JSON documents. - This, and related specifications, define keywords allowing authors to describe JSON - data in several ways. - - -
- - JSON Schema keywords fall into several general behavior categories. - Assertions validate that an instance satisfies constraints, producing - a boolean result. Annotations attach information that applications - may use in any way they see fit. - Applicators apply subschemas to parts of the instance and combine - their results. - - - Extension keywords SHOULD stay within these categories, keeping in mind - that annotations in particular are extremely flexible. Complex behavior - is usually better delegated to applications on the basis of annotation - data than implemented directly as schema keywords. However, extension - keywords MAY define other behaviors for specialized purposes. - - - Evaluating an instance against a schema involves processing all of the - keywords in the schema against the appropriate locations within the instance. - Typically, applicator keywords are processed until a schema object with no - applicators (and therefore no subschemas) is reached. The appropriate - location in the instance is evaluated against the assertion and - annotation keywords in the schema object, and their results are gathered - into the parent schema according to the rules of the applicator. - - - Evaluation of a parent schema object can complete once all of its - subschemas have been evaluated, although in some circumstances evaluation - may be short-circuited due to assertion results. - -
- - Keyword behavior MAY be defined in terms of the annotation results - of subschemas and/or adjacent keywords. - Such keywords MUST NOT result in a circular dependency. - Keywords MAY modify their behavior based on the presence or absence - of another keyword in the same - schema object. - -
-
- - A missing keyword MUST NOT produce a false assertion result, MUST - NOT produce annotation results, and MUST NOT cause any other schema - to be evaluated as part of its own behavioral definition. - However, given that missing keywords do not contribute annotations, - the lack of annotation results may indirectly change the behavior - of other keywords. - - - In some cases, the missing keyword assertion behavior of a keyword is - identical to that produced by a certain value, and keyword definitions - SHOULD note such values where known. However, even if the value which - produces the default behavior would produce annotation results if - present, the default behavior still MUST NOT result in annotations. - - - Because annotation collection can add significant cost in terms of both - computation and memory, implementations MAY opt out of this feature. - Keywords known to an implementation to have assertion or applicator behavior - that depend on annotation results MUST then be treated as errors, unless - an alternate implementation producing the same behavior is available. - Keywords of this sort SHOULD describe reasonable alternate approaches - when appropriate. This approach is demonstrated by the - "" and - "" keywords in this - document. - -
-
- - Applicators allow for building more complex schemas than can be accomplished - with a single schema object. Evaluation of an instance against a - schema document begins by applying - the root schema to the complete instance - document. From there, keywords known as applicators are used to determine - which additional schemas are applied. Such schemas may be applied in-place - to the current location, or to a child location. - - - The schemas to be applied may be present as subschemas comprising all or - part of the keyword's value. Alternatively, an applicator may refer to - a schema elsewhere in the same schema document, or in a different one. - The mechanism for identifying such referenced schemas is defined by the - keyword. - - - Applicator keywords also define how subschema or referenced schema - boolean assertion - results are modified and/or combined to produce the boolean result - of the applicator. Applicators may apply any boolean logic operation - to the assertion results of subschemas, but MUST NOT introduce new - assertion conditions of their own. - - - Annotation results are - combined according to the rules specified by each annotation keyword. - -
- -
- - JSON Schema can be used to assert constraints on a JSON document, which - either passes or fails the assertions. This approach can be used to validate - conformance with the constraints, or document what is needed to satisfy them. - - - JSON Schema implementations produce a single boolean result when evaluating - an instance against schema assertions. - - - An instance can only fail an assertion that is present in the schema. - - -
- - Most assertions only constrain values within a certain - primitive type. When the type of the instance is not of the type - targeted by the keyword, the instance is considered to conform - to the assertion. - - - For example, the "maxLength" keyword from the companion validation - vocabulary will only restrict certain strings - (that are too long) from being valid. If the instance is a number, - boolean, null, array, or object, then it is valid against this assertion. - -
-
- -
- - JSON Schema can annotate an instance with information, whenever the instance - validates against the schema object containing the annotation, and all of its - parent schema objects. The information can be a simple value, or can be - calculated based on the instance contents. - - - Annotations are attached to specific locations in an instance. - Since many subschemas can be applied to any single - location, annotation keywords need to specify any unusual handling of - multiple applicable occurrences of the keyword with different values. - - - The default behavior is simply to collect all values in a list in - indeterminate order. Given the extensibility of keywords, including - applicators, it is not possible to define a universally predictable - order of processing. - - - Unlike assertion results, annotation data can take a wide variety of forms, - which are provided to applications to use as they see fit. JSON Schema - implementations are not expected to make use of the collected information - on behalf of applications. - - - While "short-circuit" evaluation is possible for assertions, collecting - annotations requires examining all schemas that apply to an instance - location, even if they cannot change the overall assertion result. - -
-
- -
- - A JSON Schema vocabulary is a set of keywords defined for a particular - purpose. The vocabulary specifies the meaning of its keywords as - assertions, annotations, and/or any vocabulary-defined keyword category. - - - Several vocabularies are provided as - standards in this and closely related documents. These vocabularies - are used with the core keywords defined as fundamental to the - "application/schema+json" media type. - - - Schema authors are encouraged to define their own vocabularies for - domain-specific concepts. A vocabulary need not be a standard to - be re-usable, although users of extension vocabularies MUST NOT - assume that any JSON Schema implementation can support the vocabulary - unless it specifically documents such support. - -
- - This vocabulary provides keywords for applying subschemas to the - instance in various ways. It is defined in this document, and - it is RECOMMENDED that all JSON Schema implementations support it. - All other vocabularies in this section are designed to be used - alongside the subschema application vocabulary. - - - Without this vocabulary or an equivalent one, JSON Schema can only - be applied to a JSON document as a whole. In most cases, schema - keywords need to be applied to specific object properties or array items. - -
-
- - This vocabulary describes the structure of a JSON document - (for instance, required properties and length limitations). - Applications can use this information to validate instances (check that - constraints are met), or inform interfaces to collect user input - such that the constraints are satisfied. - - - Validation behaviour and keywords are specified in - a separate document. - -
-
- - A small set of annotation keywords are defined in - the validation specification - to allow associating common kinds of meta-data with an instance. - -
-
- - JSON Hyper-Schema produces hyperlinks as annotations available for - use with a JSON document. It supports resolving URI Templates - and describing the resource and data submission formats required - to use an API. - - - Hyper-schema behaviour and keywords are specified in - a separate document. - -
-
-
- -
- -
- - A JSON document is an information resource (series of octets) described by the - application/json media type. - - - In JSON Schema, the terms "JSON document", "JSON text", and "JSON value" are - interchangeable because of the data model it defines. - - - JSON Schema is only defined over JSON documents. However, any document or memory - structure that can be parsed into or processed according to the JSON Schema data - model can be interpreted against a JSON Schema, including media types like - CBOR. - -
- -
- - A JSON document to which a schema is applied is known as an "instance". - - -
- - JSON Schema interprets documents according to a data model. A JSON value - interpreted according to this data model is called an "instance". - - - An instance has one of six primitive types, and a range of possible values - depending on the type: - - - A JSON "null" production - A "true" or "false" value, from the JSON "true" or "false" productions - An unordered set of properties mapping a string to an instance, from the JSON "object" production - An ordered list of instances, from the JSON "array" production - An arbitrary-precision, base-10 decimal number value, from the JSON "number" production - A string of Unicode code points, from the JSON "string" production - - - - Whitespace and formatting concerns, including different lexical - representations of numbers that are equal within the data model, are thus - outside the scope of JSON Schema. JSON Schema - vocabularies that wish - to work with such differences in lexical representations SHOULD define - keywords to precisely interpret formatted strings within the data model - rather than relying on having the original JSON representation Unicode - characters available. - - - Since an object cannot have two properties with the same key, behavior for a - JSON document that tries to define two properties (the "member" production) with - the same key (the "string" production) in a single object is undefined. - - - Note that JSON Schema vocabularies are free to define their own extended - type system. This should not be confused with the core data model types - defined here. As an example, "integer" is a reasonable type for a - vocabulary to define as a value for a keyword, but the data model - makes no distinction between integers and other numbers. - -
- -
- - JSON Schema is designed to fully work with "application/json" documents, - as well as media types using the "+json" structured syntax suffix. - - - Some functionality that is useful for working with schemas is - defined by each media type, namely media type parameters and - URI fragment identifier syntax and semantics. These features are - useful in content negotiation and in calculating URIs for specific - locations within an instance, respectively. - - - This specification defines the "application/schema-instance+json" - media type in order to allow instance authors to take full advantage - of parameters and fragment identifiers for these purposes. - -
- -
- - Two JSON instances are said to be equal if and only if they are of the same type - and have the same value according to the data model. Specifically, this means: - - - both are null; or - both are true; or - both are false; or - both are strings, and are the same codepoint-for-codepoint; or - both are numbers, and have the same mathematical value; or - both are arrays, and have an equal value item-for-item; or - both are objects, and each property in one has exactly one property with - a key equal to the other's, and that other property has an equal - value. - - - - Implied in this definition is that arrays must be the same length, - objects must have the same number of members, - properties in objects are unordered, - there is no way to define multiple properties with the same key, - and mere formatting differences (indentation, placement of commas, trailing - zeros) are insignificant. - -
-
- -
- - A JSON Schema document, or simply a schema, is a JSON document used to describe - an instance. - A schema is itself interpreted as an instance, but SHOULD always be given - the media type "application/schema+json" rather than - "application/schema-instance+json". The "application/schema+json" media - type is defined to offer a superset of the media type parameter and - fragment identifier syntax and semantics provided by - "application/schema-instance+json". - - - A JSON Schema MUST be an object or a boolean. - -
- - Object properties that are applied to the instance are called keywords, - or schema keywords. Broadly speaking, keywords fall into one - of three categories: - - - produce a boolean result when applied to an instance - - - attach information to an instance for application use - - - apply one or more subschemas to a particular location - in the instance, and combine or modify their results - - - - - Keywords may fall into multiple categories, although applicators - SHOULD only produce assertion results based on their subschemas' - results. They should not define additional constraints independent - of their subschemas. - - - Extension keywords, meaning those defined outside of this document - and its companions, are free to define other behaviors as well. - - - A JSON Schema MAY contain properties which are not schema keywords. - Unknown keywords SHOULD be ignored. - - - An empty schema is a JSON Schema with no properties, or only unknown - properties. - -
-
- - The boolean schema values "true" and "false" are trivial schemas that - always produce themselves as assertions results, regardless of the - instance value. They never produce annotation results. - - - These boolean schemas exist to clarify schema author intent and - facilitate schema processing optimizations. They behave identically - to the following schema objects (where "not" is part of the - subschema application vocabulary defined in this document). - - - Always passes validation, as if the empty schema {} - - - Always fails validation, as if the schema { "not":{} } - - - While the empty schema object is unambiguous, there are many - possible equivalents to the "false" schema. Using the boolean - values ensures that the intent is clear to both human readers - and implementations. - -
-
- - The root schema is the schema that comprises the entire JSON document - in question. - - - Some keywords take schemas themselves, allowing JSON Schemas to be nested: - -
- - - -
- - In this example document, the schema titled "array item" is a subschema, - and the schema titled "root" is the root schema. - - - As with the root schema, a subschema is either an object or a boolean. - -
-
- - While most JSON Schema keywords can be evaluated on their own, - or at most need to take into account the values or results of - adjacent keywords in the same schema object, a few have more - complex behavior. - - - The lexical scope of a keyword is determined by the nested JSON - data structure of objects and arrays. The largest such scope - is an entire schema document. The smallest scope is a single - schema object with no subschemas. - - - Keywords MAY be defined with a partial value, such as a URI-reference, - which must be resolved against another value, such as another - URI-reference or a full URI, which is found through the lexical - structure of the JSON document. The "$id" core keyword and - the "base" JSON Hyper-Schema keyword are examples of this sort - of behavior. Additionally, "$ref" and "$recursiveRef" from - this specification resolve their values in this way, although - they do not change how further values are resolved. - - - Note that some keywords, such as "$schema", apply to the lexical - scope of the entire schema document, and therefore MUST only - appear in the document's root schema. - - - Other keywords may take into account the dynamic scope that - exists during the evaluation of a schema, typically together - with an instance document. The outermost dynamic scope is the - root schema of the schema document in which processing begins. - The path from this root schema to any particular keyword (that - includes any "$ref" and "$recursiveRef" keywords that may have - been resolved) is considered the keyword's "validation path." - - Or should this be the schema object at which processing - begins, even if it is not a root? This has some implications - for the case where "$recursiveAnchor" is only allowed in the - root schema but processing begins in a subschema. - - - - Lexical and dynamic scopes align until a reference keyword - is encountered. While following the reference keyword jumps - from one lexical scope into a different one, from the perspective - of dynamic scope, following reference is no different from descending - into a subschema present as a value. A keyword on the far side of - that reference that resolves information through the dynamic scope - will consider the originating side of the reference to be their - dynamic parent, rather than examining the local lexically enclosing parent. - - - The concept of dynamic scope is primarily used with "$recursiveRef", - "$recursiveAnchor", and should be considered an advanced feature - and used with caution when defining additional keywords. - -
-
- - As noted in , an applicator keyword may - refer to a schema to be applied, rather than including it as a - subschema in the applicator's value. In such situations, the - schema being applied is known as the referenced schema, while - the schema containing the applicator keyword is the referencing schema. - - - While root schemas and subschemas are static concepts based on a - schema's position within a schema document, referenced and referencing - schemas are dynamic. Different pairs of schemas may find themselves - in various referenced and referencing arrangements during the evaluation - of an instance against a schema. - - - For some by-reference applicators, such as - "$ref", the referenced schema can be determined - by static analysis of the schema document's lexical scope. Others, - such as "$recursiveRef" and "$recursiveAnchor", may make use of dynamic - scoping, and therefore only be resolvable in the process of evaluating - the schema with an instance. - -
-
- -
- -
- - In accordance with section 3.1 of , - the syntax and semantics of fragment identifiers specified for - any +json media type SHOULD be as specified for "application/json". - (At publication of this document, there is no fragment identification - syntax defined for "application/json".) - - - Additionally, the "application/schema+json" media type supports two - fragment identifier structures: plain names and JSON Pointers. - The "application/schema-instance+json" media type supports one - fragment identifier structure: JSON Pointers. - - - The use of JSON Pointers as URI fragment identifiers is described in - RFC 6901. - For "application/schema+json", which supports two fragment identifier syntaxes, - fragment identifiers matching the JSON Pointer syntax, including the empty string, - MUST be interpreted as JSON Pointer fragment identifiers. - - - Per the W3C's - best practices for fragment identifiers, - plain name fragment identifiers in "application/schema+json" are reserved for referencing - locally named schemas. All fragment identifiers that do - not match the JSON Pointer syntax MUST be interpreted as - plain name fragment identifiers. - - - Defining and referencing a plain name fragment identifier within an - "application/schema+json" document are specified - in the "$id" keyword section. - - - -
- -
- -
- - An instance may be any valid JSON value as defined by JSON. - JSON Schema imposes no restrictions on type: JSON Schema can describe any JSON - value, including, for example, null. - -
- -
- - JSON Schema is programming language agnostic, and supports the full range of - values described in the data model. - Be aware, however, that some languages and JSON parsers may not be able to - represent in memory the full range of values describable by JSON. - -
- -
- - Some programming languages and parsers use different internal representations - for floating point numbers than they do for integers. - - - For consistency, integer JSON numbers SHOULD NOT be encoded with a fractional - part. - -
- -
- - Keywords MAY use regular expressions to express constraints, or constrain - the instance value to be a regular expression. - These regular expressions SHOULD be valid according to the - ECMA 262 regular expression dialect. - - - Furthermore, given the high disparity in regular expression constructs support, - schema authors SHOULD limit themselves to the following regular expression - tokens: - - - individual Unicode characters, as defined by the JSON specification; - simple character classes ([abc]), range character classes ([a-z]); - complemented character classes ([^abc], [^a-z]); - simple quantifiers: "+" (one or more), "*" (zero or more), "?" (zero or - one), and their lazy versions ("+?", "*?", "??"); - range quantifiers: "{x}" (exactly x occurrences), "{x,y}" (at least x, at - most y, occurrences), {x,} (x occurrences or more), and their lazy - versions; - the beginning-of-input ("^") and end-of-input ("$") anchors; - simple grouping ("(...)") and alternation ("|"). - - - - Finally, implementations MUST NOT take regular expressions to be - anchored, neither at the beginning nor at the end. This means, for instance, - the pattern "es" matches "expression". - -
- -
- - Additional schema keywords and schema vocabularies MAY be defined - by any entity. Save for explicit agreement, schema authors SHALL NOT - expect these additional keywords and vocabularies to be supported by - implementations that do not explicitly document such support. - Implementations SHOULD ignore keywords they do not support. - - - Vocabulary authors SHOULD - take care to avoid keyword name collisions if the vocabulary is intended - for broad use, and potentially combined with other vocabularies. JSON - Schema does not provide any formal namespacing system, but also does - not constrain keyword names, allowing for any number of namespacing - approaches. - - - Vocabularies may build on each other, such as by defining the behavior - of their keywords with respect to the behavior of keywords from another - vocabulary, or by using a keyword from another vocabulary with - a restricted or expanded set of acceptable values. Not all such - vocabulary re-use will result in a new vocabulary that is compatible - with the vocabulary on which it is built. Vocabulary authors SHOULD - clearly document what level of compatibility, if any, is expected. - - - A schema that itself describes a schema is called a meta-schema. - Meta-schemas are used to validate JSON Schemas and specify which vocabulary - they are using. - - - Authors of extensions to JSON Schema are encouraged to write their own - meta-schemas, which extend the existing meta-schemas using "allOf". - This extended meta-schema SHOULD be referenced using the "$schema" keyword, to - allow tools to follow the correct behaviour. - - - The recursive nature of meta-schemas makes the "$recursiveAnchor" - and "$recursiveRef" keywords particularly useful for such extensions, - as can be seen in the JSON Hyper-Schema meta-schema. - -
- -
- -
- - Two concepts, meta-schemas and vocabularies, are used to inform an implementation - how to interpret a schema. A schema S declares its meta-schema M with the "$schema" - keyword, and meta-schemas declare vocabularies with the "$vocabulary" keyword. - The vocabularies declared in M are those that are expected to be used in S. - The meta-schema M may itself use a different set of vocabularies, which are - declared in its own meta-schema, M'. - - - The role of the meta-schema is to constrain the structure of conforming schemas, - as well as simplify the process of composing multiple vocabularies into a usable - feature set. Schema authoring is expected to be a common activity, so - schema authors need only understand how to reference a single meta-schema. - - - Meta-schema authoring is an advanced usage of JSON Schema, so the design of - meta-schema features emphasizes flexibility over simplicity. - - - The role of a vocabulary is to declare which keywords (including sub-keywords - such as those in JSON Hyper-Schema's Link Description Object) are in use, - and with which semantics. The semantics are indicated by the document - that publicizes the vocabulary URI. At this time, there is no machine-readable - description of keywords other than validation rules, which appear in the - meta-schema. - - - Meta-schemas are separate from vocabularies to allow for the same sets of - vocabularies to be combined in different ways, and for meta-schema authors - to impose additional constraints such as forbidding certain keywords, or - performing unusually strict syntactical validation, as might be done - during a development and testing cycle. - -
- - The "$schema" keyword is both used as a JSON Schema feature set identifier and - the location of a resource which is itself a JSON Schema, which describes any - schema written for this particular feature set. - - - The value of this keyword MUST be a URI - (containing a scheme) and this URI MUST be normalized. - The current schema MUST be valid against the meta-schema identified by this URI. - - - If this URI identifies a retrievable resource, that resource SHOULD be of - media type "application/schema+json". - - - The "$schema" keyword SHOULD be used in a root schema. - It MUST NOT appear in subschemas. - - - - Using multiple "$schema" keywords in the same document would imply that the - feature set and therefore behavior can change within a document. This would - necessitate resolving a number of implementation concerns that have not yet - been clearly defined. So, while the pattern of using "$schema" only in root - schemas is likely to remain the best practice for schema authoring, - implementation behavior is subject to be revised or liberalized in - future drafts. - - - - - Values for this property are defined elsewhere in this and other documents, - and by other parties. - -
-
- - The "$vocabulary" keyword, which appears in a meta-schema, identifies - what sets of keywords are expected to be used in schemas described - by that meta-schema, and with what semantics. This is conceptually - analogous to how most other keywords used in meta-schemas describe - the syntax of keywords used in schemas described by that meta-schema. - - - The value of this keyword MUST be an object. The property names in the - object MUST be URIs (containing a scheme) and this URI MUST be normalized. - Each URI that appears as a property name identifies a specific set of - keywords and their semantics. - - - The URI MAY be a URL, but the nature of the retrievable resources is - currently undefined, and reserved for future use. Vocabulary authors - SHOULD NOT serve a document at that URL. A server MAY respond with - the relevant protocol's successful "no content" message, such as - an HTTP 204 status. - - Vocabulary documents may be added shortly, or in the next draft. - For now, identifying the keyword set is deemed sufficient as that, - along with meta-schema validation, is how the current "vocabularies" - work today. - - - - The values of the object properties MUST be booleans. - If the value is true, then implementations that do not recognize - the vocabulary MUST refuse to process any schemas that declare - this meta-schema with "$schema". If the value is false, implementations - that do not recognize the vocabulary MAY choose to proceed with processing - such schemas. - - - When processing a schema that uses unrecognized vocabularies, keywords - declared by those vocabularies are treated like any other unrecognized - keyword, and ignored. - - - The "$vocabulary" keyword SHOULD be used in the root schema of any schema - document intended for use as a meta-schema. It MUST NOT appear in subschemas. - - - The "$vocabulary" keyword MUST be ignored in schema documents that - are not being processed as a meta-schema. This allows validating - a meta-schema M against its own meta-schema M' without requiring - the validator to understand the vocabularies declared by M. - - - Note that the processing restrictions on "$vocabulary" mean that - meta-schemas that reference other meta-schemas using "$ref" or - similar keywords do not automatically inherit the vocabulary - declarations of those other meta-schemas. All such declarations - must be repeated in the root of each schema document intended - for use as a meta-schema. This is demonstrated in - the example meta-schema. - - - If "$vocabulary" is absent, an implementation MAY determine - behavior based on the meta-schema if it is recognized from the - URI value of the referring schema's "$schema" keyword. - If the meta-schema, as referenced by the schema, is not recognized, - then implementations MUST assume the use of the core vocabulary, - and SHOULD assume the use of all vocabularies in this - specification and the companion Validation specification. - -
-
- - Implementations MUST recognize a schema as a meta-schema if it - is being examined because it was identified as such by another - schema's "$schema" keyword. This means that a single schema - document might sometimes be considered a regular schema, and - other times be considered a meta-schema. - - - In the case of examining a schema which is its own meta-schema, - when an implementation begins processing it as a regular schema, - it is processed under those rules. However, when loaded a second - time as a result of checking its own "$schema" value, it is treated - as a meta-schema. So the same document is processed both ways in - the course of one session. - - - Implementations MAY allow a schema to be passed as a meta-schema, - for implementation-specific purposes, such as pre-loading a commonly - used meta-schema and checking its vocabulary support requirements - up front. Meta-schema authors MUST NOT expect such features to be - interoperable across implementations. - -
-
- - Meta-schema authors SHOULD NOT use "$vocabulary" to combine multiple - vocabularies that define conflicting syntax or semantics for the same - keyword. As semantic conflicts are not generally detectable through - schema validation, implementations are not expected to detect such - conflicts. If conflicting vocabularies are declared, the resulting - behavior is undefined. - - - Vocabulary authors SHOULD provide a meta-schema that validates the - expected usage of the vocabulary's keywords. Such meta-schemas - SHOULD NOT forbid additional keywords, and MUST NOT forbid - the "$id", "$schema", or "$vocabulary" keywords in the root schema. - - - It is RECOMMENDED that meta-schema authors reference each vocabulary's - meta-schema using the "allOf" keyword, - although other mechanisms for constructing the meta-schema may be - appropriate for certain use cases. - - - Meta-schemas MAY impose additional constraints, including describing - keywords not present in any vocabulary, beyond what the meta-schemas - associated with the declared vocabularies describe. This allows for - restricting usage to a subset of a vocabulary, and for validating - locally defined keywords not intended for re-use. - - - However, meta-schemas SHOULD NOT contradict any vocabularies that - they declare, such as by requiring a different JSON type than - the vocabulary expects. The resulting behavior is undefined. - - - Meta-schemas intended for local use, with no need to test for - vocabulary support in arbitrary implementations, can safely omit - "$vocabulary" entirely. - -
-
- - Keywords declared in in this specification that begin with "$" make up - the JSON Schema Core vocabulary. These keywords are either required in - order process any schema or meta-schema, including those split across - multiple documents, or exist to reserve keywords for purposes that - require guaranteed interoperability. - - - The Core vocabulary MUST be considered mandatory at all times, in order - to bootstrap the processing of further vocabularies. Meta-schemas - that use "$vocabulary" MUST explicitly list the Core vocabulary, - which MUST have a value of true indicating that it is required. - - - The behavior of a false value for this vocabulary (and only this - vocabulary) is undefined, as is the behavior when "$vocabulary" - is present but the Core vocabulary is not included. However, it - is RECOMMENDED that implementations detect these cases and raise - an error when they occur. - - - Meta-schemas that do not use "$vocabulary" MUST be considered to - require the Core vocabulary as if its URI were present with a value of true. - - - The current URI for the Core vocabulary is: - . - - - The current URI for the corresponding meta-schema is: - . - -
-
-
- - This meta-schema explicitly declares both the Core and Applicator - vocabularies, and combines their meta-schemas with an "allOf". - It additionally restricts the usage of the Applicator vocabulary - by forbidding the keyword prefixed with "unevaluated". It also - describes a keyword, "localKeyword", that is not part of either - vocabulary. Note that it is its own meta-schema, - as it relies on both the Core vocabulary (as all schemas do) - and the Applicator vocabulary (for "allOf"). - - - - - - As shown above, even though each of the referenced standard - meta-schemas declares its corresponding vocabulary, this new - meta-schema must re-declare them for itself. It would be - valid to leave the core vocabulary out of the "$vocabulary" keyword, - but it needs to be referenced through the "allOf" keyword in order - for its terms to be validated. There is no special case for - validation of core keywords. - -
- - The standard meta-schemas that combine all vocabularies defined by - the Core and Validation specification, and that combine all vocabularies - defined by those specifications as well as the Hyper-Schema specification, - demonstrate additional complex combinations. These URIs for these - meta-schemas may be found in the Validation and Hyper-Schema specifications, - respectively. - -
-
- -
- - To differentiate between schemas in a vast ecosystem, schemas are - identified by URI, and can embed references - to other schemas by specifying their URI. - - -
- - RFC3986 Section 5.1 defines how to determine the - default base URI of a document. - - - Informatively, the initial base URI of a schema is the URI at which it was - found, whether that was a network location, a local filesystem, or any other - situation identifiable by a URI of any known scheme. - - - If no source is known, or no URI scheme is known for the source, a suitable - implementation-specific default URI MAY be used as described in - RFC 3986 Section 5.1.4. It is RECOMMENDED - that implementations document any default base URI that they assume. - -
- -
- - The "$id" keyword defines a URI for the schema, and the base URI that - other URI references within the schema are resolved against. - A subschema's "$id" is resolved against the base URI of its parent schema. - If no parent sets an explicit base with "$id", the base URI is that of the - entire document, as determined per - RFC 3986 section 5. - - - If present, the value for this keyword MUST be a string, and MUST represent a - valid URI-reference. - This value SHOULD be normalized, and SHOULD NOT be an empty fragment <#> - or an empty string <>. - -
- - The root schema of a JSON Schema document SHOULD contain an "$id" keyword with - an absolute-URI (containing a scheme, but no fragment), - or this absolute URI but with an empty fragment. - - -
-
- - When an "$id" sets the base URI, the object containing that "$id" and all of - its subschemas can be identified by using a JSON Pointer fragment starting - from that location. This is true even of subschemas that further change the - base URI. Therefore, a single subschema may be accessible by multiple URIs, - each consisting of base URI declared in the subschema or a parent, along with - a JSON Pointer fragment identifying the path from the schema object that - declares the base to the subschema being identified. Examples of this are - shown in section . - -
-
- - Using JSON Pointer fragments requires knowledge of the structure of the schema. - When writing schema documents with the intention to provide re-usable - schemas, it may be preferable to use a plain name fragment that is not tied to - any particular structural location. This allows a subschema to be relocated - without requiring JSON Pointer references to be updated. - - - To specify such a subschema identifier, - the "$id" keyword is set to a URI reference with a plain name fragment (not a JSON Pointer fragment). - This value MUST begin with the number sign that specifies a fragment ("#"), - then a letter ([A-Za-z]), - followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), - colons (":"), or periods ("."). - - - The effect of using a fragment in "$id" that isn't blank or doesn't follow the - plain name syntax is undefined. - - How should an "$id" URI reference containing a fragment with other components - be interpreted? There are two cases: when the other components match - the current base URI and when they change the base URI. - - -
-
-
- - Consider the following schema, which shows "$id" being used to identify - the root schema, change the base URI for subschemas, and assign plain - name fragments to subschemas: - - - - -
- - The schemas at the following URI-encoded JSON - Pointers (relative to the root schema) have the following - base URIs, and are identifiable by any listed URI in accordance with - Section above: - - - - - - http://example.com/root.json - http://example.com/root.json# - - - - - http://example.com/root.json#foo - http://example.com/root.json#/$defs/A - - - - - http://example.com/other.json - http://example.com/other.json# - http://example.com/root.json#/$defs/B - - - - - http://example.com/other.json#bar - http://example.com/other.json#/$defs/X - http://example.com/root.json#/$defs/B/$defs/X - - - - - http://example.com/t/inner.json - http://example.com/t/inner.json# - http://example.com/other.json#/$defs/Y - http://example.com/root.json#/$defs/B/$defs/Y - - - - - urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f - urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# - http://example.com/root.json#/$defs/C - - - - -
-
- -
- - Several keywords can be used to reference a schema which is to be applied to the - current instance location. "$ref" and "$recursiveRef" are applicator - keywords, applying the referenced schema to the instance. "$recursiveAnchor" - is a helper keyword that controls how the referenced schema of "$recursiveRef" - is determined. - - - As the value of "$ref" and "$recursiveRef" are URI References, this allows - the possibility to externalise or divide a schema across multiple files, - and provides the ability to validate recursive structures through - self-reference. - - - The resolved URI produced by these keywords is not necessarily a network - locator, only an identifier. A schema need not be downloadable from the - address if it is a network-addressable URL, and implementations SHOULD NOT - assume they should perform a network operation when they encounter - a network-addressable URI. - - -
- - The "$ref" keyword is used to reference a statically identified schema. - - - The value of the "$ref" property MUST be a string which is a URI Reference. - Resolved against the current URI base, it identifies the URI of a schema - to use. - -
- -
- - The "$recursiveRef" and "$recursiveAnchor" keywords are used to construct - extensible recursive schemas. A recursive schema is one that has - a reference to its own root, identified by the empty fragment - URI reference ("#"). - - - Extending a recursive schema with "$ref" alone involves redefining all - recursive references in the source schema to point to the root of the - extension. This produces the correct recursive behavior in the extension, - which is that all recursion should reference the root of the extension. - -
- - Consider the following two schemas. The first schema, identified - as "original" as it is the schema to be extended, describes - an object with one string property and one recursive reference - property, "r". The second schema, identified as "extension", - references the first, and describes an additional things" property, - which is an array of recursive references. - It also repeats the description of "r" from the original schema. - - - - - - This apparent duplication is important because - it resolves to "https://example.com/extension#", meaning that - for instance validated against the extension schema, the value - of "r" must be valid according to the extension, and not just the - original schema as "r" was described there. - -
- - This approach is fine for a single recursive field, but the more - complicated the original schema, the more redefinitions are necessary - in the extension. This leads to a verbose and error-prone extension, - which must be kept synchronized with the original schema if the - original changes its recursive fields. - This approach can be seen in the meta-schema for JSON Hyper-Schema - in all prior drafts. - -
- - The desired behavior is for the recursive reference, "r", in the - original schema to resolve to the original schema when that - is the only schema being used, but to resolve to the extension - schema when using the extension. Then there would be no need - to redefine the "r" property, or others like it, in the extension. - - - In order to create a recursive reference, we must do three things: - - - In our original schema, indicate that the schema author - intends for it to be extensible recursively. - - - In our extension schema, indicate that it is intended - to be a recursive extension. - - - Use a reference keyword that explicitly activates the - recursive behavior at the point of reference. - - - These three things together ensure that all schema authors - are intentionally constructing a recursive extension, which in - turn gives all uses of the regular "$ref" keyword confidence - that it only behaves as it appears to, using lexical scoping. - - - The "$recursiveAnchor" keyword is how schema authors indicate - that a schema can be extended recursively, and be a recursive - schema. This keyword MAY appear in the root schema of a - schema document, and MUST NOT appear in any subschema. - - - The value of "$recursiveAnchor" MUST be of type boolean, and - MUST be true. The value false is reserved for possible future use. - -
-
- - The "$recursiveRef" keyword behaves identically to "$ref", except - that if the referenced schema has "$recursiveAnchor" set to true, - then the implementation MUST examine the dynamic scope for the - outermost (first seen) schema document with "$recursiveAnchor" - set to true. If such a schema document exists, then the target - of the "$recursiveRef" MUST be set to that document's URI, in - place of the URI produced by the rules for "$ref". - - - Note that if the schema referenced by "$recursiveRef" does not - contain "$recursiveAnchor" set to true, or if there are no other - "$recursiveAnchor" keywords set to true anywhere further back in - the dynamic scope, then "$recursiveRef"'s behavior is identical - to that of "$ref". - -
- - With this in mind, we can rewrite the previous example: - - - - - - Note that the "r" property no longer appears in the - extension schema. Instead, all "$ref"s have been changed - to "$recursiveRef"s, and both schemas have "$recursiveAnchor" - set to true in their root schema. - -
- - When using the original schema on its own, there is no change - in behavior. The "$recursiveRef" does lead to a schema where - "$recursiveAnchor" is set to true, but since the original schema - is the only schema document in the dynamics scope (it references - itself, and does not reference any other schema documents), the - behavior is effectively the same as "$ref". - - - When using the extension schema, the "$recursiveRef" within - that schema (for the array items within "things") also effectively - behaves like "$ref". The extension schema is the outermost - dynamic scope, so the reference target is not changed. - - - In contrast, when using the extension schema, the "$recursiveRef" - for "r" in the original schema now behaves differently. Its - initial target is the root schema of the original schema document, - which has "$recursiveAnchor" set to true. In this case, the - outermost dynamic scope that also has "$recursiveAnchor" set to - true is the extension schema. So when using the extensions schema, - "r"'s reference in the original schema will resolve to - "https://example.com/extension#", not "https://example.com/original#". - -
-
- -
- - A schema MUST NOT be run into an infinite loop against an instance. For - example, if two schemas "#alice" and "#bob" both have an "allOf" property - that refers to the other, a naive validator might get stuck in an infinite - recursive loop trying to validate the instance. Schemas SHOULD NOT make - use of infinite recursive nesting like this; the behavior is undefined. - -
- -
- - The use of URIs to identify remote schemas does not necessarily mean anything is downloaded, - but instead JSON Schema implementations SHOULD understand ahead of time which schemas they will be using, - and the URIs that identify them. - - - When schemas are downloaded, - for example by a generic user-agent that doesn't know until runtime which schemas to download, - see Usage for Hypermedia. - - - Implementations SHOULD be able to associate arbitrary URIs with an arbitrary - schema and/or automatically associate a schema's "$id"-given URI, depending - on the trust that the validator has in the schema. Such URIs and schemas - can be supplied to an implementation prior to processing instances, or may - be noted within a schema document as it is processed, producing associations - as shown in section . - - - A schema MAY (and likely will) have multiple URIs, but there is no way for a - URI to identify more than one schema. When multiple schemas try to identify - as the same URI, validators SHOULD raise an error condition. - -
-
- - Schemas can be identified by any URI that has been given to them, including - a JSON Pointer or their URI given directly by "$id". In all cases, - dereferencing a "$ref" reference involves first resolving its value as a - URI reference against the current base URI per - RFC 3986. - - - If the resulting URI identifies a schema within the current document, or - within another schema document that has been made available to the implementation, - then that schema SHOULD be used automatically. - - - For example, consider this schema: - - -
- - - -
- - When an implementation encounters the <#/$defs/single> schema, - it resolves the "$id" URI reference against the current base URI to form - <http://example.net/root.json#item>. - - - When an implementation then looks inside the <#/items> schema, it - encounters the <#item> reference, and resolves this to - <http://example.net/root.json#item>, which it has seen defined in - this same document and can therefore use automatically. - - - When an implementation encounters the reference to "other.json", it resolves - this to <http://example.net/other.json>, which is not defined in this - document. If a schema with that identifier has otherwise been supplied to - the implementation, it can also be used automatically. - - What should implementations do when the referenced schema is not known? - Are there circumstances in which automatic network dereferencing is - allowed? A same origin policy? A user-configurable option? In the - case of an evolving API described by Hyper-Schema, it is expected that - new schemas will be added to the system dynamically, so placing an - absolute requirement of pre-loading schema documents is not feasible. - - -
-
- -
- - The "$defs" keyword provides a standardized location for schema - authors to inline re-usable JSON Schemas into a more general schema. - The keyword does not directly affect the validation result. - - - This keyword's value MUST be an object. - Each member value of this object MUST be a valid JSON Schema. - - - As an example, here is a schema describing an array of positive - integers, where the positive integer constraint is a subschema in - "$defs": - -
- - - -
-
-
-
- -
- - This keyword is reserved for comments from schema authors to readers or - maintainers of the schema. - - The value of this keyword MUST be a string. Implementations MUST NOT present this - string to end users. Tools for editing schemas SHOULD support displaying and - editing this keyword. The value of this keyword MAY be used in debug or error - output which is intended for developers making use of schemas. - - Schema vocabularies SHOULD allow "$comment" within any object containing - vocabulary keywords. Implementations MAY assume "$comment" is allowed - unless the vocabulary specifically forbids it. Vocabularies MUST NOT - specify any effect of "$comment" beyond what is described in this - specification. - - Tools that translate other media types or programming languages - to and from application/schema+json MAY choose to convert that media type or - programming language's native comments to or from "$comment" values. - The behavior of such translation when both native comments and "$comment" - properties are present is implementation-dependent. - - Implementations SHOULD treat "$comment" identically to an unknown extension - keyword. They MAY strip "$comment" values at any point during processing. - In particular, this allows for shortening schemas when the size of deployed - schemas is a concern. - - Implementations MUST NOT take any other action based on the presence, absence, - or contents of "$comment" properties. In particular, the value of "$comment" - MUST NOT be collected as an annotation result. - -
- -
- - Annotations are collected by keywords that explicitly define - annotation-collecting behavior. Note that boolean schemas cannot - produce annotations as they do not make use of keywords. - - - A collected annotation MUST include the following information: - - - The name of the keyword that produces the annotation - - - The instance location to which it is attached, as a JSON Pointer - - - The schema location path, indicating how reference keywords - such as "$ref" were followed to reach the absolute schema location. - - - The absolute schema location of the attaching keyword, as a URI. - This MAY be omitted if it is the same as the schema location path - from above. - - - The attached value(s) - - - - - If the same keyword attaches values from multiple schema locations - to the same instance location, and the annotation defines a process - for combining such values, then the combined value MUST also be associated - with the instance location. - -
- - Applications MAY make decisions on which of multiple annotation values - to use based on the schema location that contributed the value. - This is intended to allow flexible usage. Collecting the schema location - facilitates such usage. - - - For example, consider this schema, which uses annotations and assertions from - the Validation specification: - -
- - Note that some lines are wrapped for clarity. - - - - -
- - In this example, both Feature A and Feature B make use of the re-usable - "enabledToggle" schema. That schema uses the "title", "description", - and "default" annotations, none of which define special behavior for - handling multiple values. Therefore the application has to decide how - to handle the additional "default" value for Feature A, and the additional - "description" value for Feature B. - - - The application programmer and the schema author need to agree on the - usage. For this example, let's assume that they agree that the most - specific "default" value will be used, and any additional, more generic - "default" values will be silently ignored. Let's also assume that they - agree that all "description" text is to be used, starting with the most - generic, and ending with the most specific. This requires the schema - author to write descriptions that work when combined in this way. - - - The application can use the schema location path to determine which - values are which. The values in the feature's immediate "enabled" - property schema are more specific, while the values under the re-usable - schema that is referenced to with "$ref" are more generic. The schema - location path will show whether each value was found by crossing a - "$ref" or not. - - - Feature A will therefore use a default value of true, while Feature B - will use the generic default value of null. Feature A will only - have the generic description from the "enabledToggle" schema, while - Feature B will use that description, and also append its locally - defined description that explains how to interpret a null value. - - - Note that there are other reasonable approaches that a different application - might take. For example, an application may consider the presence of - two different values for "default" to be an error, regardless of their - schema locations. - -
-
- - Schema objects that produce a false assertion result MUST NOT - produce any annotation results, whether from their own keywords - or from keywords in subschemas. - - - Note that the overall schema results may still include annotations - collected from other schema locations. Given this schema: - -
- - - -
- - And the instance "This is a string", the - title annotation "Integer Value" is discarded because the type assertion - in that schema object fails. The title annotation "String Value" - is kept, as the instance passes the string type assertions. - -
-
- - In addition to possibly defining annotation results of their own, - applicator keywords aggregate the annotations collected in their - subschema(s) or referenced schema(s). The rules for aggregating - annotation values are defined by each annotation keyword, and are - not directly affected by the logic used for combining assertion - results. - -
-
- -
- - This section defines a vocabulary of applicator keywords that - are RECOMMENDED for use as the basis of other vocabularies. - - - The current URI for this vocabulary, known as the Applicator vocabulary, is: - . - - - The current URI for the corresponding meta-schema is: - . - - - Meta-schemas that do not use "$vocabulary" SHOULD be considered to - require this vocabulary as if its URI were present with a value of true. - -
- - Schema keywords typically operate independently, without - affecting each other's outcomes. - - - For schema author convenience, there are some exceptions among the - keywords in this vocabulary: - - - "additionalProperties", whose behavior is defined in terms of - "properties" and "patternProperties" - - - "unevaluatedProperties", whose behavior is defined in terms of - annotations from "properties", "patternProperties", - "additionalProperties" and itself - - - "additionalItems", whose behavior is defined in terms of "items" - - - "unevaluatedItems", whose behavior is defined in terms of annotations - from "items", "additionalItems" and itself - - - -
- -
- - These keywords apply subschemas to the same location in the instance - as the parent schema is being applied. They allow combining - or modifying the subschema results in various ways. - - -
- - These keywords correspond to logical operators for combining or modifying - the boolean assertion results of the subschemas. They have no direct - impact on annotation collection, although they enable the same annotation - keyword to be applied to an instance location with different values. - Annotation keywords define their own rules for combining such values. - -
- - This keyword's value MUST be a non-empty array. - Each item of the array MUST be a valid JSON Schema. - - - An instance validates successfully against this keyword if it validates - successfully against all schemas defined by this keyword's value. - -
- -
- - This keyword's value MUST be a non-empty array. - Each item of the array MUST be a valid JSON Schema. - - - An instance validates successfully against this keyword if it validates - successfully against at least one schema defined by this keyword's value. - -
- -
- - This keyword's value MUST be a non-empty array. - Each item of the array MUST be a valid JSON Schema. - - - An instance validates successfully against this keyword if it validates - successfully against exactly one schema defined by this keyword's value. - -
- -
- - This keyword's value MUST be a valid JSON Schema. - - - An instance is valid against this keyword if it fails to validate - successfully against the schema defined by this keyword. - -
-
- -
- - Three of these keywords work together to implement conditional - application of a subschema based on the outcome of another subschema. - The fourth is a shortcut for a specific conditional case. - - - "if", "then", and "else" MUST NOT interact with each other across - subschema boundaries. In other words, an "if" in one - branch of an "allOf" MUST NOT have an impact on a "then" - or "else" in another branch. - - - There is no default behavior for "if", "then", or "else" - when they are not present. In particular, they MUST NOT - be treated as if present with an empty schema, and when - "if" is not present, both "then" and "else" MUST be - entirely ignored. - -
- - This keyword's value MUST be a valid JSON Schema. - - - This validation outcome of this keyword's subschema - has no direct effect on the overall validation - result. Rather, it controls which of the "then" - or "else" keywords are evaluated. - - - Instances that successfully validate against this - keyword's subschema MUST also be valid against - the subschema value of the "then" keyword, if - present. - - - Instances that fail to validate against this - keyword's subschema MUST also be valid against - the subschema value of the "else" keyword, if - present. - - - If annotations - are being collected, they are collected from this - keyword's subschema in the usual way, including when - the keyword is present without either "then" or "else". - -
-
- - This keyword's value MUST be a valid JSON Schema. - - - When "if" is present, and the instance successfully - validates against its subschema, then validation - succeeds against this keyword if the instance also - successfully validates against this keyword's subschema. - - - This keyword has no effect when "if" is absent, or - when the instance fails to validate against its - subschema. Implementations MUST NOT evaluate - the instance against this keyword, for either validation - or annotation collection purposes, in such cases. - -
-
- - This keyword's value MUST be a valid JSON Schema. - - - When "if" is present, and the instance fails to - validate against its subschema, then validation - succeeds against this keyword if the instance - successfully validates against this keyword's subschema. - - - This keyword has no effect when "if" is absent, or - when the instance successfully validates against its - subschema. Implementations MUST NOT evaluate - the instance against this keyword, for either validation - or annotation collection purposes, in such cases. - -
-
- - This keyword specifies subschemas that are evaluated if the instance - is an object and contains a certain property. - - - This keyword's value MUST be an object. - Each value in the object MUST be a valid JSON Schema. - - - If the object key is a property in the instance, the entire - instance must validate against the subschema. Its use is - dependent on the presence of the property. - - - Omitting this keyword has the same behavior as an empty object. - -
-
-
-
- - Each of these keywords defines a rule for applying its - subschema(s) to child instances, specifically object - properties and array items, and combining their results. - -
-
- - The value of "items" MUST be either a valid JSON Schema or - an array of valid JSON Schemas. - - - If "items" is a schema, validation succeeds if all elements - in the array successfully validate against that schema. - - - If "items" is an array of schemas, validation succeeds if - each element of the instance validates against the schema at the - same position, if any. - - - This keyword produces an annotation value which is the largest - index to which this keyword applied a subschema. The value - MAY be a boolean true if a subschema was applied to every - index of the instance, such as when "items" is a schema. - - - Annotation results for "items" keywords from multiple - schemas applied to the same instance location are combined - by setting the combined result to true if any of the values - are true, and otherwise retaining the largest numerical value. - - - Omitting this keyword has the same assertion behavior as - an empty schema. - -
- -
- - The value of "additionalItems" MUST be a valid JSON Schema. - - - The behavior of this keyword depends on the presence and - annotation result of "items" within the same schema object. - If "items" is present, and its annotation result is a number, - validation succeeds if every instance element at an index - greater than that number validates against "additionalItems". - - - Otherwise, if "items" is absent or its annotation result - is the boolean true, "additionalItems" MUST be ignored. - - - If the "additionalItems" subschema is applied to any - positions within the instance array, it produces an - annotation result of boolean true, analogous to the - single schema behavior of "items". If any "additionalItems" - keyword from any subschema applied to the same instance - location produces an annotation value of true, then - the combined result from these keywords is also true. - - - Omitting this keyword has the same assertion behavior as - an empty schema. - - - Implementations MAY choose to implement or optimize this keyword - in another way that produces the same effect, such as by directly - checking for the presence and size of an "items" array. - Implementations that do not support annotation collection MUST do so. - -
- -
- - The value of "unevaluatedItems" MUST be a valid JSON Schema. - - - The behavior of this keyword depends on the annotation results of - adjacent keywords that apply to the instance location being validated. - Specifically, the annotations from "items" and "additionalItems", - which can come from those keywords when they are adjacent to the - "unevaluatedItems" keyword. Those two annotations, as well as - "unevaluatedItems", can also result from any and all adjacent - in-place applicator keywords. - This includes but is not limited to the in-place applicators - defined in this document. - - - If an "items" annotation is present, and its annotation result - is a number, and no "additionalItems" or "unevaluatedItems" - annotation is present, then validation succeeds if every instance - element at an index greater than the "items" annotation validates - against "unevaluatedItems". - - - Otherwise, if any "items", "additionalItems", or "unevaluatedItems" - annotations are present with a value of boolean true, then - "unevaluatedItems" MUST be ignored. However, if none of these - annotations are present, "unevaluatedItems" MUST be applied to - all locations in the array. - - - This means that "items", "additionalItems", and all in-place applicators - MUST be evaluated before this keyword can be evaluated. Authors of - extension keywords MUST NOT define an in-place applicator that would need - to be evaluated before this keyword. - - - If the "unevaluatedItems" subschema is applied to any - positions within the instance array, it produces an - annotation result of boolean true, analogous to the - single schema behavior of "items". If any "unevaluatedItems" - keyword from any subschema applied to the same instance - location produces an annotation value of true, then - the combined result from these keywords is also true. - - - Omitting this keyword has the same assertion behavior as - an empty schema. - - - Implementations that do not collect annotations MUST raise an error - upon encountering this keyword. - -
- -
- - The value of this keyword MUST be a valid JSON Schema. - - - An array instance is valid against "contains" if at least one of - its elements is valid against the given schema. This keyword - does not produce annotation results. - - Should it produce a set of the indices for which the - array element is valid against the subschema? "contains" - does not affect "additionalItems" or any other current - or proposed keyword, but the information could be useful, - and implementation that collect annotations need to - apply "contains" to every element anyway. - - -
-
- -
-
- - The value of "properties" MUST be an object. - Each value of this object MUST be a valid JSON Schema. - - - Validation succeeds if, for each name that appears in both - the instance and as a name within this keyword's value, the child - instance for that name successfully validates against the - corresponding schema. - - - The annotation result of this keyword is the set of instance - property names matched by this keyword. Annotation results - for "properties" keywords from multiple schemas applied to - the same instance location are combined by taking the union - of the sets. - - - Omitting this keyword has the same assertion behavior as - an empty object. - -
- -
- - The value of "patternProperties" MUST be an object. Each property name - of this object SHOULD be a valid regular expression, according to the - ECMA 262 regular expression dialect. Each property value of this object - MUST be a valid JSON Schema. - - - Validation succeeds if, for each instance name that matches any - regular expressions that appear as a property name in this keyword's value, - the child instance for that name successfully validates against each - schema that corresponds to a matching regular expression. - - - The annotation result of this keyword is the set of instance - property names matched by this keyword. Annotation results - for "patternProperties" keywords from multiple schemas applied to - the same instance location are combined by taking the union - of the sets. - - - Omitting this keyword has the same assertion behavior as - an empty object. - -
- -
- - The value of "additionalProperties" MUST be a valid JSON Schema. - - - The behavior of this keyword depends on the presence and - annotation results of "properties" and "patternProperties" - within the same schema object. - Validation with "additionalProperties" applies only to the child - values of instance names that do not appear in the annotation - results of either "properties" or "patternProperties". - - - For all such properties, validation succeeds if the child instance - validates against the "additionalProperties" schema. - - - The annotation result of this keyword is the set of instance - property names validated by this keyword's subschema. - Annotation results for "additionalProperties" keywords from - multiple schemas applied to the same instance location are combined - by taking the union of the sets. - - - Omitting this keyword has the same assertion behavior as - an empty schema. - - - Implementations MAY choose to implement or optimize this keyword - in another way that produces the same effect, such as by directly - checking the names in "properties" and the patterns in - "patternProperties" against the instance property set. - Implementations that do not support annotation collection MUST do so. - -
- -
- - The value of "unevaluatedProperties" MUST be a valid JSON Schema. - - - The behavior of this keyword depends on the annotation results of - adjacent keywords that apply to the instance location being validated. - Specifically, the annotations from "properties", "patternProperties", - and "additionalProperties", which can come from those keywords when - they are adjacent to the "unevaluatedProperties" keyword. Those - three annotations, as well as "unevaluatedProperties", can also - result from any and all adjacent - in-place applicator keywords. - This includes but is not limited to the in-place applicators - defined in this document. - - - Validation with "unevaluatedProperties" applies only to the child - values of instance names that do not appear in the "properties", - "patternProperties", "additionalProperties", or - "unevaluatedProperties" annotation results that apply to the - instance location being validated. - - - For all such properties, validation succeeds if the child instance - validates against the "unevaluatedProperties" schema. - - - This means that "properties", "patternProperties", "additionalProperties", - and all in-place applicators MUST be evaluated before this keyword can - be evaluated. Authors of extension keywords MUST NOT define an in-place - applicator that would need to be evaluated before this keyword. - - - The annotation result of this keyword is the set of instance - property names validated by this keyword's subschema. - Annotation results for "unevaluatedProperties" keywords from - multiple schemas applied to the same instance location are combined - by taking the union of the sets. - - - Omitting this keyword has the same assertion behavior as - an empty schema. - - - Implementations that do not collect annotations MUST raise an error - upon encountering this keyword. - -
- -
- - The value of "propertyNames" MUST be a valid JSON Schema. - - - If the instance is an object, this keyword validates if every property name in - the instance validates against the provided schema. - Note the property name that the schema is testing will always be a string. - - - Omitting this keyword has the same behavior as an empty schema. - -
-
-
-
- -
- - JSON Schema is defined to be platform-independent. As such, to increase compatibility - across platforms, implementations SHOULD conform to a standard validation output - format. This section describes the minimum requirements that consumers will need to - properly interpret validation results. - - -
- - JSON Schema output is defined using the JSON Schema data instance model as described - in section 4.2.1. Implementations MAY deviate from this as supported by their - specific languages and platforms, however it is RECOMMENDED that the output be - convertible to the JSON format defined herein via serialization or other means. - -
- -
- - This specification defines four output formats. See the "Output Structure" - section for the requirements of each format. - - - Flag - A boolean which simply indicates the overall validation result - with no further details. - - - Basic - Provides validation information in a flat list structure. - - - Detailed - Provides validation information in a condensed hierarchical - structure based on the structure of the schema. - - - Verbose - Provides validation information in an uncondensed hierarchical - structure that matches the exact structure of the schema. - - - An implementation SHOULD provide at least the "flag", "basic", or "detailed" - format and MAY provide the "verbose" format. If it provides one or more of the - complex formats, it MUST also provide the "flag" format. Implementations SHOULD - specify in their documentation which formats they support. - - -
- -
- - Beyond the simplistic "flag" output, additional information is useful to aid in - debugging a schema or instance. Each sub-result SHOULD contain the information - contained within this section at a minimum. - - - A single object that contains all of these components is considered an - output unit. - - - Implementations MAY elect to provide additional information. - - -
- - The relative location of the validating keyword that follows the validation - path. The value MUST be expressed as a JSON Pointer, and it MUST include - any by-reference applicators such as "$ref" or "$recursiveRef". - -
- - - -
- - Note that this pointer may not be resolvable due to the inclusion of these - applicator keywords. - - - The JSON key for this information is "keywordLocation". - -
- -
- - The absolute, dereferenced location of the validating keyword. The value MUST - be expressed as an absolute URI, and it MUST NOT include by-reference applicators - such as "$ref" or "$recursiveRef". - -
- - - -
- - This information MAY be omitted only if either the relative location contains - no references or if the schema does not declare an absolute URI as its "$id". - - - The JSON key for this information is "absoluteKeywordLocation". - -
- -
- - The location of the JSON value within the instance being validated. The - value MUST be expressed as a JSON Pointer. - - - The JSON key for this information is "instanceLocation". - -
- -
- - The error or annotation that is produced by the validation. - - - For errors, the specific wording for the message is not defined by this - specification. Implementations will need to provide this. - - - The JSON key for failed validations is "error"; for successful validations - it is "annotation". - -
- -
- - For the two hierarchical structures, this property will hold nested errors - and annotations. - - - The JSON key for nested results in failed validations is "errors"; for - successful validations it is "annotations". - -
- -
- -
- - The output MUST be an object containing a boolean property named "valid". When - additional information about the result is required, the output MUST also contain - "errors" or "annotations" as described below. - - - "valid" - a boolean value indicating the overall validation success or - failure - - - "errors" - the collection of errors or annotations produced by a failed - validation - - - "annotations" - the collection of errors or annotations produced by a - successful validation - - - For these examples, the following schema and instance will be used. - -
- - - -
- - This instance will fail validation and produce errors, but it's trivial to deduce - examples for passing schemas that produce annotations. - - - Specifically, the errors it will produce are: - - - The second element in the "vertices" property is missing a "y" property. - - - The second element in the "vertices" property has a disallowed "z" property. - - - There are only two vertices, but three are required. - - - Note that neither the error message property nor its wording as depicted in these - examples is not a requirement of this specification. Implementations SHOULD craft - error messages tailored for their audience. - - -
- - In the simplest case, merely the boolean result for the "valid" valid property - needs to be fulfilled. - -
- - - -
- - Because no errors or annotations are returned with this format, it is - RECOMMENDED that implementations use short-circuiting logic to return - failure or success as soon as the outcome can be determined. For example, - if an "anyOf" keyword contains five sub-schemas, and the second one - passes, there is no need to check the other three. The logic can simply - return with success. - -
- -
- - The "Basic" structure is a flat list of output units. - -
- - - -
-
- -
- - The "Detailed" structure is based on the schema and can be more readable - for both humans and machines. Having the structure organized this way makes - associations between the errors more apparent. For example, the fact that - the missing "y" property and the extra "z" property both stem from the same - location in the instance is not immediately obvious in the "Basic" structure. - In a hierarchy, the correllation is more easily identified. - - - The following rules govern the construction of the results object: - - - All applicator keywords ("*Of", "$ref", "if"/"then"/"else", etc.) require - a node. - - - Nodes that have no children are removed. - - - Nodes that have a single child are replaced by the child. - - - Branch nodes do not require an error message or an annotation. - -
- - - -
-
- -
- - The "Verbose" structure is a fully realized hierarchy that exactly matches - that of the schema. This structure has applications in form generation and - validation where the error's location is important. - - - The primary difference between this and the "Detailed" structure is that - all results are returned. This includes sub-schema validation results that - would otherwise be removed (e.g. annotations for failed validations, - successful validations inside a `not` keyword, etc.). Because of this, it - is RECOMMENDED that each node also carry a `valid` property to indicate the - validation result for that node. - - - Because this output structure can be quite large, a smaller example is given - here for brevity. The full output structure of the example above can be found - here. - -
- - - -
-
- -
- - For convenience, a JSON Schema has been provided to validate output generated - by implementations. It can be found here. - -
- -
- -
- -
- - - JSON has been adopted widely by HTTP servers for automated APIs and robots. This - section describes how to enhance processing of JSON documents in a more RESTful - manner when used with protocols that support media types and - Web linking. - - -
- - It is RECOMMENDED that instances described by a schema provide a link to - a downloadable JSON Schema using the link relation "describedby", as defined by - Linked Data Protocol 1.0, section 8.1. - - - - In HTTP, such links can be attached to any response using the - Link header. An example of such a header would be: - - -
- -; rel="describedby" -]]> - -
- -
- - -
- - Media types MAY allow for a "schema" media type parameter, which gives - HTTP servers the ability to perform Content-Type Negotiation based on schema. - The media-type parameter MUST be a whitespace-separated list of URIs - (i.e. relative references are invalid). - - - When using the media type application/schema-instance+json, the "schema" - parameter MUST be supplied. - - - When using the media type application/schema+json, the "schema" parameter - MAY be supplied. If supplied, it SHOULD contain the same URI as identified - by the "$schema" keyword, and MAY contain additional URIs. The "$schema" - URI MUST be considered the schema's canonical meta-schema, regardless - of the presence of alternative or additional meta-schemas as a media type - parameter. - - - The schema URI is opaque and SHOULD NOT automatically be dereferenced. - If the implementation does not understand the semantics of the provided schema, - the implementation can instead follow the "describedby" links, if any, which may - provide information on how to handle the schema. - Since "schema" doesn't necessarily point to a network location, the - "describedby" relation is used for linking to a downloadable schema. - However, for simplicity, schema authors should make these URIs point to the same - resource when possible. - - - - In HTTP, the media-type parameter would be sent inside the Content-Type header: - - -
- - - -
- - - Multiple schemas are whitespace separated, and indicate that the - instance conforms to all of the listed schemas: - - -
- - - -
- - - Media type parameters are also used in HTTP's Accept request header: - - -
- - - -
- - - As with Content-Type, multiple schema parameters in the same string - requests an instance that conforms to all of the listed schemas. - - - - Unlike Content-Type, Accept can contain multiple values to - indicate that the client can accept several media types. - In the above example, note that the two media types differ - only by their schema parameter values. This requests an - application/json representation that conforms to at least one - of the identified schemas. - - - - - This paragraph assumes that we can register a "schema" link relation. - Should we instead specify something like "tag:json-schema.org,2017:schema" - for now? - - HTTP can also send the "schema" in a Link, though this may impact media-type - semantics and Content-Type negotiation if this replaces the media-type parameter - entirely: - - -
- -;rel="schema", ;rel="schema" -]]> - -
- -
- -
- - When used for hypermedia systems over a network, - HTTP is frequently the protocol of choice for - distributing schemas. Misbehaving clients can pose problems for server - maintainers if they pull a schema over the network more frequently than - necessary, when it's instead possible to cache a schema for a long period of - time. - - - HTTP servers SHOULD set long-lived caching headers on JSON Schemas. - HTTP clients SHOULD observe caching headers and not re-request documents within - their freshness period. - Distributed systems SHOULD make use of a shared cache and/or caching proxy. - - - Clients SHOULD set or prepend a User-Agent header specific to the JSON Schema - implementation or software product. Since symbols are listed in decreasing order - of significance, the JSON Schema library name/version should precede the more - generic HTTP library name (if any). For example: -
- - - -
-
- - Clients SHOULD be able to make requests with a "From" header so that server - operators can contact the owner of a potentially misbehaving script. - -
- -
- -
- - Both schemas and instances are JSON values. As such, all security considerations - defined in RFC 8259 apply. - - - Instances and schemas are both frequently written by untrusted third parties, to be - deployed on public Internet servers. - Validators should take care that the parsing and validating against schemas doesn't consume excessive - system resources. - Validators MUST NOT fall into an infinite loop. - - - Servers MUST ensure that malicious parties can't change the functionality of - existing schemas by uploading a schema with a pre-existing or very similar "$id". - - - Individual JSON Schema vocabularies are liable to also have their own security - considerations. Consult the respective specifications for more information. - - - Schema authors should take care with "$comment" contents, as a malicious - implementation can display them to end-users in violation of a spec, or - fail to strip them if such behavior is expected. - - - A malicious schema author could place executable code or other dangerous - material within a "$comment". Implementations MUST NOT parse or otherwise - take action based on "$comment" contents. - -
- -
-
- - The proposed MIME media type for JSON Schema is defined as follows: - - - Type name: application - Subtype name: schema+json - Required parameters: N/A - - Optional parameters: - - - A non-empty list of space-separated URIs, each identifying - a JSON Schema resource. The instance SHOULD successfully - validate against at least one of these meta-schemas. - Non-validating meta-schemas MAY be included for purposes such - as allowing clients to make use of older versions of - a meta-schema as long as the runtime instance validates - against that older version. - - - - - Encoding considerations: Encoding considerations are - identical to those specified for the "application/json" - media type. See JSON. - - - Security considerations: See Section - above. - - - Interoperability considerations: See Sections - , - , and - above. - - - Fragment identifier considerations: See Section - - - - -
-
- - The proposed MIME media type for JSON Schema Instances that require - a JSON Schema-specific media type is defined as follows: - - - Type name: application - Subtype name: schema-instance+json - - Required parameters: - - - A non-empty list of space-separated URIs, each identifying - a JSON Schema resource. The instance SHOULD successfully - validate against at least one of these schemas. - Non-validating schemas MAY be included for purposes such - as allowing clients to make use of older versions of a schema - as long as the runtime instance validates against that - older version. - - - - - Encoding considerations: Encoding considerations are - identical to those specified for the "application/json" - media type. See JSON. - - - Security considerations: See Section - above. - - - Interoperability considerations: See Sections - , - , and - above. - - - Fragment identifier considerations: See Section - - - - -
-
-
- - - - - &RFC2119; - &RFC3986; - &RFC6839; - &RFC6901; - &RFC8259; - &ldp; - - - ECMA 262 specification - - - - - - - - &RFC7049; - &RFC7231; - &RFC8288; - &fragid-best-practices; - - - JSON Schema Validation: A Vocabulary for Structural Validation of JSON - - - - - - - - - - - - - - - - JSON Hyper-Schema: A Vocabulary for Hypermedia Annotation of JSON - - - - - - - - - - - - -
- - Thanks to - Gary Court, - Francis Galiegue, - Kris Zyp, - and Geraint Luff - for their work on the initial drafts of JSON Schema. - - - Thanks to - Jason Desrosiers, - Daniel Perrett, - Erik Wilde, - Ben Hutton, - Evgeny Poberezkin, - Brad Bowman, - Gowry Sankar, - Donald Pipowitch, - and Dave Finlay - for their submissions and patches to the document. - -
- -
- - This section to be removed before leaving Internet-Draft status. - - - - - - Moved "definitions" from the Validation specification here as "$defs" - Moved applicator keywords from the Validation specification as their own vocabulary - Moved the schema form of "dependencies" from the Validation specification as "dependentSchemas" - - - - - This draft is purely a clarification with no functional changes - Emphasized annotations as a primary usage of JSON Schema - Clarified $id by use cases - Exhaustive schema identification examples - Replaced "external referencing" with how and when an implementation might know of a schema from another document - Replaced "internal referencing" with how an implementation should recognized schema identifiers during parsing - Dereferencing the former "internal" or "external" references is always the same process - Minor formatting improvements - - - - - Make the concept of a schema keyword vocabulary more clear - Note that the concept of "integer" is from a vocabulary, not the data model - Classify keywords as assertions or annotations and describe their general behavior - Explain the boolean schemas in terms of generalized assertions - Reserve "$comment" for non-user-visible notes about the schema - Wording improvements around "$id" and fragments - Note the challenges of extending meta-schemas with recursive references - Add "application/schema-instance+json" media type - Recommend a "schema" link relation / parameter instead of "profile" - - - - - Updated intro - Allowed for any schema to be a boolean - "$schema" SHOULD NOT appear in subschemas, although that may change - Changed "id" to "$id"; all core keywords prefixed with "$" - Clarify and formalize fragments for application/schema+json - Note applicability to formats such as CBOR that can be represented in the JSON data model - - - - - Updated references to JSON - Updated references to HTTP - Updated references to JSON Pointer - Behavior for "id" is now specified in terms of RFC3986 - Aligned vocabulary usage for URIs with RFC3986 - Removed reference to draft-pbryan-zyp-json-ref-03 - Limited use of "$ref" to wherever a schema is expected - Added definition of the "JSON Schema data model" - Added additional security considerations - Defined use of subschema identifiers for "id" - Rewrote section on usage with HTTP - Rewrote section on usage with rel="describedBy" and rel="profile" - Fixed numerous invalid examples - - - - - Salvaged from draft v3. - Split validation keywords into separate document. - Split hypermedia keywords into separate document. - Initial post-split draft. - Mandate the use of JSON Reference, JSON Pointer. - Define the role of "id". Define URI resolution scope. - Add interoperability considerations. - - - - - Initial draft. - - - - -
-
-
diff --git a/jsonschema-hyperschema.xml b/jsonschema-hyperschema.xml deleted file mode 100644 index f7741632..00000000 --- a/jsonschema-hyperschema.xml +++ /dev/null @@ -1,2813 +0,0 @@ - - - - - - - - - - - - - - - - -]> - - - - - - - - - - - - JSON Hyper-Schema: A Vocabulary for Hypermedia Annotation of JSON - - - -
- - - San Francisco - CA - USA - - henry@cloudflare.com -
-
- - -
- aaa@bzfx.net -
-
- - - Internet Engineering Task Force - JSON - Schema - JavaScript - Object - Notation - Hyper Schema - Hypermedia - - - - JSON Schema is a JSON-based format for describing JSON data using various - vocabularies. This document specifies a vocabulary for annotating JSON - documents with hyperlinks. These hyperlinks include attributes describing - how to manipulate and interact with remote resources through hypermedia - environments such as HTTP, as well as determining whether the link is usable - based on the instance value. The hyperlink serialization format described in - this document is also usable independent of JSON Schema. - - - - - The issues list for this draft can be found at - . - - - For additional information, see - . - - - To provide feedback, use this issue tracker, the communication methods listed on the - homepage, or email the document editors. - - -
- - -
- - JSON Hyper-Schema is a JSON Schema vocabulary for annotating JSON documents - with hyperlinks and instructions for processing and - manipulating remote JSON resources through hypermedia environments such as HTTP. - - - The term JSON Hyper-Schema is used to refer to a JSON Schema that uses these - keywords. The term "hyper-schema" on its own refers to a JSON Hyper-Schema - within the scope of this specification. - - - The primary mechanism introduced for specifying links is the Link Description - Object (LDO), which is a serialization of the abstract link model - defined in RFC 8288, section 2. - - - This specification will use the concepts, syntax, and terminology defined by the - JSON Schema core and - JSON Schema validation specifications. - It is advised that readers have a copy of these specifications. - -
- -
- - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", - "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be - interpreted as described in RFC 2119. - -
- -
- - JSON Hyper-Schema makes it possible to build hypermedia systems from JSON - documents by describing how to construct hyperlinks from instance data. - - - The combination of a JSON instance document and a valid application/schema+json - hyper-schema for that instance behaves as a single hypermedia representation. - By allowing this separation, hyper-schema-based systems can gracefully support - applications that expect plain JSON, while providing full hypermedia capabilities - for hyper-schema-aware applications and user agents. - - - User agents can detect the presence of hyper-schema by looking for - the application/schema+json media type and a "$schema" value that indicates the - presence of the hyper-schema vocabulary. A user agent can then use an - implementation of JSON Hyper-Schema to provide an interface to the - combination of the schema and instance documents as a single logical - representation of a resource, just as with any single-document hypermedia - representation format. - - - Hyper-schemas allow representations to take up fewer bytes on the wire, and - distribute the burden of link construction from the server to each client. - A user agent need not construct a link unless a client application requests - that link. JSON Hyper-Schema can also be used on the server side to generate - other link serializations or representation formats at runtime, or pre-emptively - follow links to facilitate server push usage. - -
- - Here is an example hyper-schema that adds a single link, with the - IANA-registered link relation type "self", that is built from an instance - with one known object field named "id": - - - - - - If the instance is {"id": 1234}, and its base URI according to - RFC 3986 section 5.1, is - "https://example.com/api/", then "https://example.com/api/thing/1234" - is the resulting link's target URI. - -
- -
- - The terms "schema", "instance", and "meta-schema" are to be interpreted as - defined in the JSON Schema core specification. - - - The terms "applicable" and "attached" are to be interpreted as defined in - Section 3 of the - JSON Schema validation specification. - - - The terms "link", "link context" (or "context"), "link target" (or "target"), - and "target attributes" are to be interpreted as defined in - Section 2 of RFC 8288. - - - The term "user agent" is to be interpreted as defined in - Section 2.1 of RFC 7230, generalized to apply - to any protocol that may be used in a hypermedia system rather than - specifically being an HTTP client. - - - This specification defines the following terms: - - - A JSON Schema using the keywords defined by this specification. - - - Within this document, the term "hyper-schema" always refers to - a JSON Hyper-Schema - - - A valid link for an instance is one that is applicable to that - instance and does not fail any requirement imposed by the keywords - in the Link Description Object. Note that invalid links can - occur when using keywords such as "if" or "oneOf" (from the - Core specification) to describe links that are conditional on - the representation's structure or value. - - - A user agent which can be used to interact with any resource, from - any server, from among the standardized link relations, media types, - URI schemes, and protocols that it supports; though it may be - extendible to specially handle particular profiles of media types. - - - An application which uses a hypermedia system for a specific - purpose. Such an application may also be its own user agent, - or it may be built on top of a generic user agent. A client - application is programmed with knowledge of link relations, - media types, URI schemes, protocols, and data structures that - are specific to the application's domain. - - - Data provided through a user agent, and most often also through - a client application. Such data may be requested from a user - interactively, or provided before interaction in forms such as - command-line arguments, configuration files, or hardcoded values - in source code. - - - A specific use of a hyperlink, such as making a network request - (for a URI with a scheme such as "http://" that indicates a protocol) - or otherwise taking action based on a link (reading data from a - "data:" URI, or constructing an email message based on a "mailto:" - link). For protocols such as HTTP that support multiple methods, - each method is considered to be a separate operation on the same link. - - - -
- -
- - A JSON Hyper-Schema implementation is able to take a hyper-schema, an - instance, and in some cases client input, and produce a set of fully - resolved valid links. As defined by - RFC 8288, section 2, - a link consists of a context, a typed relation, a target, and optionally - additional target attributes. - - - The relation type and target attributes are taken directly from each link's - Link Description Object. The context and target identifiers are constructed - from some combination of URI Templates, instance data, and (in the case - of the target identifier) client input. - - - The target is always fully identified by a URI. Due to the lack of a URI - fragment identifier syntax for application/json and many other media types - that can be used with JSON Hyper-Schema, the context may be only partially - identified by a URI. In such cases, the remaining identification will be - provided as a JSON Pointer. - - - A few IANA-registered link relation types are given specific semantics in - a JSON Hyper-Schema document. A "self" link is used to interact with the - resource that the instance document represents, while "collection" and - "item" links identify resources for which collection-specific semantics - can be assumed. - -
-
- -
- - The current URI for the JSON Hyper-Schema meta-schema is - . - - - The link description format can be used without JSON - Schema, and use of this format can be declared by referencing the normative - link description schema as the schema for the data structure that uses the links. - The URI of the normative link description schema is: - . - - - JSON Hyper-Schema implementations are free to provide output in any format. - However, a specific format is defined for use in the conformance test suite, - which is also used to illustrate points in the - "Implementation Requirements", and to - show the output generated by examples. - It is RECOMMENDED that implementations be capable of producing output - in this format to facilitated testing. The URI of the JSON Schema - describing the recommended output format is - . - -
-
- - Hyper-schema keywords from all schemas that are applicable to a position - in an instance, as defined by Section - 3 of JSON Schema validation, can be used with that instance. - - - When multiple subschemas are applicable to a given sub-instance, all "link" - arrays MUST be combined, in any order, into a single set. Each object - in the resulting set MUST retain its own list of applicable "base" values, - in resolution order, from the same schema and any parent schemas. - - - As with all JSON Schema keywords, all keywords described in this section - are optional. The minimal valid JSON Hyper-schema is the blank object. - - -
- - If present, this keyword MUST be first resolved as - a URI Template, and then MUST be resolved as a URI Reference against the - current URI base of the instance. The result MUST be set as the new URI - base for the instance while processing the sub-schema containing "base" - and all sub-schemas within it. - - - The process for resolving the "base" template can be different when being - resolved for use with "anchor" than when being resolved for use with "href", - which is explained in detail in the URI Templating section. - -
- -
- - The "links" property of schemas is used to associate Link Description Objects - with instances. The value of this property MUST be an array, and the items in - the array must be Link Description Objects, as defined below. - -
-
- -
- - A Link Description Object (LDO) is a serialization of the abstract link model - defined in RFC 8288, section 2. - As described in that document, a link consists of a context, a relation type, - a target, and optionally target attributes. JSON Hyper-Schema's LDO provides - all of these, along with additional features using JSON Schema to describe input - for use with the links in various ways. - - - Due to the use of URI Templates to identify link contexts and targets, as well - as optional further use of client input when identifying targets, an LDO is - a link template that may resolve to multiple links when used with a JSON - instance document. - - - A specific use of an LDO, typically involving a request and response across - a protocol, is referred to as an operation. For many protocols, multiple - operations are possible on any given link. The protocol is indicated by - the target's URI scheme. Note that not all URI schemes indicate a protocol - that can be used for communications, and even resources with URI schemes that - do indicate such protocols need not be available over that protocol. - - - A Link Description Object MUST be an object, and the - "href" and "rel" properties - MUST be present. Each keyword is covered briefly in this section, with additional - usage explanation and comprehensive examples given later in the document. - - -
- - In JSON Hyper-Schema, the link's context resource is, by default, the - sub-instance to which it is attached (as defined by - Section 3 of the JSON Schema - validation specification). This is often not the entire instance - document. This default context can be changed using the keywords - in this section. - - - Depending on the media type of the instance, it may or may not be possible - to assign a URI to the exact default context resource. In particular, - application/json does not define a URI fragment resolution syntax, so - properties or array elements within a plain JSON document cannot be fully - identified by a URI. When it is not possible to produce a complete URI, - the position of the context SHOULD be conveyed by the URI of the instance - document, together with a separate plain-string JSON Pointer. - - - Implementations MUST be able to construct the link context's URI, and - (if necessary for full identification), a JSON Pointer in string representation - form as per RFC 6901, section 5 in place of - a URI fragment. The process for constructing a URI based on a URI template - is given in the URI Templating section. - -
- - This property sets the context URI of the link. - The value of the property is a URI Template, - and the resulting URI-reference MUST - be resolved against the base URI of the instance. - - - The URI is computed from the provided URI template using the same process - described for the "href" property, with the - exception that "hrefSchema" MUST NOT - be applied. Unlike target URIs, context URIs do not accept user input. - -
-
- - This property changes the point within the instance that is considered - to be the context resource of the link. The value of the property MUST - be a valid JSON Pointer in JSON String representation form, or a valid - Relative JSON Pointer - which is evaluated relative to the default context. - - - While an alternate context with a known URI is best set with the - "anchor" keyword, the lack of a fragment - identifier syntax for application/json means that it is usually not - possible to change the context within a JSON instance using a URI. - - - Even in "+json" media types that define JSON Pointer as a fragment - identifier syntax, if the default context is nested within an array, - it is not possible to obtain the index of the default context's position - in that array in order to construct a pointer to another property in that - same nested JSON object. This will be demonstrated in the examples. - - - The result of processing this keyword SHOULD be a URI fragment if the - media type of the instance allows for such a fragment. Otherwise it - MUST be a string-encoded JSON Pointer. - -
-
-
- - The link's relation type identifies its semantics. It is the primary - means of conveying how an application can interact with a resource. - - - Relationship definitions are not normally media type - dependent, and users are encouraged to utilize the most - suitable existing accepted relation definitions. - -
- - The value of this property MUST be either a string or - an array of strings. If the value is an array, - it MUST contain at least one string. - - - Each string MUST be a single Link Relation Type as defined - in RFC 8288, Section 2.1, including the restriction that - additional semantics SHOULD NOT be inferred based upon the - presence or absence of another link relation type. - - - This property is required. - -
-
- - A "self" link, as originally defined by Section - 4.2.7.2 of RFC 4287, indicates that the target URI identifies - a resource equivalent to the link context. In JSON Hyper-Schema, - a "self" link MUST be resolvable from the instance, and therefore - "hrefSchema" MUST NOT be present. - - - Hyper-schema authors SHOULD use "templateRequired" to ensure that the - "self" link has all instance data that is needed for use. - - - A hyper-schema implementation MUST recognize that a link with relation - type "self" that has the entire current instance document as its context - describes how a user agent can interact with the resource represented by - that instance document. - -
-
- - RFC 6573 defines and registers - the "item" and "collection" link relation types. JSON Hyper-Schema imposes - additional semantics on collection resources indicated by these types. - - - Implementations MUST recognize the target of a "collection" link and - the context of an "item" link as collections. - - - A well-known design pattern in hypermedia is to use a collection resource - to create a member of the collection and give it a server-assigned URI. - If the protocol indicated by the URI scheme defines a specific method - that is suited to creating a resource with a server-assigned URI, then - a collection resource, as identified by these link relation types, - MUST NOT define semantics for that method that conflict with the semantics - of creating a collection member. Collection resources MAY implement - item creation via such a protocol method, and user agents MAY assume - that any such operation, if it exists, has item creation semantics. - - - As such a method would correspond to JSON Hyper-Schema's data submission - concept, the "submissionSchema" - field for the link SHOULD be compatible with the schema of the - representation of the collection's items, as indicated by the "item" link's - target resource or the "self" link of the "collection" link's context - resource. - -
-
- - When no registered relation (aside from "related") applies, users are - encouraged to mint their own extension relation types, as described in - section 2.1.2 of RFC 8288. The simplest - approaches for choosing link relation type URIs are to either use - a URI scheme that is already in use to identify the system's primary - resources, or to use a human-readable, non-dereferenceable URI scheme - such as "tag", defined by RFC 4151. - - - Extension relation type URIs need not be dereferenceable, even when - using a scheme that allows it. - -
-
-
- - The target URI template is used to identify the link's target, potentially - making use of instance data. Additionally, with - "hrefSchema", this template can identify - a set of possible target resources to use based on client input. - The full process of resolving the URI template, with or without client - input, is covered in the URI Templating - section. - -
- - The value of the "href" link description property is a template used to - determine the target URI of the related resource. - The value of the instance property MUST be resolved as a - URI-reference against the base URI of the - instance. - - - This property is REQUIRED. - -
-
- -
- - The keywords in this section are used when resolving all URI Templates - involved in hyper-schema: "base", "anchor", and "href". See the - URI Templating section for the complete - template resolution algorithm. - - - Note that when resolving a "base" template, the attachment point from - which resolution begins is the attachment point of the "href" or "anchor" - keyword being resolved which requires "base" templates to be resolved, - not the attachment point of the "base" keyword itself. - -
- - The value of the "templatePointers" link description property MUST be - an object. Each property value in the object MUST be a valid - JSON Pointer, or a valid - Relative JSON Pointer - which is evaluated relative to the attachment point of the link - for which the template is being resolved. - - - For each property name in the object that matches a variable name in the - template being resolved, the value of that property adjusts the starting - position of variable resolution for that variable. Properties which - do not match template variable names in the template being resolved - MUST be ignored. - -
-
- - The value of this keyword MUST be an array, and the elements MUST be unique. - Each element SHOULD match a variable in the link's URI Template, without - percent-encoding. After completing the entire URI Template resolution - process, if any variable that is present in this array does not have - a value, the link MUST NOT be used. - -
-
- -
- - All properties in this section are advisory only. While keywords such - as "title" and "description" are used primarily to present the link - to users, those keywords that predict the nature of a link interaction - or response MUST NOT be considered authoritative. The runtime behavior - of the target resource MUST be respected whenever it conflicts with - the target attributes in the LDO. - -
- - This property defines a title for the link. - The value MUST be a string. - - - - User agents MAY use this title when presenting the link to the user. - -
- -
- - This property provides additional information beyond what - is present in the title. The value MUST be a string. - While a title is preferably short, a description can be - used to go into more detail about the purpose and usage - of the link. - - - - User agents MAY use this description when presenting - the link to the user. - -
- -
- - The value of this property represents the media type - RFC 2046, that is expected to be returned - when fetching this resource. This property value MAY be a media range - instead, using the same pattern defined in - RFC 7231, section 5.3.2 - - HTTP "Accept" header. - - - This property is analogous to the "type" property of other link - serialization formats. User agents MAY use this information to inform - the interface they present to the user before the link is followed, - but MUST NOT use this information in the interpretation of the resulting - data. Instead, a user agent MUST use the media type given by the response - for run-time interpretation. See the section on - "Security Concerns" for a detailed - examination of mis-use of "targetMediaType". - - - For protocols supporting content-negotiation, implementations MAY choose to - describe possible target media types using protocol-specific information in - "headerSchema". If both - protocol-specific information and "targetMediaType" are present, then the - value of "targetMediaType" MUST be compatible with the protocol-specific - information, and SHOULD indicate the media type that will be returned in the - absence of content negotiation. - - - When no such protocol-specific information is available, or when the - implementation does not recognize the protocol involved, then the value - SHOULD be taken to be "application/json". - -
- -
- - This property provides a schema that is expected to describe - the link target's representation. Depending on the protocol, - the schema may or may not describe the request or response to - any particular operation performed with the link. See the - JSON Hyper-Schema and HTTP section for - an in-depth discussion of how this keyword is used with HTTP. - -
- -
- - - This section attempts to strike a balance between comprehensiveness - and flexibility by deferring most of its structure to the protocol - indicated by the URI scheme. Note that a resource can be identified - by a URI with a dereferenceable scheme, yet not be accessible over - that protocol. While currently very loose, this section is expected - to become more well-defined based on draft feedback, and may change - significantly in future drafts. - - - - The value of this property is advisory only. It represents information that - is expected to be discoverable through interacting with the target resource, - typically in the form of protocol-specific control information or meta-data - such as headers returned in response to an HTTP HEAD or OPTIONS request. - The protocol is determined by the "href" URI scheme, although note that - resources are not guaranteed to be accessible over such a protocol. - - - The value of this property SHOULD be an object. The keys to this object - SHOULD be lower-cased forms of the control data field names. Each value - SHOULD be an array, in order to uniformly handle multi-valued fields. - Multiple values MUST be presented as an array, and not as a single string. - - - Protocols with control information not suitable for representation as - a JSON object MAY be represented by another data type, such as an array. - - - Values that cannot be understood as part of the indicated protocol MUST - be ignored by a JSON Hyper-Schema implementation. Applications MAY make - use of such values, but MUST NOT assume interoperability with other - implementations. - - - Implementations MUST NOT assume that all discoverable information is - accounted for in this object. Client applications MUST properly handle - run-time responses that contradict this property's values. - - - Client applications MUST NOT assume that an implementation will - automatically take any action based on the value of this property. - - - See "JSON Hyper-Schema and HTTP" for - guidance on using this keyword with HTTP and analogous protocols. - -
-
-
- - There are four ways to use client input with a link, and each - is addressed by a separate link description object keyword. When performing - operations, user agents SHOULD ignore schemas that are not relevant to their - semantics. - -
- - The value of the "hrefSchema" link description property MUST be - a valid JSON Schema. This schema is used to validate user input - or other user agent data for filling out the URI Template in - "href". - - - Omitting "hrefSchema" or setting the entire schema to "false" prevents - any user agent data from being accepted. - - - Setting any subschema that applies to a particular variable to the - JSON literal value "false" prevents any user agent data from being - accepted for that single variable. - - - For template variables that can be resolved from the instance data, - if the instance data is valid against all applicable subschemas - in "hrefSchema", then it MUST be used to pre-populate the input - data set for that variable. - - - Note that even when data is pre-populated from the instance, the - validation schema for that variable in "hrefSchema" need not be identical - to the validation schema(s) that apply to the instance data's location. - This allows for different validation rules for user agent data, such as - supporting spelled-out months for date-time input, but using the standard - date-time format for storage. - - - After input is accepted, potentially overriding the pre-populated - instance data, the resulting data set MUST successfully validate - against the value of "hrefSchema". If it does not then the link - MUST NOT be used. If it is valid, then the process given in the - "URI Templating" section continues with this updated data set. - -
- -
- - - As with "targetHints", this keyword is somewhat under-specified - to encourage experimentation and feedback as we try to balance - flexibility and clarity. - - - - If present, this property is a schema for protocol-specific request - headers or analogous control and meta-data. The value of this - object MUST be a valid JSON Schema. - The protocol is determined by the "href" URI scheme, although note that - resources are not guaranteed to be accessible over such a protocol. - The schema is advisory only; the target resource's behavior is not - constrained by its presence. - - - The purpose of this keyword is to advertise target resource interaction - features, and indicate to user agents and client applications what headers - and header values are likely to be useful. - User agents and client applications MAY use the schema to validate relevant - headers, but MUST NOT assume that missing headers or values are forbidden - from use. While schema authors MAY set "additionalProperties" to - false, this is NOT RECOMMENDED and MUST NOT prevent client applications - or user agents from supplying additional headers when requests are made. - - - The exact mapping of the JSON data model into the headers is - protocol-dependent. However, in most cases this schema SHOULD - specify a type of "object", and the property names SHOULD be - lower-cased forms of the control data field names. As with - "targetHints", the values SHOULD be described as arrays to - allow for multiple values, even if only one value is expected. - - - See the "JSON Hyper-Schema and HTTP" section - for detailed guidance on using this keyword with HTTP and - analogous protocols. - - - "headerSchema" is applicable to any request method or command that the - protocol supports. When generating a request, user agents and client - applications SHOULD ignore schemas for headers that are not relevant - to that request. - -
- -
- - In JSON Hyper-Schema, "targetSchema" - supplies a non-authoritative description of the target resource's - representation. A client application can use "targetSchema" to structure - input for replacing or modifying the representation, or as the base - representation for building a patch document based on a patch media type. - - - Alternatively, if "targetSchema" is absent or if the client application - prefers to only use authoritative information, it can interact with the - target resource to confirm or discover its representation structure. - - - "targetSchema" is not intended to describe link operation responses, - except when the response semantics indicate that it is a representation - of the target resource. In all cases, the schema indicated by the response - itself is authoritative. See - "JSON Hyper-Schema and HTTP" for detailed - examples. - -
- -
- - The "submissionSchema" and - "submissionMediaType" keywords - describe the domain of the processing function implemented by the target - resource. Otherwise, as noted above, the submission schema and media type - are ignored for operations to which they are not relevant. - - -
- - If present, this property indicates the media type format the - client application and user agent should use for the request - payload described by - "submissionSchema". - - - Omitting this keyword has the same behavior as a value of - application/json. - - - Note that "submissionMediaType" and "submissionSchema" - are not restricted to HTTP URIs. - This statement might move to wherever the example ends up. - -
- -
- - This property contains a schema which defines the acceptable structure - of the document to be encoded according to the "submissionMediaType" - property and sent to the target resource for processing. This can be - viewed as describing the domain of the processing function implemented - by the target resource. - - - This is a separate concept from the - "targetSchema" property, which - describes the target information resource (including for replacing the - contents of the resource in a PUT request), unlike "submissionSchema" - which describes the user-submitted request data to be evaluated by the - resource. "submissionSchema" is intended for use with requests that - have payloads that are not necessarily defined in terms of the target - representation. - - - Omitting "submissionSchema" has the same behavior as a value of "true". - -
-
-
-
- -
- - At a high level, a conforming implementation will meet the following - requirements. Each of these requirements is covered in more detail in the - individual keyword sections and keyword group overviews. - - - Note that the requirements around how an implementation MUST recognize - "self", "collection", and "item" links are thoroughly covered in the - link relation type section and are not - repeated here. - - - While it is not a mandatory format for implementations, the output format used - in the test suite summarizes what needs to be computed for each link before - it can be used: - - - The fully resolved URI (with scheme) of the context resource. If - the context is not the entire resource and there is a usable fragment - identifier syntax, then the URI includes a fragment. Note that there - is no such syntax for application/json. - - - The JSON Pointer for the location within the instance of the context - resource. If the instance media type supports JSON Pointers as fragment - identifiers, this pointer will be the same as the one encoded in the - fragment of the "contextUri" field. - - - The link relation type. When multiple link relation types appear - in the LDO, for the purpose of producing output, they are to be - treated as multiple LDOs, each with a single link relation type - but otherwise identical. - - - The fully resolved URI (with a scheme) of the target resource. If the - link accepts input, this can only be produced once the input has been - supplied. - - - The list of partially resolved URI references for a link that accepts - input. The first entry in the list is the partially resolved "href". - The additional entries, if any, are the partially resolved "base" values - ordered from the most immediate out to the root of the schema. - Template variables that are pre-populated in the input are not resolved - at this stage, as the pre-populated value can be overridden. - - - The data set that the user agent should use to prepopulate any - input mechanism before accepting client input. If input is to be - accepted but no fields are to be pre-populated, then this will be - an empty object. - - - The JSON Pointer for the location within the instance to which the - link is attached. By default, "contextUri" and "attachmentPointer" are - the same, but "contextUri" can be changed by LDO keywords, while - "attachmentPointer" cannot. - - - Other LDO keywords that are not involved in producing the above information - are included exactly as they appear when producing output for the test suite. - Those fields will not be further discussed here unless specifically relevant. - - -
- - Before links can be used, they must be discovered by applying the hyper-schema - to the instance and finding all applicable and valid links. Note that in - addition to collecting valid links, any "base" - values necessary to resolve each LDO's URI Templates must also be located - and associated with the LDO through whatever mechanism is most useful for - the implementation's URI Template resolution process. - - - And implementation MUST support looking up links by either their - attachment pointer or context pointer, either by performing the look-up - or by providing the set of all links with both pointers determined - so that user agents can implement the look-up themselves. - - - When performing look-ups by context pointer, links that are attached to - elements of the same array MUST be returned in the same order as the - array elements to which they are attached. - -
- -
- - Three hyper-schema keywords are URI Templates: - "base", "anchor", and "href". Each are resolved separately to URI-references, - and then the anchor or href URI-reference is resolved against the base (which - is itself resolved against earlier bases as needed, each of which was first - resolved from a URI Template to a URI-reference). - - - All three keywords share the same algorithm for resolving variables from - instance data, which makes use of the "templatePointers" and "templateRequired" - keywords. When resolving "href", both it and any "base" templates - needed for resolution to an absolute URI, the algorithm is modified to - optionally accept user input based on the "hrefSchema" keyword. - - - For each URI Template (T), the following pseudocode describes an algorithm for - resolving T into a URI-reference (R). For the purpose of this algorithm: - - - "ldo.templatePointers" is an empty object if the keyword was not - present and "ldo.templateRequired" is likewise an empty array. - - - "attachmentPointer" is the absolute JSON Pointer for the attachment - location of the LDO. - - - "getApplicableSchemas()" returns an iterable set of all (sub)schemas - that apply to the attachment point in the instance. - - - - - This algorithm should be applied first to either "href" or "anchor", - and then as needed to each successive "base". The order is important, - as it is not always possible to tell whether a template will resolve - to a full URI or a URI-reference. - - - In English, the high-level algorithm is: - - Populate template variable data from the instance - If input is desired, accept input - Check that all required variables have a value - Encode values into strings and fill out the template - - -
- - This is the high-level algorithm as pseudocode. "T" comes from either - "href" or "anchor" within the LDO, or from "base" in a containing schema. - Pseudocode for each step follows. "initialTemplateKeyword" indicates - which of the two started the process (since "base" is always resolved - in order to finish resolving one or the other of those keywords). - - - - -
- -
- - This step looks at various locations in the instance for variable values. - For each variable: - - - Use "templatePointers" to find a value if the variable - appears in that keyword's value - - - Otherwise, look for a property name matching the variable in - the instance location to which the link is attached - - - In either case, if there is a value at the location, put it in - the template resolution data set - - - -
- - - -
-
- -
- - This step is relatively complex, as there are several cases to support. - Some variables will forbid input and some will allow it. Some will - have initial values that need to be presented in the input interface, - and some will not. - - - - - Determine which variables can accept input - - - Pre-populate the input data set if the template resolution data - set has a value - - - Accept input (present a web form, make a callback, etc.) - - - Validate the input data set, (not the template resolution data set) - - - Put the input in the template resolution data set, overriding - any existing values - - - -
- - "InputForm" represents whatever sort of input mechanism is appropriate. - This may be a literal web form, or may be a more programmatic construct - such as a callback function accepting specific fields and data types, - with the given initial values, if any. - - - - -
-
- -
- - This section is straightforward, converting literals to their names - as strings, and converting numbers to strings in the most obvious manner, - and percent-encoding as needed for use in the URI. - -
- - - - - In some software environments the original JSON representation of a - number will not be available (there is no way to tell the difference - between 1.0 and 1), so any reasonable representation should be used. - Schema and API authors should bear this in mind, and use other types - (such as string or boolean) if the exact representation is - important. If the number was provide as input in the form of a - string, the string used as input SHOULD be used. - -
-
-
- -
- - For a given link, an implementation MUST make the values of all - target attribute keywords directly available to the user agent. - Implementations MAY provide additional interfaces for using this - information, as discussed in each keyword's section. - - - For a given link, an implementation MUST make the value of each - input schema keyword directly available to the user agent. - - - To encourage encapsulation of the URI Template resolution process, - implementations MAY omit the LDO keywords that are used only to - construct URIs. However, implementations MUST provide access to - the link relation type. - - - Unrecognized keywords SHOULD be made available to the user agent, - and MUST otherwise be ignored. - -
- -
- - A hyper-schema implementation SHOULD provide access to all information - needed to construct any valid request to the target resource. - - - The LDO can express all information needed to perform any operation on - a link. This section explains what hyper-schema fields a user agent - should examine to build requests from any combination of instance data - and client input. A hyper-schema implementation is not itself expected - to construct and send requests. - - - Target URI construction rules, including "hrefSchema" for accepting input, - are identical for all possible requests. - - - Requests that do not carry a body payload do not require additional keyword - support. - - - Requests that take a target representation as a payload SHOULD use the - "targetSchema" and "targetMediaType" keywords for input description and - payload validation. If a protocol allows an operation taking a payload - that is based on the representation as modified by a media type - (such as a patch media type), then such a media type SHOULD be indicated - through "targetHints" in a protocol-specific manner. - - - Requests that take a payload that is not derived from the target resource's - representation SHOULD use the "submissionSchema" and "submissionMediaType" - keywords for input description and payload validation. Protocols used in - hypermedia generally only support one such non-representation operation - per link. - - - RPC systems that pipe many application operations with arbitrarily different - request structures through a single hypermedia protocol operation are outside - of the scope of a hypermedia format such as JSON Hyper-Schema. - -
- -
- - As a hypermedia format, JSON Hyper-Schema is concerned with describing - a resource, including describing its links in sufficient detail to make - all valid requests. It is not concerned with directly describing all - possible responses for those requests. - - - As in any hypermedia system, responses are expected to be self-describing. - In the context of hyper-schema, this means that each response MUST link - its own hyper-schema(s). While responses that consist of a representation - of the target resource are expected to be valid against "targetSchema" - and "targetMediaType", those keywords are advisory only and MUST be - ignored if contradicted by the response itself. - - - Other responses, including error responses, complex redirections, and - processing status representations SHOULD also link to their own schemas - and use appropriate media types - (e.g. "application/problem+json" for errors). - Certain errors might not link a schema due to being generated by an - intermediary that is not aware of hyper-schema, rather than by the origin. - - - User agents are expected to understand protocol status codes and response - media types well enough to handle common situations, and provide enough - information to client applications to handle domain-specific responses. - - - Statically mapping all possible responses and their schemas at design time - is outside of the scope of JSON Hyper-Schema, but may be within the scope - of other JSON Schema vocabularies which build on hyper-schema - (see ). - -
- -
- - The requirements around discovering links based on their context, or - using the context of links to identify collections, present unique - challenges when used with streaming parsers. It is not possible to - authoritatively fulfill these requirements without processing the entire - schema and instance documents. - - - Such implementations MAY choose to return non-authoritative answers - based on data processed to date. When offering this approach, - implementations MUST be clear on the nature of the response, and MUST - offer an option to block and wait until all data is processed and - an authoritative answer can be returned. - -
-
- -
- - While JSON Hyper-Schema is a hypermedia format and therefore protocol-independent, - it is expected that its most common use will be in HTTP systems, or systems - using protocols such as CoAP that are explicitly analogous to HTTP. - - - This section provides guidance on how to use each common HTTP method with a link, - and how collection resources impose additional constraints on HTTP POST. - Additionally, guidance is provided on hinting at HTTP response header values and - describing possible HTTP request headers that are relevant to the given resource. - - - Section 11 of the JSON Schema core specification - provides guidance on linking instances in a hypermedia system to their schemas. - This may be done with network-accessible schemas, or may simply identify schemas - which were pre-packaged within the client application. JSON Hyper-Schema - intentionally does not constrain this mechanism, although it is RECOMMENDED that - the techniques outlined in the core specification be used to whatever extent - is possible. - -
- - Link Description Objects do not directly indicate what operations, such - as HTTP methods, are supported by the target resource. Instead, operations - should be inferred primarily from link relation types - and URI schemes. - - - This means that for each target resource and link relation type pair, schema - authors SHOULD only define a single LDO. While it is possible to use - "allow" with "targetHints" to repeat a relation type and target pair with - different HTTP methods marked as allowed, this is NOT RECOMMENDED and may - not be well-supported by conforming implementations. - - - All information necessary to use each HTTP method can be conveyed in a - single LDO as explained in this section. The "allow" field in "targetHints" - is intended simply to hint at which operations are supported, not to - separately define each operation. - - - Note, however, that a resource may always decline an operation at runtime, - for instance due to authorization failure, or due to other application state - that controls the operation's availability. - -
-
- - "targetSchema" describes the resource on the target end of the link, while - "targetMediaType" defines that resource's media type. With HTTP links, - "headerSchema" can also be used to describe valid values for use in an - "Accept" request header, which can support multiple media types or - media ranges. When both ways of indicating the target media type are - present, "targetMediaType" SHOULD indicate the default representation - media type, while the schema for "accept" in "headerSchema" SHOULD include - the default as well as any alternate media types or media ranges that can - be requested. - - - Since the semantics of many HTTP methods are defined in terms of the target - resource, "targetSchema" is used for requests and/or responses for several - HTTP methods. In particular, "targetSchema" suggests what a client - application can expect for the response to an HTTP GET or any response - for which the "Content-Location" header is equal to the request URI, - and what a client application should send if it creates or replaces - the resource with an HTTP PUT request. - These correlations are defined by RFC 7231, - section 4.3.1 - "GET", section 4.3.4 "PUT", and section 3.1.4.2, - "Content-Location". - - - Per RFC 5789, the request structure for an HTTP - PATCH is determined by the combination of "targetSchema" and the request - media type, which is conveyed by the "Accept-Patch" header, which may be - included in "targetHints". Media types that are suitable for PATCH-ing - define a syntax for expressing changes to a document, which can be applied - to the representation described by "targetSchema" to determine the set of - syntactically valid request payloads. Often, the simplest way to validate - a PATCH request is to apply it and validate the result as a normal - representation. - -
-
- - JSON Hyper-Schema allows for resources that process arbitrary data - in addition to or instead of working with the target's representation. - This arbitrary data is described by the "submissionSchema" and - "submissionMediaType" keywords. In the case of HTTP, the POST method - is the only one that handles such data. While there are certain - conventions around using POST with collections, the semantics of a POST - request are defined by the target resource, not HTTP. - - - In addition to the protocol-neutral "submission*" keywords (see - for a non-HTTP example), the "Accept-Post" header - can be used to specify the necessary media type, and MAY be - advertised via the "targetHints" field. - - What happens if both are used? Also, "submissionSchema" is a MUST - to support, while "targetHints" are at most a SHOULD. But forbidding - the use of "Accept-Post" in "targetHints" seems incorrect. - - - - Successful responses to POST other than a 201 or a 200 with "Content-Location" - set likewise have no HTTP-defined semantics. As with all HTTP responses, - any representation in the response should link to its own hyper-schema to - indicate how it may be processed. As noted in , - connecting hyperlinks with all possible operation responses is not within - the scope of JSON Hyper-Schema. - -
-
- - It would be good to also include a section with CoAP examples. - - - JSON serializations of HTTP response header information SHOULD follow the - guidelines established by the work in progress - "A JSON Encoding for HTTP Header Field Values". - Approaches shown in that document's examples SHOULD be applied to other - similarly structured headers wherever possible. - - - Headers for all possible HTTP method responses all share "headerSchema". - In particular, both headers that appear in a HEAD response and those - that appear in an OPTIONS response can appear. No distinction is made - within "headerSchema" as to which method response contains which header. - - - It is RECOMMENDED that schema authors provide hints for the values of - the following types of HTTP headers whenever applicable: - - Method allowance - Method-specific request media types - Authentication challenges - - - - In general, headers that are likely to have different values at different - times SHOULD NOT be included in "targetHints". - -
- - As an example, an Allow header allowing HEAD, GET, and POST - would be shown as follows: - - - - - - Note that this is represented identically whether there is - a single-line Allow header with comma-separated values, - multiple Allow headers on separate lines, each with one value, - or any combination of such arrangements. As is generally true - with HTTP headers, comma-separated values and multiple occurrences - of the header are treated the same way. - -
-
-
- - Schemas SHOULD be written to describe JSON serializations that - follow guidelines established by the work in progress - "A JSON Encoding for HTTP Header Field Values" - Approaches shown in that document's examples SHOULD be applied to - other similarly structured headers wherever possible. - - - It is RECOMMENDED that schema authors describe the available usage of - the following types of HTTP headers whenever applicable: - - Content negotiation - Authentication and authorization - Range requests - The "Prefer" header - - - - Headers such as cache control and conditional request headers are generally - implemented by intermediaries rather than the resource, and are therefore - not generally useful to describe. While the resource must supply the - information needed to use conditional requests, the runtime handling of - such headers and related responses is not resource-specific. - -
-
- - When using HTTP, or a protocol such as CoAP that is explicitly analogous - to HTTP, this is done by POST-ing a representation of the individual - resource to be created to the collection resource. The process for - recognizing collection and item resources is described in - . - -
-
- - JSON Hyper-Schema facilitates HTTP content negotiation, and allows for - a hybrid of the proactive and reactive strategies. As mentioned - above, a hyper-schema can include a schema for HTTP headers such as - "Accept", "Accept-Charset", "Accept-Language", etc with the "headerSchema" - keyword. A user agent or client application can use information in - this schema, such as an enumerated list of supported languages, in lieu of - making an initial request to start the reactive negotiation process. - - - In this way, the proactive content negotiation technique of setting these - headers can be informed by server information about what values are - possible, similar to examining a list of alternatives in reactive negotiation. - - - For media types that allow specifying a schema as a media type parameter, - the "Accept" values sent in a request or advertised in "headerSchema" can - include the URI(s) of the schema(s) to which the negotiated representation - is expected to conform. One possible use for schema parameters in - content negotiation is if the resource has conformed to several different - schema versions over time. The client application can indicate what version(s) - it understands in the "Accept" header in this way. - -
-
- -
- - This section shows how the keywords that construct URIs and JSON Pointers - are used. The results are shown in the format used by the test suite. - - Need to post that and link it, but it should be pretty self-explanatory - to those of you reviewing things at this stage. - - - Most other keywords are either straightforward ("title" and "description"), - apply validation to specific sorts of input, requests, or responses, or have - protocol-specific behavior. Examples demonstrating HTTP usage are available - in an Appendix. - - -
- - For this example, we will assume an example API with a documented - entry point URI of https://example.com/api, which is an empty JSON object - with a link to a schema. Here, the entry point has no data of its - own and exists only to provide an initial set of links: - -
- -; rel="describedBy" -{} -]]> - -
- - The linked hyper-schema defines the API's base URI and provides - two links: an "about" link to API documentation, and a "self" - link indicating that this is a schema for the base URI. - -
- - - -
- - These are the simplest possible links, with only a relation type and - an "href" with no template variables. They resolve as follows: - - - The duplication of "api" in both the base and the "../api" - href in the "self" link is due to quirks of the RFC 3986 - URI-reference resolution algorithm. In order for relative - URI-references to work well in general, the base URI needs - to include a trailing slash. The "about" link with its "docs" - href shows the common case of relative references, which is - used in the other examples in this document. - - - However, if an API uses URIs without trailing slashes for its resources, - there is no way to provide a relative reference that just removes a - trailing slash without duplicating the path component above it. - Which makes the case of the entry point resource, which differs - from the base URI only in terms of the trailing slash, somewhat awkward. - - - Resource URIs, of course, may have trailing slashes, but this example - is intended to highlight this frequently confusing special case. - -
- - - -
- - The attachment pointer is the root pointer (the only possibility with - an empty object for the instance). The context URI is the default, - which is the requested document. Since application/json does not allow - for fragments, the context pointer is necessary to fully describe the - context. Its default behavior is to be the same as the attachment pointer. - -
-
- - Let's add "things" to our system, starting with an individual thing: - -
- - - -
- - Our "thing" has a server-assigned id, which is required in order to - construct the "self" link. It also has a "data" field which can be - of any type. The reason for the "$defs" section will be clear - in the next example. - - - Note that "id" is not required by the validation schema, but is required - by the self link. This makes sense: a "thing" only has a URI if it has - been created, and the server has assigned an id. However, you can use - this schema with an instance containing only the data field, which allows - you to validate "thing" instances that you are about to create. - - - Let's add a link to our entry point schema that lets you jump directly - to a particular thing if you can supply it's id as input. To save space, - only the new LDO is shown. Unlike "self" and "about", there is no - IANA-registered relationship about hypothetical things, so an extension - relationship is defined using the - "tag:" URI scheme: - -
- - - -
- - The "href" value here is the same, but everything else is different. - Recall that the instance is an empty object, so "id" cannot be resolved - from instance data. Instead it is required as client input. This LDO - could also have used "templateRequired" but with "required" in "hrefSchema" - it is not strictly necessary. Providing "templateRequired" without marking - "id" as required in "hrefSchema" would lead to errors, as client input - is the only possible source for resolving this link. - -
-
- - This example covers using the "submission" fields for non-representation - input, as well as using them alongside of resolving the URI Template with - input. Unlike HTML forms, which require either constructing a URI or - sending a payload, but do not allow not both at once, JSON Hyper-Schema can - describe both sorts of input for the same operation on the same link. - - - The "submissionSchema" and "submissionMediaType" fields are for - describing payloads that are not representations of the target resource. - When used with "http(s)://" URIs, they generally refer to a POST request - payload, as seen in the appendix on HTTP usage. - - - In this case, we use a "mailto:" URI, which, per - RFC 6068, Section 3", does not provide any - operation for retrieving a resource. It can only be used to construct - a message for sending. Since there is no concept of a retrievable, - replaceable, or deletable target resource, "targetSchema" and - "targetMediaType" are not used. Non-representation payloads are - described by "submissionSchema" and "submissionMediaType". - - - We use "submissionMediaType" to indicate a multipart/alternative - payload format, providing two representations of the same data (HTML and - plain text). Since a multipart/alternative message is an ordered sequence - (the last part is the most preferred alternative), we model the sequence as - an array in "submissionSchema". Since each part is itself a document with - a media type, we model each item in the array as a string, using - "contentMediaType" to indicate the format within the string. - - - Note that media types such as multipart/form-data, which associate a name with - each part and are not ordered, should be modeled as JSON objects rather than - arrays. - -
- - Note that some lines are wrapped to fit this document's width restrictions. - - - - -
- - For the URI parameters, each of the three demonstrates a different way of - resolving the input: - - - This variable's presence in "templateRequired" means that it must be - resolved for the template to be used. Since the "false" schema - assigned to it in "hrefSchema" excludes it from the input data set, - it must be resolved from the instance. - - - The instance field matching this variable is required, and it is also - allowed in the input data. So its instance value is used to - pre-populate the input data set before accepting client input. The - client application can opt to leave the instance value in place. Since - this field is required in "hrefSchema", the client application cannot - delete it (although it could set it to an empty string). - - - The "false" schema set for this in the main schema prevents this field - from having an instance value. If it is present at all, it must come - from client input. As it is not required in "hrefSchema", it may not - be used at all. - - - - - So, given the following instance retrieved from "https://example.com/api/stuff": - -
- - - -
- - We can partially resolve the link as follows, before asking the client - application for input. - -
- - - -
- - Notice the "href*" keywords in place of "targetUri". These are three - possible kinds of "targetUri" values covering different sorts of input. Here - are examples of each: - - - "mailto:someone@example.com?subject=The%20Awesome%20Thing" - - - "mailto:someone@example.com?subject=your%20work" - - - "mailto:someone@example.com?subject=your%20work&cc=other@elsewhere.org" - - - -
-
- - A link is a typed connection from a context resource to a target resource. - Older link serializations support a "rev" keyword that takes a link relation - type as "rel" does, but reverses the semantics. This has long been deprecated, - so JSON Hyper-Schema does not support it. Instead, "anchor"'s ability to - change the context URI can be used to reverse the direction of a link. - It can also be used to describe a link between two resources, neither of - which is the current resource. - - - As an example, there is an IANA-registered "up" relation, but - there is no "down". In an HTTP Link header, you could implement - "down" as "rev": "up". - -
- - First let's look at how this could be done in HTTP, showing a "self" - link and two semantically identical links, one with "rev": "up" - and the other using "anchor" with "rel": "up" (line wrapped due to - formatting limitations). - - -; rel="self" -Link: ; rel="up"; - anchor="https://example.com/api/trees/1/nodes/456" -Link: ; rev="up" -{ - "id": 123, - "treeId": 1, - "childIds": [456] -} -]]> - - - Note that the "rel=up" link has a target URI identical - to the "rel=self" link, and sets "anchor" (which identifies - the link's context) to the child's URI. This sort of reversed - link is easily detectable by tools when a "self" link is also present. - -
- -
- - The following hyper-schema, applied to the instance in the response - above, would produce the same "self" link and "up" link with "anchor". - It also shows the use of a templated "base" URI, plus both absolute - and relative JSON Pointers in "templatePointers". - - - - - - The "base" template is evaluated identically for both the - target ("href") and context ("anchor") URIs. - -
- - Note the two different sorts of templatePointers used. - "thisNodeId" is mapped to an absolute JSON Pointer, "/id", - while "childId" is mapped to a relative pointer, "0", which - indicates the value of the current item. Absolute - JSON Pointers do not support any kind of wildcarding, so - there is no way to specify a concept like "current item" - without a relative JSON Pointer. - -
-
- - In many systems, individual resources are grouped into collections. Those - collections also often provide a way to create individual item resources with - server-assigned identifiers. - -
- - For this example, we will re-use the individual thing schema as - shown in an earlier section. It is repeated here for convenience, - with an added "collection" link with a "targetSchema" reference - pointing to the collection schema we will introduce next. - - - - - - The "collection" link is the same for all items, so there are no - URI Template variables. The "submissionSchema" is that of the - item itself. As described in , - if a "collection" link supports a submission mechanism (POST in HTTP) - then it MUST implement item creation semantics. Therefore - "submissionSchema" is the schema for creating a "thing" via this link. - -
-
- - Now we want to describe collections of "thing"s. - This schema describes a collection where each item representation is - identical to the individual "thing" representation. While many - collection representations only include subset of the item - representations, this example uses the entirety to minimize the - number of schemas involved. The actual collection items appear as - an array within an object, as we will add more fields to the object - in the next example. - - - - -
-
- - Here is a simple two-element collection instance: - - - - -
-
- - Here are all of the links that apply to this instance, - including those that are defined in the referenced individual - "thing" schema: - - - - - - - In all cases, the context URI is shown for - an instance of media type application/json, which does not - support fragments. If the instance media type was - application/instance+json, which supports JSON Pointer fragments, - then the context URIs would contain fragments identical to - the context pointer field. For application/json and other media types - without fragments, it is critically important to consider the context - pointer as well as the context URI. - -
- - There are three "self" links, one for the collection, and one for - each item in the "elements" array. The item "self" links are defined - in the individual "thing" schema which is referenced with "$ref". - The three links can be distinguished by their context or attachment - pointers. We will revisit the "submissionSchema" of the collection's - "self" link in . - - - There are two "item" links, one for each item in the "elements" array. - Unlike the "self" links, these are defined only in the collection schema. - Each of them have the same target URI as the corresponding "self" link that - shares the same attachment pointer. However, each has a different context - pointer. The context of the "self" link is the entry in "elements", - while the context of the "item" link is always the entire collection - regardless of the specific item. - - - Finally, there are two "collection" links, one for each item in "elements". - In the individual item schema, these produce links with the item resource - as the context. When referenced from the collection schema, the context - is the location in the "elements" array of the relevant "thing", rather than - that "thing"'s own separate resource URI. - - - The collection links have identical target URIs as there is only one relevant - collection URI. While calculating both links as part of a full set of - constructed links may not seem useful, when constructing links on an as-needed - basis, this arrangement means that there is a "collection" link definition - close at hand no matter which "elements" entry you are processing. - -
-
- - Here we add pagination to our collection. There is a "meta" section - to hold the information about current, next, and previous pages. - Most of the schema is the same as in the previous section and has been - omitted. Only new fields and new or (in the case of the main "self" - link) changed links are shown in full. - - - - - - Notice that the "self" link includes the pagination query - that produced the exact representation, rather than being - a generic link to the collection allowing selecting the - page via input. - -
-
- - Given this instance: - - - - -
-
- - Here are all of the links that apply to this instance - that either did not appear in the previous example or - have been changed with pagination added. - - - - - - Note that there is no "prev" link in the output, as we are looking - at the first page. The lack of a "prev" field under "meta", - together with the "prev" link's "templateRequired" values, means - that the link is not usable with this particular instance. - -
- - - It's not clear how pagination should work with the link from - the "collection" links in the individual "thing" schema. - Technically, a link from an item to a paginated or filtered - collection should go to a page/filter that contains the item - (in this case the "thing") that is the link context. - See GitHub issue #421 for more discussion. - - - - Let's add a link for this collection to the entry point schema - (), including - pagination input in order to allow client applications to jump directly - to a specific page. Recall that the entry point schema consists only - of links, therefore we only show the newly added link: - -
- - - - - Now we see the pagination parameters being accepted as input, so - we can jump to any page within the collection. The link relation - type is a custom one as the generic "collection" link can only - be used with an item as its context, not an entry point or other - resource. - -
-
-
- - When we do not have any "thing"s, we do not have any resources with - a relevant "collection" link. Therefore we cannot use a "collection" - link's submission keywords to create the first "thing"; hyper-schemas - must be evaluated with respect to an instance. Since the "elements" - array in the collection instance would be empty, it cannot provide - us with a collection link either. - - - However, our entry point link can take us to the empty collection, and - we can use the presence of "item" links in the hyper-schema to recognize - that it is a collection. Since the context of the "item" link is the - collection, we simply look for a "self" link with the same context, which - we can then treat as collection for the purposes of a creation operation. - - - Presumably, our custom link relation type in the entry point schema was - sufficient to ensure that we have found the right collection. A client - application that recognizes that custom link relation type may know that - it can immediately assume that the target is a collection, but a generic - user agent cannot do so. Despite the presence of a "-collection" suffix - in our example, a generic user agent would have no way of knowing whether - that substring indicates a hypermedia resource collection, or some other - sort of collection. - - - Once we have recognized the "self" link as being for the correct collection, - we can use its "submissionSchema" and/or "submissionMediaType" keywords to - perform an item creation operation. - - This works perfectly if the collection is unfiltered and unpaginated. - However, one should generally POST to a collection that will contain - the created resource, and a "self" link MUST include any filters, - pagination, or other query parameters. Is it still valid to POST to - such a "self" link even if the resulting item would not match the - filter or appear within that page? See GitHub issue #421 for further - discussion. - - - Draft-04 of Hyper-Schema defined a "create" link relation that - had the schema, rather than the instance, as its context. This - did not fit into the instance-based link model, and incorrectly - used an operation name for a link relation type. However, defining - a more correctly designed link from the schema to the collection - instance may be one possible approach to solving this. - Again, see GitHub issue #421 for more details. - - -
-
-
- -
- - JSON Hyper-Schema defines a vocabulary for JSON Schema core and concerns all - the security considerations listed there. As a link serialization format, - the security considerations of RFC 8288 Web Linking - also apply, with appropriate adjustments (e.g. "anchor" as an LDO keyword rather - than an HTTP Link header attribute). - -
- - As stated in , all LDO keywords describing - the target resource are advisory and MUST NOT be used in place of - the authoritative information supplied by the target resource in response - to an operation. Target resource responses SHOULD indicate their own - hyper-schema, which is authoritative. - - - If the hyper-schema in the target response matches (by "$id") the hyper-schema - in which the current LDO was found, then the target attributes MAY be - considered authoritative. - - Need to add something about the risks of spoofing by "$id", but given - that other parts of the specification discourage always re-downloading - the linked schema, the risk mitigation options are unclear. - - - - User agents or client applications MUST NOT use the value of "targetSchema" - to aid in the interpretation of the data received in response to following - the link, as this leaves - "safe" data open to re-interpretation. - - - When choosing how to interpret data, the type information provided by the - server (or inferred from the filename, or any other usual method) MUST be - the only consideration, and the "targetMediaType" property of the link - MUST NOT be used. - User agents MAY use this information to determine how they represent the - link or where to display it (for example hover-text, opening in a new tab). - If user agents decide to pass the link to an external program, they SHOULD - first verify that the data is of a type that would normally be passed to - that external program. - - - This is to guard against re-interpretation of "safe" data, similar to the - precautions for "targetSchema". - - - Protocol meta-data values conveyed in "targetHints" MUST NOT be considered - authoritative. Any security considerations defined by the protocol that - may apply based on incorrect assumptions about meta-data values apply. - - - Even when no protocol security considerations are directly applicable, - implementations MUST be prepared to handle responses that do not - match the link's "targetHints" values. - -
-
- - When link relation of "self" is used to denote a full representation of an - object, the user agent SHOULD NOT consider the representation to be the - authoritative representation of the resource denoted by the target URI if - the target URI is not equivalent to or a sub-path of the URI used to request - the resource representation which contains the target URI with the "self" - link. - - It is no longer entirely clear what was intended by the "sub-path" - option in this paragraph. It may have been intended to allow - "self" links for embedded item representations in a collection, which - usually have target URIs that are sub-paths of that collection's URI, - to be considered authoritative. However, this is simply a common - design convention and does not appear to be based in RFC 3986 or any other - guidance on URI usage. See GitHub issue #485 for further discussion. - - -
-
- -
- - Thanks to - Gary Court, - Francis Galiegue, - Kris Zyp, - and Geraint Luff - for their work on the initial drafts of JSON Schema. - - - Thanks to - Jason Desrosiers, - Daniel Perrett, - Erik Wilde, - Ben Hutton, - Evgeny Poberezkin, - Brad Bowman, - Gowry Sankar, - Donald Pipowitch, - Dave Finlay, - and Denis Laxalde - for their submissions and patches to the document. - -
-
- - - - - &rfc2119; - &rfc3986; - &rfc4287; - &rfc6570; - &rfc6573; - &rfc6901; - &rfc8288; - - - Relative JSON Pointers - - - - - - - - - - - - - JSON Schema: A Media Type for Describing JSON Documents - - - - - - - - - - - - - JSON Schema Validation: A Vocabulary for Structural Validation of JSON - - - - - - - - - - - - - - - - &rfc2046; - &rfc4151; - &rfc5789; - &rfc6068; - &rfc7230; - &rfc7231; - &rfc7807; - &I-D.reschke-http-jfv; - -
- - Hypermedia APIs, which follow the constraints of the REST architectural - style, enable the creation of generic user agents. Such a user agent - has no application-specific knowledge. Rather, it understands pre-defined - media types, URI schemes, protocols, and link relations, often by recognizing - these and coordinating the use of existing software that implements support - for them. Client applications can then be built on top of such a user agent, - focusing on their own semantics and logic rather than the mechanics of the - interactions. - - - Hyper-schema is only concerned with one resource and set of associated links - at a time. Just as a web browser works with only one HTML page at a time, - with no concept of whether or how that page functions as part of a "site", - a hyper-schema-aware user agent works with one resource at a time, without - any concept of whether or how that resource fits into an API. - - - Therefore, hyper-schema is suitable for use within an API, but is not suitable - for the description of APIs as complete entities in their own right. There is - no way to describe concepts at the API scope, rather than the resource and - link scope, and such descriptions are outside of the boundaries - of JSON Hyper-Schema. - -
- - Since a given JSON Hyper-Schema is used with a single resource at a single - point in time, it has no inherent notion of versioning. However, a given - resource can change which schema or schemas it uses over time, and the - URIs of these schemas can be used to indicate versioning information. - When used with a media type that supports indicating a schema with a media - type parameter, these versioned schema URIs can be used in content negotiation. - - - A resource can indicate that it is an instance of multiple schemas, which allows - supporting multiple compatible versions simultaneously. A client application - can then make use of the hyper-schema that it recognizes, and ignore newer - or older versions. - -
-
- - Because a hyper-schema represents a single resource at a time, it does not - provide for an enumeration of all possible responses to protocol operations - performed with links. Each response, including errors, is considered - its own (possibly anonymous) resource, and should identify its own - hyper-schema, and optionally use an appropriate media type such as - RFC 7807's "application/problem+json", - to allow the user agent or client application to interpret any - information that is provided beyond the protocol's own status reporting. - -
-
- - It is possible to statically analyze a set of hyper-schemas without instance - data in order to generate output such as documentation or code. However, - the full feature set of both validation and hyper-schema cannot be accessed - without runtime instance data. - - - This is an intentional design choice to provide the maximum runtime - flexibility for hypermedia systems. JSON Schema as a media type allows for - establishing additional vocabularies for static analysis and content - generation, which are not addressed in this specification. Additionally, - individual systems may restrict their usage to subsets that can be - analyzed statically if full design-time description is a goal. - - Vocabularies for API documentation and other purposes have been - proposed, and contributions are welcome at - https://github.com/json-schema-org/json-schema-vocabularies - - -
-
- -
- - This section to be removed before leaving Internet-Draft status. - - - - - - - - - - - This draft is purely a bug fix with no functional changes - Fixed erroneous meta-schema URI (draft-07, not draft-07-wip) - Removed stray "work in progress" language left over from review period - Fixed missing trailing "/" in various "base" examples - Fixed incorrect draft name in changelog (luff-*-00, not -01) - Update relative pointer ref to handrews-*-01, also purely a bug fix - - - - - Top to bottom reorganization and rewrite - Group keywords per RFC 8288 context/relation/target/target attributes - Additional keyword groups for template resolution and describing input - Clarify implementation requirements with a suggested output format - Expanded overview to provide context - Consolidated examples into their own section, illustrate real-world patterns - Consolidated HTTP guidance in its own section - Added a subsection on static analysis of hyper-schemas - Consolidated security concerns in their own section - Added an appendix on usage in APIs - Moved "readOnly" to the validation specification - Moved "media" to validation as "contentMediaType"/"contentEncoding" - Renamed "submissionEncType" to "submissionMediaType" - Renamed "mediaType" to "targetMediaType" - Added "anchor" and "anchorPointer" - Added "templatePointers" and "templateRequired" - Clarified how "hrefSchema" is used - Added "targetHints" and "headerSchema" - Added guidance on "self", "collection" and "item" link usage - Added "description" as an LDO keyword - Added "$comment" in LDOs to match the schema keyword - - - - - Fixed examples - Added "hrefSchema" for user input to "href" URI Templates - Removed URI Template pre-processing - Clarified how links and data submission work - Clarified how validation keywords apply hyper-schema keywords and links - Clarified HTTP use with "targetSchema" - Renamed "schema" to "submissionSchema" - Renamed "encType" to "submissionEncType" - Removed "method" - - - - - "rel" is now optional - rel="self" no longer changes URI base - Added "base" keyword to change instance URI base - Removed "root" link relation - Removed "create" link relation - Removed "full" link relation - Removed "instances" link relation - Removed special behavior for "describedBy" link relation - Removed "pathStart" keyword - Removed "fragmentResolution" keyword - Updated references to JSON Pointer, HTML - Changed behavior of "method" property to align with hypermedia best current practices - - - - - Split from main specification. - - - - -
-
-
diff --git a/jsonschema-validation.xml b/jsonschema-validation.xml deleted file mode 100644 index c589d1cd..00000000 --- a/jsonschema-validation.xml +++ /dev/null @@ -1,1268 +0,0 @@ - - - - - - - - - - - - - - - - - - - -]> - - - - - - - - - - - - JSON Schema Validation: A Vocabulary for Structural Validation of JSON - - - -
- aaa@bzfx.net -
-
- - -
- - - San Francisco - CA - USA - - henry@cloudflare.com -
-
- - - Wellcome Sanger Institute -
- bh7@sanger.ac.uk -
-
- - -
- - - Cambridge - UK - - luffgd@gmail.com -
-
- - - Internet Engineering Task Force - JSON - Schema - validation - - - - JSON Schema (application/schema+json) has several purposes, one of which is JSON - instance validation. - This document specifies a vocabulary for JSON Schema to describe the meaning of JSON - documents, provide hints for user interfaces working with JSON data, and to make - assertions about what a valid document must look like. - - - - - - The issues list for this draft can be found at - . - - - For additional information, see . - - - To provide feedback, use this issue tracker, the communication methods listed on the - homepage, or email the document editors. - - -
- - -
- - JSON Schema can be used to require that a given JSON document (an instance) - satisfies a certain number of criteria. These criteria are asserted by using - keywords described in this specification. In addition, a set of keywords - is also defined to assist in interactive user interface instance generation. - - - This specification will use the concepts, syntax, and terminology defined - by the JSON Schema core specification. - -
- -
- - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", - "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be - interpreted as described in RFC 2119. - - - This specification uses the term "container instance" to refer to both array and - object instances. It uses the term "children instances" to refer to array elements - or object member values. - - - Elements in an array value are said to be unique if no two elements of this array - are equal. - -
- -
- - JSON Schema validation asserts constraints on the structure of instance data. - An instance location that satisfies all asserted constraints is then - annotated with any keywords that contain non-assertion information, - such as descriptive metadata and usage hints. If all locations within - the instance satisfy all asserted constraints, then the instance is - said to be valid against the schema. - - - Each schema object is independently evaluated against each instance location - to which it applies. This greatly simplifies the implementation requirements - for validators by ensuring that they do not need to maintain state across - the document-wide validation process. - - - This specification defines a set of assertion keywords, as well as a small vocabulary - of metadata keywords that can be used to annotate the JSON instance with - useful information. The and - keywords are also useful as annotations as well as being optional assertions, - as they convey additional usage guidance for the instance data. - -
- -
- -
- - It should be noted that the nul character (\u0000) is valid in a JSON string. An - instance to validate may contain a string value with this character, regardless - of the ability of the underlying programming language to deal with such data. - -
- -
- - The JSON specification allows numbers with arbitrary precision, and JSON Schema - does not add any such bounds. - This means that numeric instances processed by JSON Schema can be arbitrarily large and/or - have an arbitrarily long decimal part, regardless of the ability of the - underlying programming language to deal with such data. - -
- -
- - Keywords that use regular expressions, or constrain the instance value - to be a regular expression, are subject to the interoperability - considerations for regular expressions in the - JSON Schema Core specification. - -
- -
- -
- - The current URI for the JSON Schema Validation meta-schema is - . - This meta-schema describes the core keywords, the subschema application - vocabulary from the core specification, and all keywords - defined by this specification. All implementations of this specification - SHOULD support the subschema application vocabulary, and MUST NOT - implement behavior that contradicts that vocabulary. - -
- -
- - Validation keywords in a schema impose requirements for successful validation of an - instance. These keywords are all assertions without any annotation behavior. - - -
-
- - The value of this keyword MUST be either a string or an array. If it is - an array, elements of the array MUST be strings and MUST be unique. - - - String values MUST be one of the six primitive types - ("null", "boolean", "object", "array", "number", or "string"), - or "integer" which matches any number with a zero fractional part. - - - An instance validates if and only if the instance is in any of the sets listed - for this keyword. - -
- -
- - The value of this keyword MUST be an array. This array SHOULD have at - least one element. Elements in the array SHOULD be unique. - - - An instance validates successfully against this keyword if its value is - equal to one of the elements in this keyword's array value. - - - Elements in the array might be of any type, including null. - -
- -
- - The value of this keyword MAY be of any type, including null. - - - An instance validates successfully against this keyword if its value is - equal to the value of the keyword. - -
-
- -
-
- - The value of "multipleOf" MUST be a number, strictly greater than 0. - - - A numeric instance is valid only if division by this keyword's value results in - an integer. - -
- -
- - The value of "maximum" MUST be a number, representing an inclusive upper limit - for a numeric instance. - - - If the instance is a number, then this keyword validates only if the instance is - less than or exactly equal to "maximum". - -
- -
- - The value of "exclusiveMaximum" MUST be number, representing an exclusive upper - limit for a numeric instance. - - - If the instance is a number, then the instance is valid only if it has a value - strictly less than (not equal to) "exclusiveMaximum". - -
- -
- - The value of "minimum" MUST be a number, representing an inclusive lower limit - for a numeric instance. - - - If the instance is a number, then this keyword validates only if the instance is - greater than or exactly equal to "minimum". - -
- -
- - The value of "exclusiveMinimum" MUST be number, representing an exclusive lower - limit for a numeric instance. - - - If the instance is a number, then the instance is valid only if it has a value - strictly greater than (not equal to) "exclusiveMinimum". - -
-
- -
-
- - The value of this keyword MUST be a non-negative integer. - - A string instance is valid against this keyword if its - length is less than, or equal to, the value of this keyword. - - - The length of a string instance is defined as the number of its - characters as defined by RFC 8259. - -
- -
- - The value of this keyword MUST be a non-negative integer. - - - A string instance is valid against this keyword if its - length is greater than, or equal to, the value of this keyword. - - - - The length of a string instance is defined as the number of its - characters as defined by RFC 8259. - - - Omitting this keyword has the same behavior as a value of 0. - -
- -
- - The value of this keyword MUST be a string. This string SHOULD be a - valid regular expression, according to the ECMA 262 regular expression - dialect. - - - A string instance is considered valid if the regular - expression matches the instance successfully. Recall: regular - expressions are not implicitly anchored. - -
-
- -
- -
- - The value of this keyword MUST be a non-negative integer. - - - An array instance is valid against "maxItems" if its size is - less than, or equal to, the value of this keyword. - -
- -
- - The value of this keyword MUST be a non-negative integer. - - - An array instance is valid against "minItems" if its size is - greater than, or equal to, the value of this keyword. - - - Omitting this keyword has the same behavior as a value of 0. - -
- -
- - The value of this keyword MUST be a boolean. - - - If this keyword has boolean value false, the instance validates - successfully. If it has boolean value true, the instance validates - successfully if all of its elements are unique. - - - Omitting this keyword has the same behavior as a value of false. - -
- -
- - The value of this keyword MUST be a non-negative integer. - - - An array instance is valid against "maxContains" if the number of - elements that are valid against the schema for - "contains" is - less than, or equal to, the value of this keyword. - - - If "contains" is not present within the same schema object, - then this keyword has no effect. - -
- -
- - The value of this keyword MUST be a non-negative integer. - - - An array instance is valid against "minContains" if the number of - elements that are valid against the schema for - "contains" is - greater than, or equal to, the value of this keyword. - - - A value of 0 is allowed, but is only useful for setting a range - of occurrences from 0 to the value of "maxContains". A value of - 0 with no "maxContains" causes "contains" to always pass validation. - - - If "contains" is not present within the same schema object, - then this keyword has no effect. - - - Omitting this keyword has the same behavior as a value of 1. - -
-
- -
-
- - The value of this keyword MUST be a non-negative integer. - - - An object instance is valid against "maxProperties" if its - number of properties is less than, or equal to, the value of this - keyword. - -
- -
- - The value of this keyword MUST be a non-negative integer. - - - An object instance is valid against "minProperties" if its - number of properties is greater than, or equal to, the value of this - keyword. - - - Omitting this keyword has the same behavior as a value of 0. - -
- -
- - The value of this keyword MUST be an array. - Elements of this array, if any, MUST be strings, and MUST be unique. - - - An object instance is valid against this keyword if every item in the array is - the name of a property in the instance. - - - Omitting this keyword has the same behavior as an empty array. - -
- -
- - The value of this keyword MUST be an object. Properties in - this object, if any, MUST be arrays. Elements in each array, - if any, MUST be strings, and MUST be unique. - - - This keyword specifies properties that are required if a specific - other property is present. Their requirement is dependent on the - presence of the other property. - - - Validation succeeds if, for each name that appears in both - the instance and as a name within this keyword's value, every - item in the corresponding array is also the name of a property - in the instance. - - - Omitting this keyword has the same behavior as an empty object. - -
-
-
- -
- -
- - Structural validation alone may be insufficient to validate that an instance - meets all the requirements of an application. The "format" keyword is defined to - allow interoperable semantic validation for a fixed subset of values which are - accurately described by authoritative resources, be they RFCs or other external - specifications. - - - - The value of this keyword is called a format attribute. It MUST be a string. A - format attribute can generally only validate a given set of instance types. If - the type of the instance to validate is not in this set, validation for this - format attribute and instance SHOULD succeed. - - -
- -
- - The "format" keyword functions as both an annotation - and as an assertion. While no special effort is required to - implement it as an annotation conveying semantic meaning, implementing - validation is non-trivial. - - - Implementations MAY support the "format" keyword as a validation assertion. - Should they choose to do so: - - - they SHOULD implement validation for attributes defined below; - they SHOULD offer an option to disable validation for this keyword. - - - - - - Implementations MAY add custom format attributes. Save for agreement between - parties, schema authors SHALL NOT expect a peer implementation to support this - keyword and/or custom format attributes. - -
- -
- -
- - These attributes apply to string instances. - - - Date and time format names are derived from - RFC 3339, section 5.6. - - - Implementations supporting formats SHOULD implement support for - the following attributes: - - - A string instance is valid against this attribute if it is - a valid representation according to the "date-time" production. - - - A string instance is valid against this attribute if it is - a valid representation according to the "full-date" production. - - - A string instance is valid against this attribute if it is - a valid representation according to the "full-time" production. - - - - - Implementations MAY support additional attributes using the other - production names defined in that section. If "full-date" or "full-time" - are implemented, the corresponding short form ("date" or "time" - respectively) MUST be implemented, and MUST behave identically. - Implementations SHOULD NOT define extension attributes - with any name matching an RFC 3339 production unless it validates - according to the rules of that production. - - There is not currently consensus on the need for supporting - all RFC 3339 formats, so this approach of reserving the - namespace will encourage experimentation without committing - to the entire set. Either the format implementation requirements - will become more flexible in general, or these will likely - either be promoted to fully specified attributes or dropped. - - -
- -
- - These attributes apply to string instances. - - - A string instance is valid against these attributes if it is a valid - Internet email address as follows: - - - As defined by RFC 5322, section 3.4.1. - - - As defined by RFC 6531 - - - Note that all strings valid against the "email" attribute are also - valid against the "idn-email" attribute. - -
-
- - These attributes apply to string instances. - - - A string instance is valid against these attributes if it is a valid - representation for an Internet hostname as follows: - - - As defined by RFC 1034, section 3.1, - including host names produced using the Punycode algorithm - specified in RFC 5891, section 4.4. - - - As defined by either RFC 1034 as for hostname, or an - internationalized hostname as defined by - RFC 5890, section 2.3.2.3. - - - Note that all strings valid against the "hostname" attribute are also - valid against the "idn-hostname" attribute. - -
- -
- - These attributes apply to string instances. - - - A string instance is valid against these attributes if it is a valid - representation of an IP address as follows: - - - An IPv4 address according to the "dotted-quad" ABNF - syntax as defined in - RFC 2673, section 3.2. - - - An IPv6 address as defined in - RFC 4291, section 2.2. - - - -
- -
- - These attributes apply to string instances. - - - - - A string instance is valid against this attribute if it is - a valid URI, according to . - - - A string instance is valid against this attribute if it is a valid URI - Reference (either a URI or a relative-reference), - according to . - - - A string instance is valid against this attribute if it is - a valid IRI, according to . - - - A string instance is valid against this attribute if it is a valid IRI - Reference (either an IRI or a relative-reference), - according to . - - - Note that all valid URIs are valid IRIs, and all valid URI References are - also valid IRI References. - -
- -
- - This attribute applies to string instances. - - - A string instance is valid against this attribute if it is a valid URI Template - (of any level), according to . - - - Note that URI Templates may be used for IRIs; there is no separate - IRI Template specification. - -
- -
- - These attributes apply to string instances. - - - - - A string instance is valid against this attribute if it - is a valid JSON string representation of a JSON Pointer, - according to RFC 6901, section 5. - - - A string instance is valid against this attribute if it is a valid - Relative JSON Pointer. - - - To allow for both absolute and relative JSON Pointers, use "anyOf" or - "oneOf" to indicate support for either format. - -
-
- - This attribute applies to string instances. - - - A regular expression, which SHOULD be valid according to the - ECMA 262 regular expression dialect. - - - Implementations that validate formats MUST accept at least the subset of - ECMA 262 defined in the Regular Expressions - section of this specification, and SHOULD accept all valid ECMA 262 expressions. - -
-
-
- -
- -
- - Properties defined in this section indicate that an instance contains - non-JSON data encoded in a JSON string. - They describe the type of content and how it is encoded. - - - These properties provide additional information required to interpret JSON data - as rich multimedia documents. - -
- -
- - The content keywords function as both annotations and as assertions. - While no special effort is required to implement them as annotations conveying - how applications can interpret the data in the string, implementing - validation of conformance to the media type and encoding is non-trivial. - - - Implementations MAY support the "contentMediaType" and "contentEncoding" - keywords as validation assertions. - Should they choose to do so, they SHOULD offer an option to disable validation - for these keywords. - -
- -
- - - If the instance value is a string, this property defines that the string - SHOULD be interpreted as binary data and decoded using the encoding - named by this property. - - - - Possible values for this property are listed in - RFC 2045, Sec 6.1 and - RFC 4648. For "base64", which is defined - in both RFCs, the definition in RFC 4648, which removes line length - limitations, SHOULD be used, as various other specifications have - mandated different lengths. Note that line lengths within a string - can be constrained using the "pattern" keyword. - - - - If this keyword is absent, but "contentMediaType" is present, this - indicates that the media type could be encoded into UTF-8 like any - other JSON string value, and does not require additional decoding. - - - - The value of this property MUST be a string. - - - - The value of this property SHOULD be ignored if the instance described is not a - string. - - -
- -
- - If the instance is a string, this property defines the media type - of the contents of the string. If "contentEncoding" is present, - this property describes the decoded string. - - - The value of this property MUST be a string, which MUST be a media type, - as defined by RFC 2046. - - - - The value of this property SHOULD be ignored if the instance described is not a - string. - -
- -
- - If the instance is a string, and if "contentMediaType" is present, this - property contains a schema which describes the structure of the string. - - - This keyword MAY be used with any media type that can be mapped into - JSON Schema's data model. - - - The value of this property SHOULD be ignored if the instance described is not a - string, or if "contentMediaType" is not present. - -
- -
-
- - Here is an example schema, illustrating the use of "contentEncoding" and - "contentMediaType": - - - - - - Instances described by this schema should be strings, and their values - should be interpretable as base64-encoded PNG images. - -
- -
- - Another example: - - - - - - Instances described by this schema should be strings containing HTML, using - whatever character set the JSON string was decoded into (default is - Unicode). - -
- -
- - This example describes a JWT that is MACed using the HMAC SHA-256 - algorithm, and requires the "iss" and "exp" fields in its claim set. - - - - - - Note that "contentEncoding" does not appear. While the "application/jwt" - media type makes use of base64url encoding, that is defined by the media - type, which determines how the JWT string is decoded into a list of two - JSON data structures: first the header, and then the payload. Since the - JWT media type ensures that the JWT can be represented in a JSON string, - there is no need for further encoding or decoding. - -
-
- -
- -
- - These general-purpose annotation keywords provide commonly used information - for documentation and user interface display purposes. They are not intended - to form a comprehensive set of features. Rather, additional vocabularies - can be defined for more complex annotation-based applications. - -
- - The value of both of these keywords MUST be a string. - - - Both of these keywords can be used to decorate a user interface with - information about the data produced by this user interface. A title will - preferably be short, whereas a description will provide explanation about - the purpose of the instance described by this schema. - -
- -
- - There are no restrictions placed on the value of this keyword. When - multiple occurrences of this keyword are applicable to a single - sub-instance, implementations SHOULD remove duplicates. - - - This keyword can be used to supply a default JSON value associated with a - particular schema. It is RECOMMENDED that a default value be valid against - the associated schema. - -
- -
- - The value of these keywords MUST be a boolean. When multiple occurrences - of these keywords are applicable to a single sub-instance, the resulting - value MUST be true if any occurrence specifies a true value, and MUST - be false otherwise. - - - If "readOnly" has a value of boolean true, it indicates that the value - of the instance is managed exclusively by the owning authority, and - attempts by an application to modify the value of this property are - expected to be ignored or rejected by that owning authority. - - - An instance document that is marked as "readOnly for the entire document - MAY be ignored if sent to the owning authority, or MAY result in an - error, at the authority's discretion. - - - If "writeOnly" has a value of boolean true, it indicates that the value - is never present when the instance is retrieved from the owning authority. - It can be present when sent to the owning authority to update or create - the document (or the resource it represents), but it will not be included - in any updated or newly created version of the instance. - - - An instance document that is marked as "writeOnly" for the entire document - MAY be returned as a blank document of some sort, or MAY produce an error - upon retrieval, or have the retrieval request ignored, at the authority's - discretion. - - - For example, "readOnly" would be used to mark a database-generated serial - number as read-only, while "writeOnly" would be used to mark a password - input field. - - - These keywords can be used to assist in user interface instance generation. - In particular, an application MAY choose to use a widget that hides - input values as they are typed for write-only fields. - - - Omitting these keywords has the same behavior as values of false. - -
- -
- - The value of this keyword MUST be an array. - There are no restrictions placed on the values within the array. - When multiple occurrences of this keyword are applicable to a single - sub-instance, implementations MUST provide a flat array of all - values rather than an array of arrays. - - - This keyword can be used to provide sample JSON values associated with a - particular schema, for the purpose of illustrating usage. It is - RECOMMENDED that these values be valid against the associated schema. - - - Implementations MAY use the value(s) of "default", if present, as - an additional example. If "examples" is absent, "default" - MAY still be used in this manner. - -
-
- -
- - JSON Schema validation defines a vocabulary for JSON Schema core and concerns all - the security considerations listed there. - - - JSON Schema validation allows the use of Regular Expressions, which have numerous - different (often incompatible) implementations. - Some implementations allow the embedding of arbitrary code, which is outside the - scope of JSON Schema and MUST NOT be permitted. - Regular expressions can often also be crafted to be extremely expensive to compute - (with so-called "catastrophic backtracking"), resulting in a denial-of-service - attack. - - - Implementations that support validating or otherwise evaluating instance - string data based on "contentEncoding" and/or "contentMediaType" are at - risk of evaluating data in an unsafe way based on misleading information. - Applications can mitigate this risk by only performing such processing - when a relationship between the schema and instance is established - (e.g., they share the same authority). - - - Processing a media type or encoding is subject to the security considerations - of that media type or encoding. For example, the security considerations - of RFC 4329 Scripting Media Types apply when - processing JavaScript or ECMAScript encoded within a JSON string. - -
- - -
- - - - - &RFC2119; - &RFC1034; - &RFC2045; - &RFC2046; - &RFC2673; - &RFC3339; - &RFC3986; - &RFC3987; - &RFC4291; - &RFC4648; - &RFC5322; - &RFC5890; - &RFC5891; - &RFC6570; - &RFC6531; - &RFC6901; - &RFC8259; - - - ECMA 262 specification - - - - - - - Relative JSON Pointers - - - - - Cloudflare, Inc. - - - - - - - - JSON Schema: A Media Type for Describing JSON Documents - - - - - - - - - - - - - - &RFC4329; - - -
- - Several keywords have been moved from this document into the - Core Specification as of this draft, in some - cases with re-naming or other changes. This affects the following former - validation keywords: - - - Renamed to "$defs" to match "$ref" and be shorter to type. - Schema vocabulary authors SHOULD NOT define a "definitions" keyword - with different behavior in order to avoid invalidating schemas that - still use the older name. - - - All of these keywords apply subschemas to the instance and combine - their results, without asserting any conditions of their own. - Without assertion keywords, these applicators can only cause assertion - failures by using the false boolean schema, or by inverting the result - of the true boolean schema. For this reason, they are better defined - as a generic mechanism on which validation, hyper-schema, and extension - vocabularies can all be based - - - This keyword had two different modes of behavior, which made it - relatively challenging to implement and reason about. - The schema form has been moved to Core and renamed to - "dependentSchemas", as part of the applicator vocabulary. - It is analogous to "properties", except that instead of applying - its subschema to the property value, it applies it to the object - containing the property. - The property name array form is retained here and renamed to - "dependentRequired", as it is an assertion which is a shortcut - for the conditional use of the "required" assertion keyword. - - - -
- -
- - Thanks to - Gary Court, - Francis Galiegue, - Kris Zyp, - and Geraint Luff - for their work on the initial drafts of JSON Schema. - - - Thanks to - Jason Desrosiers, - Daniel Perrett, - Erik Wilde, - Ben Hutton, - Evgeny Poberezkin, - Brad Bowman, - Gowry Sankar, - Donald Pipowitch, - Dave Finlay, - and Denis Laxalde - for their submissions and patches to the document. - -
- -
- - This section to be removed before leaving Internet-Draft status. - - - - - - Moved "definitions" to the core spec as "$defs" - Moved applicator keywords to the core spec - Renamed the array form of "dependencies" to "dependentRequired", moved the schema form to the core spec - - - - - This draft is purely a clarification with no functional changes - Provided the general principle behind ignoring annotations under "not" and similar cases - Clarified "if"/"then"/"else" validation interactions - Clarified "if"/"then"/"else" behavior for annotation - Minor formatting and cross-referencing improvements - - - - - Added "if"/"then"/"else" - Classify keywords as assertions or annotations per the core spec - Warn of possibly removing "dependencies" in the future - Grouped validation keywords into sub-sections for readability - Moved "readOnly" from hyper-schema to validation meta-data - Added "writeOnly" - Added string-encoded media section, with former hyper-schema "media" keywords - Restored "regex" format (removal was unintentional) - Added "date" and "time" formats, and reserved additional RFC 3339 format names - I18N formats: "iri", "iri-reference", "idn-hostname", "idn-email" - Clarify that "json-pointer" format means string encoding, not URI fragment - Fixed typo that inverted the meaning of "minimum" and "exclusiveMinimum" - Move format syntax references into Normative References - JSON is a normative requirement - - - - - Standardized on hyphenated format names with full words ("uriref" becomes "uri-reference") - Add the formats "uri-template" and "json-pointer" - Changed "exclusiveMaximum"/"exclusiveMinimum" from boolean modifiers of "maximum"/"minimum" to independent numeric fields. - Split the additionalItems/items into two sections - Reworked properties/patternProperties/additionalProperties definition - Added "examples" keyword - Added "contains" keyword - Allow empty "required" and "dependencies" arrays - Fixed "type" reference to primitive types - Added "const" keyword - Added "propertyNames" keyword - - - - - Added additional security considerations - Removed reference to "latest version" meta-schema, use numbered version instead - Rephrased many keyword definitions for brevity - Added "uriref" format that also allows relative URI references - - - - - Initial draft. - Salvaged from draft v3. - Redefine the "required" keyword. - Remove "extends", "disallow" - Add "anyOf", "allOf", "oneOf", "not", "definitions", "minProperties", - "maxProperties". - "dependencies" member values can no longer be single strings; at - least one element is required in a property dependency array. - Rename "divisibleBy" to "multipleOf". - "type" arrays can no longer have schemas; remove "any" as a possible - value. - Rework the "format" section; make support optional. - "format": remove attributes "phone", "style", "color"; rename - "ip-address" to "ipv4"; add references for all attributes. - Provide algorithms to calculate schema(s) for array/object - instances. - Add interoperability considerations. - - - - -
-
-
diff --git a/links.json b/links.json deleted file mode 100644 index 435eecba..00000000 --- a/links.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-08/hyper-schema#", - "$id": "http://json-schema.org/draft-08/links", - "title": "Link Description Object", - "allOf": [ - { "required": [ "rel", "href" ] }, - { "$ref": "#/$defs/noRequiredFields" } - ], - "$defs": { - "noRequiredFields": { - "type": "object", - "properties": { - "anchor": { - "type": "string", - "format": "uri-template" - }, - "anchorPointer": { - "type": "string", - "anyOf": [ - { "format": "json-pointer" }, - { "format": "relative-json-pointer" } - ] - }, - "rel": { - "anyOf": [ - { "type": "string" }, - { - "type": "array", - "items": { "type": "string" }, - "minItems": 1 - } - ] - }, - "href": { - "type": "string", - "format": "uri-template" - }, - "hrefSchema": { - "$recursiveRef": "http://json-schema.org/draft-08/hyper-schema", - "default": false - }, - "templatePointers": { - "type": "object", - "additionalProperties": { - "type": "string", - "anyOf": [ - { "format": "json-pointer" }, - { "format": "relative-json-pointer" } - ] - } - }, - "templateRequired": { - "type": "array", - "items": { - "type": "string" - }, - "uniqueItems": true - }, - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "targetSchema": { - "$recursiveRef": "http://json-schema.org/draft-08/hyper-schema", - "default": true - }, - "targetMediaType": { - "type": "string" - }, - "targetHints": { }, - "headerSchema": { - "$recursiveRef": "http://json-schema.org/draft-08/hyper-schema", - "default": true - }, - "submissionMediaType": { - "type": "string", - "default": "application/json" - }, - "submissionSchema": { - "$recursiveRef": "http://json-schema.org/draft-08/hyper-schema", - "default": true - }, - "$comment": { - "type": "string" - } - } - } - } -} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..0047608d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8149 @@ +{ + "name": "@json-schema-org/json-schema-spec", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@json-schema-org/json-schema-spec", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@stylistic/eslint-plugin": "^2.9.0", + "eslint": "^9.13.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-plugin-import": "^2.31.0", + "mdast-builder": "^1.1.1", + "mdast-util-find-and-replace": "^3.0.1", + "mdast-util-to-string": "^4.0.0", + "rehype-document": "^7.0.3", + "rehype-highlight": "^7.0.2", + "rehype-highlight-code-lines": "^1.1.3", + "rehype-stringify": "^10.0.1", + "remark-cli": "^12.0.1", + "remark-flexible-containers": "^1.2.1", + "remark-gfm": "^4.0.0", + "remark-heading-id": "^1.0.1", + "remark-preset-lint-consistent": "^6.0.0", + "remark-preset-lint-markdown-style-guide": "^6.0.0", + "remark-preset-lint-recommended": "^7.0.0", + "remark-rehype": "^11.1.1", + "remark-validate-links": "^13.0.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", + "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", + "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", + "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/config": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-8.3.4.tgz", + "integrity": "sha512-01rtHedemDNhUXdicU7s+QYz/3JyV5Naj84cvdXGH4mgCdL+agmSYaLF4LUG4vMCLzhBO8YtS0gPpH1FGvbgAw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/package-json": "^5.1.1", + "ci-info": "^4.0.0", + "ini": "^4.1.2", + "nopt": "^7.2.1", + "proc-log": "^4.2.0", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", + "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz", + "integrity": "sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz", + "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.13.0.tgz", + "integrity": "sha512-RnO1SaiCFHn666wNz2QfZEFxvmiNRqhzaMXHXxXXKt+MEP7aajlPxUSMIQpKAaJfverpovEYqjBOXDq6dDcaOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@types/concat-stream": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-2.0.3.tgz", + "integrity": "sha512-3qe4oQAPNwVNwK4C9c8u+VJqv9kez+2MR4qJpoPFfXtgxxif1QbFusvXzK0/Wra2VX07smostI2VMmJNSpZjuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/hosted-git-info": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hosted-git-info/-/hosted-git-info-3.0.5.tgz", + "integrity": "sha512-Dmngh7U003cOHPhKGyA7LWqrnvcTyILNgNPmNCxlx7j8MIi54iBliiT8XqVLIQ3GchoOjVAyBzNJVyuaJjqokg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/is-empty": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/is-empty/-/is-empty-1.2.3.tgz", + "integrity": "sha512-4J1l5d79hoIvsrKh5VUKVRA1aIdsOb10Hu5j3J2VfP/msDnfTdGPmNp2E1Wg+vs97Bktzo+MZePFFXSGoykYJw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/supports-color": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.3.tgz", + "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/text-table": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@types/text-table/-/text-table-0.2.5.tgz", + "integrity": "sha512-hcZhlNvMkQG/k1vcZ6yHOl6WAYftQ2MLfTHcYRZ2xYZFD8tGVnE3qFV0lj1smQeDSR7/yY0PyuUalauf33bJeA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.1.tgz", + "integrity": "sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.1.tgz", + "integrity": "sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.1.tgz", + "integrity": "sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.1.tgz", + "integrity": "sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.26.1", + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/typescript-estree": "8.26.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.1.tgz", + "integrity": "sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.1", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ci-info": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", + "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.1.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.22.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/hast-util-to-html/node_modules/property-information": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz", + "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-empty": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", + "integrity": "sha512-F2FnH/otLNJv0J6wc73A5Xo7oHLNnqplYqZhUu01tD54DIPvxIRSTSLkrUB/M0nHO4vo1O9PDfN4KoTxCzLh/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levenshtein-edit-distance": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/levenshtein-edit-distance/-/levenshtein-edit-distance-1.0.0.tgz", + "integrity": "sha512-gpgBvPn7IFIAL32f0o6Nsh2g+5uOvkt4eK9epTfgE4YVxBxwVhJ/p1888lMm/u8mXdu1ETLSi6zeEmkBI+0F3w==", + "dev": true, + "license": "MIT", + "bin": { + "levenshtein-edit-distance": "cli.js" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/load-plugin": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-6.0.3.tgz", + "integrity": "sha512-kc0X2FEUZr145odl68frm+lMJuQ23+rTXYmR6TImqPtbpmXC4vVXbWKDQ9IzndA0HfyQamWfKLhzsqGSTxE63w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@npmcli/config": "^8.0.0", + "import-meta-resolve": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lowlight": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", + "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-builder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mdast-builder/-/mdast-builder-1.1.1.tgz", + "integrity": "sha512-a3KBk/LmYD6wKsWi8WJrGU/rXR4yuF4Men0JO0z6dSZCm5FrXXWTRDjqK0vGSqa+1M6p9edeuypZAZAzSehTUw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/unist": "^2.0.3" + } + }, + "node_modules/mdast-comment-marker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-3.0.0.tgz", + "integrity": "sha512-bt08sLmTNg00/UtVDiqZKocxqvQqqyQZAg1uaRuO/4ysXV5motg7RolF5o5yy/sY1rG0v2XgZEqFWho1+2UquA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-mdx-expression": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-heading-style": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-3.0.0.tgz", + "integrity": "sha512-tsUfM9Kj9msjlemA/38Z3pvraQay880E3zP2NgIthMoGcpU9bcPX9oSM6QC/+eFXGGB4ba+VCB1dKAPHB7Veug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", + "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-json": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/propose": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/propose/-/propose-0.0.5.tgz", + "integrity": "sha512-Jary1vb+ap2DIwOGfyiadcK4x1Iu3pzpkDBy8tljFPmQvnc9ES3m1PMZOMiWOG50cfoAyYNtGeBzrp+Rlh4G9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "levenshtein-edit-distance": "^1.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quotation": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/quotation/-/quotation-2.0.3.tgz", + "integrity": "sha512-yEc24TEgCFLXx7D4JHJJkK4JFVtatO8fziwUxY4nB/Jbea9o9CVS3gt22mA0W7rPYAGW2fWzYDSOtD94PwOyqA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rehype-document": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/rehype-document/-/rehype-document-7.0.3.tgz", + "integrity": "sha512-g5zq6i2FwWVBVdyVi0Jw/5MRvsHj3wuJCn+QeyOjm29QBpTG4r1iUElyH9GhfWx5fB27ZEApA53RdAiYGBb4zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^8.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-highlight": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.2.tgz", + "integrity": "sha512-k158pK7wdC2qL3M5NcZROZ2tR/l7zOzjxXd5VGdcfIyoijjQqpHd3JKtYSBDpDZ38UI2WJWuFAtkMDxmx5kstA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-text": "^4.0.0", + "lowlight": "^3.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-highlight-code-lines": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/rehype-highlight-code-lines/-/rehype-highlight-code-lines-1.1.3.tgz", + "integrity": "sha512-Kq63wvBTkaQn5d5eqVJsqkpAW2fmqwbyGRervWtH32fTY6+cFqzVU5NTBZH/fe9PjjRUTyZfWinEDu7Ewvr+lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.4", + "parse-numeric-range": "^1.3.0", + "unist-util-visit": "^5.0.0" + }, + "peerDependencies": { + "unified": "^11" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-cli": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-12.0.1.tgz", + "integrity": "sha512-2NAEOACoTgo+e+YAaCTODqbrWyhMVmlUyjxNCkTrDRHHQvH6+NbrnqVvQaLH/Q8Ket3v90A43dgAJmXv8y5Tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-meta-resolve": "^4.0.0", + "markdown-extensions": "^2.0.0", + "remark": "^15.0.0", + "unified-args": "^11.0.0" + }, + "bin": { + "remark": "cli.js" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-flexible-containers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/remark-flexible-containers/-/remark-flexible-containers-1.2.1.tgz", + "integrity": "sha512-6qsWW2A3577AyYWDKtiKb79+KISiReB7Tos/aJg8uu9dwGPt14KRZrrJB32zY9/VYIetW15SZiqN3v7W2UP8rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.3", + "unist-builder": "^4.0.0", + "unist-util-find-after": "^5.0.0", + "unist-util-find-between-all": "^1.0.5", + "unist-util-visit": "^5.0.0" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-heading-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/remark-heading-id/-/remark-heading-id-1.0.1.tgz", + "integrity": "sha512-GmJjuCeEkYvwFlvn/Skjc/1Qafj71412gbQnrwUmP/tKskmAf1cMRlZRNoovV+aIvsSRkTb2rCmGv2b9RdoJbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "unist-util-visit": "^1.4.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/remark-heading-id/node_modules/unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true, + "license": "MIT" + }, + "node_modules/remark-heading-id/node_modules/unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "node_modules/remark-heading-id/node_modules/unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "unist-util-is": "^3.0.0" + } + }, + "node_modules/remark-lint": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-10.0.1.tgz", + "integrity": "sha512-1+PYGFziOg4pH7DDf1uMd4AR3YuO2EMnds/SdIWMPGT7CAfDRSnAmpxPsJD0Ds3IKpn97h3d5KPGf1WFOg6hXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "remark-message-control": "^8.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-blockquote-indentation": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-4.0.1.tgz", + "integrity": "sha512-7BhOsImFgTD7IIliu2tt+yJbx5gbMbXCOspc3VdYf/87iLJdWKqJoMy2V6DZG7kBjBlBsIZi38fDDngJttXt4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-checkbox-character-style": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-5.0.1.tgz", + "integrity": "sha512-6qilm7XQXOcTvjFEqqNY57Ki7md9rkSdpMIfIzVXdEnI4Npl2BnUff6ANrGRM7qTgJTrloaf8H0eQ91urcU6Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-code-block-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-4.0.1.tgz", + "integrity": "sha512-d4mHsEpv1yqXWl2dd+28tGRX0Lzk5qw7cfxAQVkOXPUONhsMFwXJEBeeqZokeG4lOKtkKdIJR7ezScDfWR0X4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-definition-case": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-definition-case/-/remark-lint-definition-case-4.0.1.tgz", + "integrity": "sha512-BItJMeXyEBKW/beM7gFLMt3flnyNoRDd8yNFq+7pIeFjO7KWGRxBWUaNgk/tFEPyQcGeCqrNS3nS0ic7qi7I2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-definition-spacing": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-4.0.1.tgz", + "integrity": "sha512-ZjShKaBUGeHrZyIZWwOZOxX3guj/P7gRR5wbDADQctL4oK+ZLQfOvJFmAsF1nD4gNr0Ficjd0AuiWxQcc1qTMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-emphasis-marker": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-emphasis-marker/-/remark-lint-emphasis-marker-4.0.1.tgz", + "integrity": "sha512-BF1WWsAxai3XoKk48sfiqT3L8m02AZLj3BnipWkHDRXuLfz6VwsHVaHWyNvvE0p6b2B3A5dSYbcfJu5RmPx4tQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-fenced-code-flag": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-4.1.1.tgz", + "integrity": "sha512-hKPqowc79jrJL47AfnqDThvE8Q249nHCleR5nxuf9ybriMqcAHYxragKzU5c4W1fNy20bTfFdZz/iAAQAk9kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "quotation": "^2.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-fenced-code-marker": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-4.0.1.tgz", + "integrity": "sha512-uI91OcVPKjNxV+vpjDW9T64hkE0a/CRn3JhwdMxUAJYpVsKnA7PFPSFJOx/abNsVZHNSe7ZFGgGdaH/lqgSizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-file-extension": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-3.0.1.tgz", + "integrity": "sha512-1Ca5Dgu9J/j1fb7nvzNXh2xy4ija03igiP5i4le64LfrlloGax4VWcG/M7uL+CpRTFVqEJMWw0iKDEZxYSgImg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "quotation": "^2.0.0", + "unified-lint-rule": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-final-definition": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-4.0.2.tgz", + "integrity": "sha512-fz3UAcFQef77Zb8rz4za2R6y7pdyJot22iGtFoNIKdtbcNa8IKKEVoY3NIfrsLfhrjwzcha1Sp3fFA9NF6lc4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-mdx": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-final-newline": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-3.0.1.tgz", + "integrity": "sha512-q5diKHD6BMbzqWqgvYPOB8AJgLrMzEMBAprNXjcpKoZ/uCRqly+gxjco+qVUMtMWSd+P+KXZZEqoa7Y6QiOudw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "unified-lint-rule": "^3.0.0", + "vfile-location": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-hard-break-spaces": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-4.1.1.tgz", + "integrity": "sha512-AKDPDt39fvmr3yk38OKZEWJxxCOOUBE+96AsBfs+ExS5LW6oLa9041X5ahFDQHvHGzdoremEIaaElursaPEkNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-heading-increment": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-heading-increment/-/remark-lint-heading-increment-4.0.1.tgz", + "integrity": "sha512-uat7RTQn0hGlMv62p7yjLlg3tO3RljFbH6C+0M+5BNEF+s3NrA8jJgqW0UwLLNdCd3EABCKaWloHumT57ND7PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-mdx": "^3.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-heading-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-4.0.1.tgz", + "integrity": "sha512-+rUpJ/N2CGC5xPgZ18XgsCsUBtadgEhdTi0BJPrsFmHPzL22BUHajeg9im8Y7zphUcbi1qFiKuxZd2nzDgZSXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-heading-style": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-link-title-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-link-title-style/-/remark-lint-link-title-style-4.0.1.tgz", + "integrity": "sha512-MtmnYrhjhRXR0zeiyYf/7GBlUF5KAPypJb345KjyDluOhI4Wj4VAXvVQuov/MFc3y8p/1yVwv3QDYv6yue8/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-list-item-bullet-indent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-5.0.1.tgz", + "integrity": "sha512-LKuTxkw5aYChzZoF3BkfaBheSCHs0T8n8dPHLQEuOLo6iC5wy98iyryz0KZ61GD8stlZgQO2KdWSdnP6vr40Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-list-item-content-indent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-content-indent/-/remark-lint-list-item-content-indent-4.0.1.tgz", + "integrity": "sha512-KSopxxp64O6dLuTQ2sWaTqgjKWr1+AoB1QCTektMJ3mfHfn0QyZzC2CZbBU22KGzBhiYXv9cIxlJlxUtq2NqHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-list-item-indent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-4.0.1.tgz", + "integrity": "sha512-gJd1Q+jOAeTgmGRsdMpnRh01DUrAm0O5PCQxE8ttv1QZOV015p/qJH+B4N6QSmcUuPokHLAh9USuq05C73qpiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-list-item-spacing": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-spacing/-/remark-lint-list-item-spacing-5.0.1.tgz", + "integrity": "sha512-AsxDL9U4qRmFGiz6lfsO833sJaHDlESjxM2rAvssPiXMZau3w/pZItaJyjowQBygDqGrj30sHvOfJzCHKbm1CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-maximum-heading-length": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-heading-length/-/remark-lint-maximum-heading-length-4.1.1.tgz", + "integrity": "sha512-99yonukJ+e0uhx0zGH4uq6H9mhO7FA1ufmuToODH1N+X3ja61Grvlvvlq9UbP9+gbfbWgN97QGKPaTlE29FpaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-maximum-line-length": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-4.1.1.tgz", + "integrity": "sha512-oIncZkI0oIXZk+1kJOMnE3WPbyMTUbds0q1E8WbCwtjN9pAZsQD2e+wK+xdi5VqOLPkvLER+yzbmi/A3Tp+XEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-mdx": "^3.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-blockquote-without-marker": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-6.0.1.tgz", + "integrity": "sha512-b4IOkNcG7C16HYAdKUeAhO7qPt45m+v7SeYbVrqvbSFtlD3EUBL8fgHRgLK1mdujFXDP1VguOEMx+Txv8JOT4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-directive": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-location": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-consecutive-blank-lines": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-5.0.1.tgz", + "integrity": "sha512-yLtYCrEBtGDao4ozmZruRzjMYAcBVFK69PoYjPfNwFO8pQ/LPt8KCq6oyg1ronNyRbDYEGqVdLIHcT/zL3LjPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "mdast-util-mdx": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-definitions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-4.0.1.tgz", + "integrity": "sha512-Ek+A/xDkv5Nn+BXCFmf+uOrFSajCHj6CjhsHjtROgVUeEPj726yYekDBoDRA0Y3+z+U30AsJoHgf/9Jj1IFSug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-duplicate-headings": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-headings/-/remark-lint-no-duplicate-headings-4.0.1.tgz", + "integrity": "sha512-6lggqnpIe5FepikjYF2me3ovKV4oD/rAz8WmwVbLR2cLkce1iH+PB7jyxk/A2gQQqrDcIlRMA5Ct2Yj56cEwhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-emphasis-as-heading": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-emphasis-as-heading/-/remark-lint-no-emphasis-as-heading-4.0.1.tgz", + "integrity": "sha512-zzI/C330qdKO9FB3h6IUtOG36FSrS5nfJ7qxp0atXGYtHyg+Ag7dPC/0FzchOVsxofQm0QTstVoIARt/9TiN5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-articles": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-3.0.1.tgz", + "integrity": "sha512-h31ZDDJV2T6g9WLBrXg1CJ1m8M170O/tlDPAEPGCa/rxwKvMcfum4yicaot0ZKbUZ1uEPjVSUPDeo3sU0zciCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-consecutive-dashes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-3.0.1.tgz", + "integrity": "sha512-qGJRZ81sowEjv1dBodbHZ29pDZbrFpxiQQ6gBvkkHkkoYPekdnr8iUxmV38HcqH8+JNW1O4ELr+m71AA9/34Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-irregular-characters": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-irregular-characters/-/remark-lint-no-file-name-irregular-characters-3.0.1.tgz", + "integrity": "sha512-kNm16eDnPqbN05W0RLIedHi40YzHf1esPHbNKv12AljKWptdCTS72uGjAbqUSZ48dRoKtJzL0HJ0OAqXIWUyxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-mixed-case": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-mixed-case/-/remark-lint-no-file-name-mixed-case-3.0.1.tgz", + "integrity": "sha512-cXVY0gM6DIHHK+mUhQVZ/WLh4cNfzEDpM54LNJBnflR9n9r6eNLR3JlWFRviTL4xRrQ5FXisBSlBa87BquiFVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-file-name-outer-dashes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-3.0.1.tgz", + "integrity": "sha512-QIMrBPZKZ6BwQRPM65HhEHcJv6+wZnZ4z2ikvx2ht40cSmIN7ZTL7wKKJlnpF+4Ioi9XUj+cRHWqEhwJ9LCQIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-content-indent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-5.0.1.tgz", + "integrity": "sha512-YIWktnZo7M9aw7PGnHdshvetSH3Y0qW+Fm143R66zsk5lLzn1XA5NEd/MtDzP8tSxxV+gcv+bDd5St1QUI4oSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-heading-punctuation": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-punctuation/-/remark-lint-no-heading-punctuation-4.0.1.tgz", + "integrity": "sha512-lpSVFEHPDKGWi8YPeO51xmLNVON5A2cGz0Y8VRkW0f2l6LvEkPTMjQAvA84AQu/10TrxTbIzU/tQlRLpG96QUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-literal-urls": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-4.0.1.tgz", + "integrity": "sha512-RhTANFkFFXE6bM+WxWcPo2TTPEfkWG3lJZU50ycW7tJJmxUzDNzRed/z80EVJIdGwFa0NntVooLUJp3xrogalQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-character": "^2.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-multiple-toplevel-headings": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-4.0.1.tgz", + "integrity": "sha512-8sepobIOu3PlDOuMH7jtri+LH4tFNVQU+aqKSkrlNRdp831fYz9S+jA2crTVqWqxVbTwiF96uJWePv8/9qmHnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-mdx": "^3.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shell-dollars": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-4.0.1.tgz", + "integrity": "sha512-UPE1DNCIkLtnS3YFD065Gkq5lQqfndBDpX8Ct/Zjn7M0/hzCyf9B6tpwCU0I20m9jzhS/CSY6mxYnAiEg+KkFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "collapse-white-space": "^2.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-image": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-4.0.1.tgz", + "integrity": "sha512-hQhJ3Dr8ZWRdj7qm6+9vcPpqtGchhENA2UHOmcTraLf6dN1cFATCgY/HbTbRIN6NkG/EEClTgRC1QCokWR2Mmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-shortcut-reference-link": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-4.0.1.tgz", + "integrity": "sha512-YxciuUZc90QaJYhayGO80lS3zxEOBgwwLW1MKYB7AfUdkrLcLVlS+DFloiq0MZ7EDVXuuGUEnIzyjyLSbI5BUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-table-indentation": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-5.0.1.tgz", + "integrity": "sha512-LHw9MGsuilM+3HkbRFZmdSE4T+sziaQzULH5ImYkLH2MLF8GKnAm2mgtveLZcW01wqFV2oEbpF1Y/s/QloXT7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-location": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-undefined-references": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-5.0.1.tgz", + "integrity": "sha512-j3qOk+jry1NPNbUmydGJpfbo1LeuZkvXOwr8ocxh1ymDzHf2GMCiToAiicDNaOuG85RkiIzLvnnCV5I7Mo5q8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-location": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-no-unused-definitions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-4.0.1.tgz", + "integrity": "sha512-AdMbaCeMpj32HvDUuyI+bQyu/405Nby/rgFW8XDpI7U7ufPhHl+jj9J4NgeW7Z8DrODGr0iFgPNt6JtNLskFdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-4.0.1.tgz", + "integrity": "sha512-vZTAbstcBPbGwJacwldGzdGmKwy5/4r29SZ9nQkME4alEl5B1ReSBlYa8t7QnTSW7+tqvA9Sg71RPadgAKWa4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "micromark-util-character": "^2.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-ordered-list-marker-value": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-value/-/remark-lint-ordered-list-marker-value-4.0.1.tgz", + "integrity": "sha512-HQb1MrArvApREC1/I6bkiFlZVDjngsuII29n8E8StnAaHOMN3hVYy6wJ9Uk+O3+X9O8v7fDsZPqFUHSfJhERXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-phrasing": "^4.0.0", + "micromark-util-character": "^2.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-rule-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-4.0.1.tgz", + "integrity": "sha512-gl1Ft13oTS3dJUCsWZzxD/5dAwI1HON67KU7uNfODD5gXJ8Y11deOWbun190ma7XbYdD7P0l8VT2HeRtEQzrWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-strong-marker": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-4.0.1.tgz", + "integrity": "sha512-KaGtj/OWEP4eoafevnlp3NsEVwC7yGEjBJ6uFMzfjNoXyjATdfZ2euB/AfKVt/A/FdZeeMeVoAUFH4DL+hScLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-5.1.1.tgz", + "integrity": "sha512-6fgVA1iINBoAJaZMOnSsxrF9Qj9+hmCqrsrqZqgJJETjT1ODGH64iAN1/6vHR7dIwmy73d6ysB2WrGyKhVlK3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-cell-padding/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/remark-lint-table-pipe-alignment": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipe-alignment/-/remark-lint-table-pipe-alignment-4.1.1.tgz", + "integrity": "sha512-9VxivIJaDonrd/Jgkim1oYQ5MIqhWmyJggr2AqtiizwqxT4epRsWmLOz+/sk7PtTGoT/MtwndhlbM3lxuVXFow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-phrasing": "^4.0.0", + "pluralize": "^8.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipe-alignment/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/remark-lint-table-pipes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-5.0.1.tgz", + "integrity": "sha512-oOkRC0WRRDwvodfffGafoBFBTGwy9udQgKtxN53apmZpOmaUAxTi833ite0jMo078+LehNftO5bxrElZ9EQUlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-lint-table-pipes/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/remark-lint-unordered-list-marker-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-4.0.1.tgz", + "integrity": "sha512-HMrVQC0Qbr8ktSy+1lJGRGU10qecL3T14L6s/THEQXR5Tk0wcsLLG0auNvB4r2+H+ClhVO/Vnm1TEosh1OCsfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-phrasing": "^4.0.0", + "unified-lint-rule": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-message-control": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-8.0.0.tgz", + "integrity": "sha512-brpzOO+jdyE/mLqvqqvbogmhGxKygjpCUCG/PwSCU43+JZQ+RM+sSzkCWBcYvgF3KIAVNIoPsvXjBkzO7EdsYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-comment-marker": "^3.0.0", + "unified-message-control": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-consistent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/remark-preset-lint-consistent/-/remark-preset-lint-consistent-6.0.1.tgz", + "integrity": "sha512-SOLdA36UOU1hiGFm6HAqN9+DORGJPVWxU/EvPVkknTr9V4ULhlzHEJ8OVRMVX3jqoy4lrwb4IqiboVz0YLA7+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "remark-lint": "^10.0.0", + "remark-lint-blockquote-indentation": "^4.0.0", + "remark-lint-checkbox-character-style": "^5.0.0", + "remark-lint-code-block-style": "^4.0.0", + "remark-lint-emphasis-marker": "^4.0.0", + "remark-lint-fenced-code-marker": "^4.0.0", + "remark-lint-heading-style": "^4.0.0", + "remark-lint-link-title-style": "^4.0.0", + "remark-lint-list-item-content-indent": "^4.0.0", + "remark-lint-ordered-list-marker-style": "^4.0.0", + "remark-lint-ordered-list-marker-value": "^4.0.0", + "remark-lint-rule-style": "^4.0.0", + "remark-lint-strong-marker": "^4.0.0", + "remark-lint-table-cell-padding": "^5.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-markdown-style-guide": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/remark-preset-lint-markdown-style-guide/-/remark-preset-lint-markdown-style-guide-6.0.1.tgz", + "integrity": "sha512-hVCRMC8PZlI9hnXkZdrvg4n4j1aD//xHWj26Q7iFAbDB3JKtW1Ne72P7QNVyppmdrR6Gj84zhG3qphOLo8/i8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "remark-lint": "^10.0.0", + "remark-lint-blockquote-indentation": "^4.0.0", + "remark-lint-code-block-style": "^4.0.0", + "remark-lint-definition-case": "^4.0.0", + "remark-lint-definition-spacing": "^4.0.0", + "remark-lint-emphasis-marker": "^4.0.0", + "remark-lint-fenced-code-flag": "^4.0.0", + "remark-lint-fenced-code-marker": "^4.0.0", + "remark-lint-file-extension": "^3.0.0", + "remark-lint-final-definition": "^4.0.0", + "remark-lint-hard-break-spaces": "^4.0.0", + "remark-lint-heading-increment": "^4.0.0", + "remark-lint-heading-style": "^4.0.0", + "remark-lint-link-title-style": "^4.0.0", + "remark-lint-list-item-content-indent": "^4.0.0", + "remark-lint-list-item-indent": "^4.0.0", + "remark-lint-list-item-spacing": "^5.0.0", + "remark-lint-maximum-heading-length": "^4.0.0", + "remark-lint-maximum-line-length": "^4.0.0", + "remark-lint-no-blockquote-without-marker": "^6.0.0", + "remark-lint-no-consecutive-blank-lines": "^5.0.0", + "remark-lint-no-duplicate-headings": "^4.0.0", + "remark-lint-no-emphasis-as-heading": "^4.0.0", + "remark-lint-no-file-name-articles": "^3.0.0", + "remark-lint-no-file-name-consecutive-dashes": "^3.0.0", + "remark-lint-no-file-name-irregular-characters": "^3.0.0", + "remark-lint-no-file-name-mixed-case": "^3.0.0", + "remark-lint-no-file-name-outer-dashes": "^3.0.0", + "remark-lint-no-heading-punctuation": "^4.0.0", + "remark-lint-no-literal-urls": "^4.0.0", + "remark-lint-no-multiple-toplevel-headings": "^4.0.0", + "remark-lint-no-shell-dollars": "^4.0.0", + "remark-lint-no-shortcut-reference-image": "^4.0.0", + "remark-lint-no-shortcut-reference-link": "^4.0.0", + "remark-lint-no-table-indentation": "^5.0.0", + "remark-lint-ordered-list-marker-style": "^4.0.0", + "remark-lint-ordered-list-marker-value": "^4.0.0", + "remark-lint-rule-style": "^4.0.0", + "remark-lint-strong-marker": "^4.0.0", + "remark-lint-table-cell-padding": "^5.0.0", + "remark-lint-table-pipe-alignment": "^4.0.0", + "remark-lint-table-pipes": "^5.0.0", + "remark-lint-unordered-list-marker-style": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-preset-lint-recommended": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-7.0.1.tgz", + "integrity": "sha512-j1CY5u48PtZl872BQ40uWSQMT3R4gXKp0FUgevMu5gW7hFMtvaCiDq+BfhzeR8XKKiW9nIMZGfIMZHostz5X4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "remark-lint": "^10.0.0", + "remark-lint-final-newline": "^3.0.0", + "remark-lint-hard-break-spaces": "^4.0.0", + "remark-lint-list-item-bullet-indent": "^5.0.0", + "remark-lint-list-item-indent": "^4.0.0", + "remark-lint-no-blockquote-without-marker": "^6.0.0", + "remark-lint-no-duplicate-definitions": "^4.0.0", + "remark-lint-no-heading-content-indent": "^5.0.0", + "remark-lint-no-literal-urls": "^4.0.0", + "remark-lint-no-shortcut-reference-image": "^4.0.0", + "remark-lint-no-shortcut-reference-link": "^4.0.0", + "remark-lint-no-undefined-references": "^5.0.0", + "remark-lint-no-unused-definitions": "^4.0.0", + "remark-lint-ordered-list-marker-style": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz", + "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-validate-links": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/remark-validate-links/-/remark-validate-links-13.1.0.tgz", + "integrity": "sha512-z+glZ4zoRyrWimQHtoqJEFJdPoIR1R1SDr/JoWjmS6EsYlyhxNuCHtIt165gmV7ltOSFJ+rGsipqRGfBPInd7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hosted-git-info": "^3.0.0", + "@types/mdast": "^4.0.0", + "github-slugger": "^2.0.0", + "hosted-git-info": "^7.0.0", + "mdast-util-to-hast": "^13.0.0", + "mdast-util-to-string": "^4.0.0", + "propose": "0.0.5", + "trough": "^2.0.0", + "unified-engine": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-args": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-11.0.1.tgz", + "integrity": "sha512-WEQghE91+0s3xPVs0YW6a5zUduNLjmANswX7YbBfksHNDGMjHxaWCql4SR7c9q0yov/XiIEdk6r/LqfPjaYGcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/text-table": "^0.2.0", + "chalk": "^5.0.0", + "chokidar": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "json5": "^2.0.0", + "minimist": "^1.0.0", + "strip-ansi": "^7.0.0", + "text-table": "^0.2.0", + "unified-engine": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-args/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/unified-args/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/unified-engine": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-11.2.2.tgz", + "integrity": "sha512-15g/gWE7qQl9tQ3nAEbMd5h9HV1EACtFs6N9xaRBZICoCwnNGbal1kOs++ICf4aiTdItZxU2s/kYWhW7htlqJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/concat-stream": "^2.0.0", + "@types/debug": "^4.0.0", + "@types/is-empty": "^1.0.0", + "@types/node": "^22.0.0", + "@types/unist": "^3.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.0.0", + "extend": "^3.0.0", + "glob": "^10.0.0", + "ignore": "^6.0.0", + "is-empty": "^1.0.0", + "is-plain-obj": "^4.0.0", + "load-plugin": "^6.0.0", + "parse-json": "^7.0.0", + "trough": "^2.0.0", + "unist-util-inspect": "^8.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0", + "vfile-reporter": "^8.0.0", + "vfile-statistics": "^3.0.0", + "yaml": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-engine/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified-engine/node_modules/ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/unified-lint-rule": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-3.0.1.tgz", + "integrity": "sha512-HxIeQOmwL19DGsxHXbeyzKHBsoSCFO7UtRVUvT2v61ptw/G+GbysWcrpHdfs5jqbIFDA11MoKngIhQK0BeTVjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "trough": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-lint-rule/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified-message-control": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-5.0.0.tgz", + "integrity": "sha512-B2cSAkpuMVVmPP90KCfKdBhm1e9KYJ+zK3x5BCa0N65zpq1Ybkc9C77+M5qwR8FWO7RF3LM5QRRPZtgjW6DUCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-message-control/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-builder": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-4.0.0.tgz", + "integrity": "sha512-wmRFnH+BLpZnTKpc5L7O67Kac89s9HMrtELpnNaE6TAobq5DTZZs5YaTQfAZBA9bFPECx2uVAPO31c+GVug8mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-builder/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-after/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-find-between-all": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unist-util-find-between-all/-/unist-util-find-between-all-1.0.5.tgz", + "integrity": "sha512-zqpIPPzhbG6fI5lqYZhS1UPsMvxV9IY6dwbizLHLPAGNb3pQT3mTvmzXpP1K2lmUh4bhUwAN4gkQcxhR/OLS4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-find-between-all/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-inspect": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-8.1.0.tgz", + "integrity": "sha512-mOlg8Mp33pR0eeFpo5d2902ojqFFOKMMG2hF8bmH7ZlhnmjFgh0NI3/ZDwdaBJNbvrS7LZFVrBVtIE9KZ9s7vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-inspect/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-visit/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile-reporter": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-8.1.1.tgz", + "integrity": "sha512-qxRZcnFSQt6pWKn3PAk81yLK2rO2i7CDXpy8v8ZquiEOMLSnPw6BMSi9Y1sUCwGGl7a9b3CJT1CKpnRF7pp66g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/supports-color": "^8.0.0", + "string-width": "^6.0.0", + "supports-color": "^9.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0", + "vfile-sort": "^4.0.0", + "vfile-statistics": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile-reporter/node_modules/string-width": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", + "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^10.2.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vfile-reporter/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/vfile-sort": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-4.0.0.tgz", + "integrity": "sha512-lffPI1JrbHDTToJwcq0rl6rBmkjQmMuXkAxsZPRS9DXbaJQvc642eCg6EGxcX2i1L+esbuhq+2l9tBll5v8AeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-statistics": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-3.0.0.tgz", + "integrity": "sha512-/qlwqwWBWFOmpXujL/20P+Iuydil0rZZNglR+VNm6J0gpLHwuVM5s7g2TfVoswbXjZ4HuIhLMySEyIw5i7/D8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dev": true, + "license": "ISC" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..b7a625b6 --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "@json-schema-org/json-schema-spec", + "version": "1.0.0", + "description": "The JSON Schema Specification", + "type": "module", + "main": "index.js", + "scripts": { + "lint": "eslint . ; remark --no-stdout --frail .", + "build": "remark --rc-path specs/.remarkrc-build.js --output web/" + }, + "license": "MIT", + "devDependencies": { + "@stylistic/eslint-plugin": "^2.9.0", + "eslint": "^9.13.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-plugin-import": "^2.31.0", + "mdast-builder": "^1.1.1", + "mdast-util-find-and-replace": "^3.0.1", + "mdast-util-to-string": "^4.0.0", + "rehype-document": "^7.0.3", + "rehype-highlight": "^7.0.2", + "rehype-highlight-code-lines": "^1.1.3", + "rehype-stringify": "^10.0.1", + "remark-cli": "^12.0.1", + "remark-flexible-containers": "^1.2.1", + "remark-gfm": "^4.0.0", + "remark-heading-id": "^1.0.1", + "remark-preset-lint-consistent": "^6.0.0", + "remark-preset-lint-markdown-style-guide": "^6.0.0", + "remark-preset-lint-recommended": "^7.0.0", + "remark-rehype": "^11.1.1", + "remark-validate-links": "^13.0.1" + } +} diff --git a/remark/rehype-link-transformer.js b/remark/rehype-link-transformer.js new file mode 100644 index 00000000..224667d1 --- /dev/null +++ b/remark/rehype-link-transformer.js @@ -0,0 +1,18 @@ +import { existsSync } from "fs"; +import { visit } from "unist-util-visit"; +import url from "url"; + + +const rehypeLinkTransformer = () => (tree, vfile) => { + visit(tree, "element", (node) => { + if (node.tagName === "a") { + const href = url.parse(node.properties.href); + if (href.hostname === null && href.pathname?.endsWith(".md") && existsSync(vfile.history[0])) { + href.pathname = href.pathname.replace(/.md$/, ".html"); + node.properties.href = url.format(href); + } + } + }); +}; + +export default rehypeLinkTransformer; diff --git a/remark/remark-code-titles.js b/remark/remark-code-titles.js new file mode 100644 index 00000000..2f7aab28 --- /dev/null +++ b/remark/remark-code-titles.js @@ -0,0 +1,68 @@ +import { visit } from "unist-util-visit"; +import { text } from "mdast-builder"; + + +const hexdig = `[0-9a-fA-F]`; +const char = `(?:\\\\["\\/\\\\brfnt]|\\\\u${hexdig}{4}|[^"\\\\])`; +const jsonStringPattern = new RegExp(`^"${char}*"`); + +const remarkNumberHeadings = () => (tree) => { + visit(tree, "code", (codeNode, index, parent) => { + // Support title without a language + if (codeNode.lang && codeNode.lang[0] === "\"") { + codeNode.meta = `${codeNode.lang} ${codeNode.meta}`; + codeNode.lang = null; + } + + let title = ""; + const titleClasses = ["remark-code-title"]; + + const language = codeNode.lang ?? ""; + if (language.toLowerCase() === "jsonschema") { + codeNode.lang = "json"; + title = "JSON Schema"; + titleClasses.push("code-title-jsonschema"); + } else if (language.toLowerCase() === "json") { + title = "JSON"; + titleClasses.push("code-title-json"); + } else if (language.toLowerCase() === "jsonc") { + title = "JSON"; + titleClasses.push("code-title-json"); + } else { + titleClasses.push("code-title-unknown"); + } + + if ("meta" in codeNode) { + const match = jsonStringPattern.exec(codeNode.meta); + if (match) { + const customTitle = JSON.parse(match[0]); + title = title ? `${title} - ${customTitle}` : customTitle; + codeNode.meta = codeNode.meta.slice(match[0].length).trim(); + } + } + + const containerChildren = []; + if (title) { + const titleNode = div([text(title)], { className: titleClasses }); + containerChildren.push(titleNode); + } + containerChildren.push(codeNode); + + const wrappedCodeNode = div(containerChildren, { className: ["remark-code-container"] }); + + parent.children.splice(index, 1, wrappedCodeNode); + }); +}; + +const div = (children, properties) => { + return { + type: "container", + children, + data: { + hName: "div", + hProperties: properties + } + }; +}; + +export default remarkNumberHeadings; diff --git a/remark/remark-headings.js b/remark/remark-headings.js new file mode 100644 index 00000000..1cc6abb8 --- /dev/null +++ b/remark/remark-headings.js @@ -0,0 +1,97 @@ +import { visit } from "unist-util-visit"; +import { link, text } from "mdast-builder"; +import { findAndReplace } from "mdast-util-find-and-replace"; +import { toString as nodeToString } from "mdast-util-to-string"; + + +const defaultOptions = { + startDepth: 1, + skip: [], + appendixToken: "%appendix%", + appendixPrefix: "Appendix" +}; + +const remarkNumberHeadings = (options) => (tree, file) => { + options = { ...defaultOptions, ...options }; + options.skip = new RegExp(`^(${options.skip.join("|")})$`, "u"); + + // Auto-number headings + let sectionNumbers = []; + + visit(tree, "heading", (headingNode) => { + if (headingNode.depth < options.startDepth) { + return; + } + + const headingText = nodeToString(headingNode); + if (options.skip.test(headingText)) { + return; + } + + if (!("data" in headingNode)) { + headingNode.data = {}; + } + + if (!("hProperties" in headingNode.data)) { + headingNode.data.hProperties = {}; + } + + if (headingText.startsWith(options.appendixToken)) { + findAndReplace(headingNode, [options.appendixToken]); + + const currentIndex = typeof sectionNumbers[headingNode.depth] === "string" + ? sectionNumbers[headingNode.depth] + : "@"; + sectionNumbers[headingNode.depth] = String.fromCharCode(currentIndex.charCodeAt(0) + 1); + sectionNumbers = sectionNumbers.slice(0, headingNode.depth + 1); + + const sectionNumber = sectionNumbers.slice(options.startDepth, headingNode.depth + 1).join("."); + headingNode.data.section = `${options.appendixPrefix} ${sectionNumber}`; + + headingNode.children.splice(0, 0, text(`${headingNode.data.section}. `)); + } else { + sectionNumbers[headingNode.depth] = (sectionNumbers[headingNode.depth] ?? 0) + 1; + sectionNumbers = sectionNumbers.slice(0, headingNode.depth + 1); + + const sectionNumber = sectionNumbers.slice(options.startDepth, headingNode.depth + 1).join("."); + const prefix = typeof sectionNumbers[options.startDepth] === "string" + ? options.appendixPrefix + : "Section"; + headingNode.data.section = `${prefix} ${sectionNumber}`; + + headingNode.children.splice(0, 0, text(`${sectionNumber}. `)); + } + + if (!("id" in headingNode.data)) { + const sectionSlug = headingNode.data?.id + ?? headingNode.data.section.replaceAll(/[ .]/g, "-").toLowerCase(); + headingNode.data.hProperties.id = sectionSlug; + headingNode.data.id = sectionSlug; + } + }); + + // Build headings data used by ./remark-reference-links.js + if (!("data" in file)) { + file.data = {}; + } + + file.data.headings = {}; + + visit(tree, "heading", (headingNode) => { + if (headingNode.data?.id) { + if (headingNode.data.id in file.data.headings) { + file.message(`Found duplicate heading id "${headingNode.data.id}"`); + } + file.data.headings[headingNode.data.id] = headingNode; + } + }); + + // Make heading a link + visit(tree, "heading", (headingNode) => { + if (headingNode.data?.id) { + headingNode.children = [link(`#${headingNode.data.id}`, "", headingNode.children)]; + } + }); +}; + +export default remarkNumberHeadings; diff --git a/remark/remark-reference-links.js b/remark/remark-reference-links.js new file mode 100644 index 00000000..16af2928 --- /dev/null +++ b/remark/remark-reference-links.js @@ -0,0 +1,21 @@ +import { text, link } from "mdast-builder"; +import { toString as nodeToString } from "mdast-util-to-string"; +import { findAndReplace } from "mdast-util-find-and-replace"; + + +const referenceLink = /\{\{(?.*?)\}\}/ug; + +const remarkReferenceLinks = () => (tree, file) => { + findAndReplace(tree, [referenceLink, (value, id) => { + // file.data.headings comes from ./remark-headings.js + if (!(id in file.data.headings)) { + throw Error(`ReferenceLinkError: No header found with id "${id}"`); + } + + const headerText = nodeToString(file.data.headings[id]); + const linkText = text(file.data.headings[id].data.section); + return link(`#${id}`, headerText, [linkText]); + }]); +}; + +export default remarkReferenceLinks; diff --git a/remark/remark-table-of-contents.js b/remark/remark-table-of-contents.js new file mode 100644 index 00000000..3fbb3bde --- /dev/null +++ b/remark/remark-table-of-contents.js @@ -0,0 +1,65 @@ +import { visit } from "unist-util-visit"; +import { list, listItem } from "mdast-builder"; +import { toString as nodeToString } from "mdast-util-to-string"; + + +const defaultOptions = { + heading: "Table of Contents", + startDepth: 1, + skip: [] +}; + +const remarkTableOfContents = (options) => (tree, file) => { + options = { ...defaultOptions, ...options }; + options.skip.push(options.heading); + options.skip = new RegExp(`^(${options.skip.join("|")})$`, "u"); + + let insertTableOfContents; + + const tableOfContents = list("unordered"); + let currentList = tableOfContents; + const listStack = [currentList]; + let currentDepth = options.startDepth; + + visit(tree, "heading", (headingNode, index, parent) => { + const headingText = nodeToString(headingNode); + + if (headingText === options.heading) { + insertTableOfContents = () => { + parent.children.splice(index + 1, 0, tableOfContents); + }; + } + + if (headingNode.depth < options.startDepth) { + return; + } + + while (headingNode.depth > currentDepth) { + const newList = list("unordered"); + listStack.push(newList); + currentList.children.push(newList); + currentList = newList; + currentDepth++; + } + + while (headingNode.depth < currentDepth) { + listStack.pop(); + currentList = listStack[listStack.length - 1]; + currentDepth--; + } + + if (options.skip.test(headingText)) { + return; + } + + currentList.children.push(listItem(headingNode.children)); + }); + + if (insertTableOfContents) { + insertTableOfContents(); + } else { + file.message(`Table of Contents not added. Add a heading with the text "${options.heading}" or set the 'heading' option to use a different heading.`); + } +}; + +export default remarkTableOfContents; diff --git a/requirements.in b/requirements.in new file mode 100644 index 00000000..f5cf3e08 --- /dev/null +++ b/requirements.in @@ -0,0 +1 @@ +xml2rfc>=3.12.0 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..92b43d25 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,45 @@ +# +# This file is autogenerated by pip-compile with Python 3.13 +# by the following command: +# +# pip-compile requirements.in +# +certifi==2025.7.14 + # via requests +charset-normalizer==3.4.2 + # via requests +configargparse==1.7.1 + # via xml2rfc +google-i18n-address==3.1.1 + # via xml2rfc +idna==3.10 + # via requests +intervaltree==3.1.0 + # via xml2rfc +jinja2==3.1.6 + # via xml2rfc +lxml==6.0.0 + # via xml2rfc +markupsafe==3.0.2 + # via jinja2 +platformdirs==4.3.8 + # via xml2rfc +pycountry==24.6.1 + # via xml2rfc +pyyaml==6.0.2 + # via xml2rfc +requests==2.32.4 + # via + # google-i18n-address + # xml2rfc +sortedcontainers==2.4.0 + # via intervaltree +urllib3==2.5.0 + # via requests +wcwidth==0.2.13 + # via xml2rfc +xml2rfc==3.30.0 + # via -r requirements.in + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/schema-output.json b/schema-output.json deleted file mode 100644 index 579ef8bb..00000000 --- a/schema-output.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-08/schema#", - "$id": "http://json-schema.org/draft-08/schema-output#", - "description": "A schema that validates the minimum requirements for validation output", - "$defs": { - "outputUnit":{ - "properties": { - "valid": { "type": "boolean" }, - "keywordLocation": { - "type": "string", - "format": "uri-reference" - }, - "absoluteKeywordLocation": { - "type": "string", - "format": "uri" - }, - "instanceLocation": { - "type": "string", - "format": "uri-reference" - }, - "errors": { - "$ref": "#/$defs/outputUnitArray" - }, - "annotations": { - "$ref": "#/$defs/outputUnitArray" - } - }, - "required": [ "valid", "keywordLocation", "instanceLocation" ], - "allOf": [ - { - "if": { - "properties": { - "valid": { "const": false } - } - }, - "then": { - "required": [ "errors" ] - } - }, - { - "if": { - "oneOf": [ - { - "properties": { - "keywordLocation": { - "pattern": ".*/$ref/.*" - } - } - }, - { - "properties": { - "keywordLocation": { - "pattern": ".*/$recursiveRef/.*" - } - } - } - ] - }, - "then": { - "required": [ "absoluteKeywordLocation" ] - } - } - ] - }, - "outputUnitArray": { - "type": "array", - "items": { "$ref": "#/$defs/outputUnit" } - }, - "flag": { - "properties": { - "valid": { "type": "boolean" } - }, - "required": [ "valid" ] - }, - "basic": { "$ref": "#/outputUnit" }, - "detailed": { "$ref": "#/outputUnit" }, - "verbose": { "$ref": "#/outputUnit" } - }, - "oneOf": [ - { "$ref": "#/$defs/flag" }, - { "$ref": "#/$defs/basic" }, - { "$ref": "#/$defs/detailed" }, - { "$ref": "#/$defs/verbose" } - ] -} \ No newline at end of file diff --git a/specs/.remarkrc-build.js b/specs/.remarkrc-build.js new file mode 100644 index 00000000..089e2cce --- /dev/null +++ b/specs/.remarkrc-build.js @@ -0,0 +1,34 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; +import rehypeHighlight from "rehype-highlight"; +import { all } from "lowlight"; +import rehypeHighlightCodeLines from "rehype-highlight-code-lines"; +import remarkRehype from "remark-rehype"; +import rehypeStringify from "rehype-stringify"; +import rehypeDocument from "rehype-document"; +import specsPreset from "./.remarkrc-specs.js"; +import rehypeLinkTransformer from "../remark/rehype-link-transformer.js"; + + +export default { + plugins: [ + specsPreset, + remarkRehype, + [rehypeHighlight, { languages: all }], + [rehypeHighlightCodeLines, { showLineNumbers: true }], + rehypeLinkTransformer, + [rehypeDocument, { + css: [ + "https://cdn.jsdelivr.net/npm/water.css@2/out/dark.css", + "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/github-dark-dimmed.min.css" + ], + style: readFileSync(resolve(import.meta.dirname, "spec.css"), "utf8") + }], + rehypeStringify, + () => (_tree, file) => { + if (file.extname) { + file.extname = ".html"; + } + } + ] +}; diff --git a/specs/.remarkrc-specs.js b/specs/.remarkrc-specs.js new file mode 100644 index 00000000..2e3058e6 --- /dev/null +++ b/specs/.remarkrc-specs.js @@ -0,0 +1,42 @@ +import remarkGfm from "remark-gfm"; +import remarkHeadingId from "remark-heading-id"; +import remarkFlexibleContainers from "remark-flexible-containers"; +import remarkCodeTitles from "../remark/remark-code-titles.js"; +import remarkHeadings from "../remark/remark-headings.js"; +import remarkReferenceLinks from "../remark/remark-reference-links.js"; +import remarkTableOfContents from "../remark/remark-table-of-contents.js"; + + +export default { + plugins: [ + remarkGfm, + remarkHeadingId, + [remarkHeadings, { + startDepth: 2, + skip: [ + "Abstract", + "Status", + "Note to Readers", + "Table of Contents", + "Authors' Addresses", + "Champions", + "\\[.*\\]", + "draft-.*" + ] + }], + remarkReferenceLinks, + [remarkTableOfContents, { + startDepth: 2, + skip: [ + "Abstract", + "Note to Readers", + "Authors' Addresses", + "Champions", + "\\[.*\\]", + "draft-.*" + ] + }], + remarkFlexibleContainers, + remarkCodeTitles + ] +}; diff --git a/specs/.remarkrc.js b/specs/.remarkrc.js new file mode 100644 index 00000000..11ab67dc --- /dev/null +++ b/specs/.remarkrc.js @@ -0,0 +1,10 @@ +import specPreset from "./.remarkrc-specs.js"; +import lintPreset from "../.remarkrc-lint.js"; + + +export default { + plugins: [ + specPreset, + lintPreset + ] +}; diff --git a/specs/jsonschema-core.md b/specs/jsonschema-core.md new file mode 100644 index 00000000..4d629d3f --- /dev/null +++ b/specs/jsonschema-core.md @@ -0,0 +1,2582 @@ +# JSON Schema: A Media Type for Describing JSON Documents + +## Abstract + +JSON Schema defines the media type `application/schema+json`, a JSON-based +format for describing the structure of JSON data. JSON Schema asserts what a +JSON document must look like, ways to extract information from it, and how to +interact with it. The `application/schema-instance+json` media type provides +additional feature-rich integration with `application/schema+json` beyond what +can be offered for `application/json` documents. + +## Note to Readers + +The issues list for this draft can be found at +. + +For additional information, see . + +To provide feedback, use this issue tracker, the communication methods listed on +the homepage, or email the document editors. + +## Table of Contents + +## Introduction + +JSON Schema is a JSON media type for defining the structure of JSON data. JSON +Schema is intended to define validation, documentation, hyperlink navigation, +and interaction control of JSON data. + +This specification defines JSON Schema core terminology and mechanisms, +including pointing to another JSON Schema by reference, dereferencing a JSON +Schema reference, specifying the dialect being used, and defining terms. + +Other specifications define keywords that perform assertions about validation, +linking, annotation, navigation, interaction, as well as other related concepts +such as output formats. + +## Conventions and Terminology + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in [RFC 2119](https://www.rfc-editor.org/info/rfc2119). + +The terms "JSON", "JSON text", "JSON value", "member", "element", "object", +"array", "number", "string", "boolean", "true", "false", and "null" in this +document are to be interpreted as defined in [RFC 8259][rfc8259]. + +## Overview + +This document proposes a new media type `application/schema+json` to identify a +JSON Schema for describing JSON data. It also proposes a further optional media +type, `application/schema-instance+json`, to provide additional integration +features. JSON Schemas are themselves JSON documents. This, and related +specifications, define keywords allowing authors to describe JSON data in +several ways. + +JSON Schema uses keywords to assert constraints on JSON instances or annotate +those instances with additional information. Additional keywords are used to +apply assertions and annotations to more complex JSON data structures, or based +on some sort of condition. + +To facilitate re-use, keywords can be organized into vocabularies. A vocabulary +consists of a list of keywords, together with their syntax and semantics. A +dialect is defined as a set of vocabularies and their required support +identified in a meta-schema. + +JSON Schema can be extended either by defining additional vocabularies, or less +formally by defining additional keywords outside of any vocabulary. Unrecognized +individual keywords are not supported. + +This document defines a set of core keywords that MUST be supported by any +implementation, and cannot be disabled. These keywords are each prefixed with a +"$" character to emphasize their required nature. These keywords are essential +to the functioning of the `application/schema+json` media type. + +Additionally, this document defines a RECOMMENDED set of keywords for +applying subschemas conditionally, and for applying subschemas to the contents +of objects and arrays. These keywords, or a set very much like them, are +required to write schemas for non-trivial JSON instances, whether those schemas +are intended for assertion validation, annotation, or both. While not part of +the required core set, for maximum interoperability this additional +set is included in this document and its use is strongly encouraged. + +Further keywords for purposes such as structural validation or hypermedia +annotation are defined in other documents. These other documents each define a +dialect collecting the standard sets of keywords needed to write schemas for +that document's purpose. + +## Definitions + +### JSON Document + +A JSON document is an information resource (series of octets) described by the +`application/json` media type. + +In JSON Schema, the terms "JSON document", "JSON text", and "JSON value" are +interchangeable because of the data model it defines in {{data-model}}. + +JSON Schema is only defined over JSON documents. However, any document or memory +structure that can be parsed into or processed according to the JSON Schema data +model can be interpreted against a JSON Schema. + +### Instance + +A JSON document to which a schema is applied is known as an "instance". + +JSON Schema is defined over `application/json` or compatible documents, +including media types with the `+json` structured syntax suffix. + +Among these, this specification defines the `application/schema-instance+json` +media type which defines handling for fragments in the IRI. + +#### Instance Data Model {#data-model} + +JSON Schema interprets documents according to a data model. A JSON value +interpreted according to this data model is called an "instance". + +An instance has one of six primitive types, and a range of possible values +depending on the type: + +- *null*: A JSON "null" value +- boolean: A "true" or "false" value, from the JSON "true" or "false" value +- *object*: An unordered set of properties mapping a string to an instance, from + the JSON "object" value +- *array*: An ordered list of instances, from the JSON "array" value +- *number*: An arbitrary-precision, base-10 decimal number value, from the JSON + "number" value +- *string*: A string of Unicode code points, from the JSON "string" value + +Whitespace and formatting concerns, including different lexical representations +of numbers that are equal within the data model, are thus outside the scope of +JSON Schema. Extensions to JSON Schema that wish to work with such differences +in lexical representations SHOULD define keywords to precisely interpret +formatted strings within the data model rather than relying on having the +original JSON representation Unicode characters available. + +Since an object cannot have two properties with the same key, behavior for a +JSON document that tries to define two properties with the same key in a single +object is undefined. + +Note that JSON Schema extensions are free to define their own extended type +system. This should not be confused with the core data model types defined here. +As an example, "integer" is a reasonable type to define as a value for a +keyword, but the data model makes no distinction between integers and other +numbers. + +#### Instance Equality + +Two JSON instances are said to be equal if and only if they are of the same type +and have the same value according to the data model. Specifically, this means: + +- both are null; or +- both are true; or +- both are false; or +- both are strings, and are the same codepoint-for-codepoint; or +- both are numbers, and have the same mathematical value; or +- both are arrays, and have an equal value item-for-item; or +- both are objects, and each property in one has exactly one property with a key + equal to the other's, and that other property has an equal value. + +Implied in this definition is that arrays must be the same length, objects must +have the same number of members, properties in objects are unordered, there is +no way to define multiple properties with the same key, and mere formatting +differences (indentation, placement of commas, trailing zeros) are +insignificant. + +#### Non-JSON Instances + +It is possible to use JSON Schema with a superset of the JSON Schema data model, +where an instance may be outside any of the six JSON data types. + +In this case, annotations still apply; but most validation keywords will not be +useful, as they will always pass or always fail. + +An extension may define support for a superset of the core data model. +The schema itself may only be expressible in this superset; for example, to make +use of the `const` keyword. + +### JSON Schema Documents {#schema-document} + +A JSON Schema document, or simply a schema, is a JSON document used to describe +an instance. A schema can itself be interpreted as an instance, but SHOULD +always be given the media type `application/schema+json` rather than +`application/schema-instance+json`. The `application/schema+json` media type is +defined to offer a superset of the fragment identifier syntax and semantics +provided by `application/schema-instance+json`. + +A JSON Schema MUST be an object or a boolean. + +#### JSON Schema Objects and Keywords + +Object properties that are applied to the instance are called keywords, or +schema keywords. Broadly speaking, keywords fall into one of five categories: + +- *identifiers*: control schema identification through setting a IRI for the + schema and/or changing how the base IRI is determined +- *assertions*: produce a boolean result when applied to an instance +- *annotations*: attach information to an instance for application use +- *applicators*: apply one or more subschemas to a particular location in the + instance, and combine or modify their results +- *reserved locations*: do not directly affect results, but reserve a place for + a specific purpose to ensure interoperability + +Keywords may fall into multiple categories, although applicators SHOULD only +produce assertion results based on their subschemas' results. They should not +define additional constraints independent of their subschemas. + +Keywords which are properties within the same schema object are referred to as +adjacent keywords. + +Extension keywords, meaning those defined outside of this document and its +companions, are free to define other behaviors as well. + +A JSON Schema MUST NOT contain properties which are not schema keywords or are +not recognized as schema keywords. The behavior of such keywords is governed by +{{unrecognized}}. + +An empty schema is a JSON Schema with no properties. + +#### Boolean JSON Schemas + +The boolean schema values `true` and `false` are trivial schemas that always +produce themselves as assertion results, regardless of the instance value. They +never produce annotation results. + +These boolean schemas exist to clarify schema author intent and facilitate +schema processing optimizations. They behave identically to the following schema +objects (where `not` is defined [later in this document](#not)). + +- `true`: Always passes validation, as if the empty schema `{}` +- `false`: Always fails validation, as if the schema `{ "not": {} }` + +While the empty schema object is unambiguous, there are many possible +equivalents to the `false` schema. Using the boolean values ensures that the +intent is clear to both human readers and implementations. + +#### Meta-Schemas + +A schema that itself describes a schema is called a meta-schema. Meta-schemas +are used to validate JSON Schemas and specify the set of keywords those schemas +are using. + +#### Root Schema, Subschemas, and Resources {#root} + +A JSON Schema resource is a schema which is +[canonically](https://www.rfc-editor.org/info/rfc6596) identified by an +[absolute IRI](https://www.rfc-editor.org/rfc/rfc3987.html#section-2.2). Schema +resources MAY also be identified by IRIs, including IRIs with fragments, if the +resulting secondary resource (as defined by +[section 3.5 of RFC 3986](https://www.rfc-editor.org/rfc/rfc3986.html#section-3.5)) +is identical to the primary resource. This can occur with the empty fragment, or +when one schema resource is embedded in another. Any such IRIs with fragments +are considered to be non-canonical. + +A root schema, which may comprise the entire JSON document, is the top-level +schema that is identified by the absolute IRI. The root schema is always a +schema resource, where the IRI is determined as described in {{initial-base}}. + +Document formats which embed JSON Schemas within them will not necessarily have +a single root schema in this sense. How root schemas are identified within such +documents SHOULD be defined by the specifications which govern them. + +Some keywords take schemas themselves, allowing JSON Schemas to be nested: + +```jsonschema +{ + "title": "root", + "items": { + "title": "array item" + } +} +``` + +In this example document, the schema titled "array item" is a subschema, and the +schema titled "root" is the root schema. + +As with the root schema, a subschema is either an object or a boolean. + +As discussed in {{id-keyword}}, a JSON Schema document can contain multiple JSON +Schema resources. When used without qualification, the term "root schema" refers +to the document's root schema. In some cases, resource root schemas are +discussed. A resource's root schema is its top-level schema object, which would +also be a document root schema if the resource were to be extracted to a +standalone JSON Schema document. + +Whether multiple schema resources are embedded or linked with a reference, they +are processed in the same way, with the same available behaviors. + +## Fragment Identifiers {#fragments} + +In accordance with +[section 3.1 of RFC 6839](https://www.rfc-editor.org/rfc/rfc6839.html#section-3.1), +the syntax and semantics of fragment identifiers specified for any +json media +type SHOULD be as specified for `application/json`. (At publication of this +document, there is no fragment identification syntax defined for +`application/json`.) + +Additionally, the `application/schema+json` media type supports two fragment +identifier structures: plain names and JSON Pointers. The +`application/schema-instance+json` media type supports one fragment identifier +structure: JSON Pointers. + +The use of JSON Pointers as IRI fragment identifiers is described in [RFC +6901][rfc6901]. For `application/schema+json`, which supports two fragment +identifier syntaxes, fragment identifiers matching the JSON Pointer syntax, +including the empty string, MUST be interpreted as JSON Pointer fragment +identifiers. + +Per the W3C's +[best practices for fragment identifiers](https://www.w3.org/TR/2012/WD-fragid-best-practices-20121025), +plain name fragment identifiers in `application/schema+json` are reserved for +referencing locally named schemas. + +Plain name fragments MUST follow XML's +[`NCName` production](https://www.w3.org/TR/2006/REC-xml-names11-20060816/#NT-NCName), +which allows for compatibility with the recommended [plain name +syntax](https://www.w3.org/TR/2003/REC-xptr-framework-20030325/) for XML-based +media types. For convenience, the `NCName` syntax is reproduced here in ABNF +form, using a minimal set of rules: + +```abnf +NCName = NCNameStartChar *NCNameChar +NCNameStartChar = "_" / ALPHA + / %xC0-D6 / %xD8-F6 / %xF8-2FF + / %x370-37D / %x37F-1FFF + / %x200C-200D / %x2070-218F + / %x2C00-2FEF / %x3001-D7FF + / %xF900-FDCF / %xFDF0-FFFD + / %x10000-EFFFF +NCNameChar = NCNameStartChar / "-" / "." / DIGIT + / %xB7 / %x0300-036F / %x203F-2040 +``` + +All fragment identifiers that do not match the JSON Pointer syntax MUST be +interpreted as plain name fragment identifiers. + +Defining a plain name fragment identifier within an `application/schema+json` +document is specified in the [`$anchor` keyword](#anchors) section. + +## General Considerations + +### Range of JSON Values + +An instance may be any valid JSON value as defined by [JSON][rfc8259]. JSON +Schema imposes no restrictions on type: JSON Schema can describe any JSON value, +including, for example, null. + +### Programming Language Independence {#language} + +JSON Schema is programming language agnostic, and supports the full range of +values described in the data model. Be aware, however, that some languages and +JSON parsers may not be able to represent in memory the full range of values +describable by JSON. + +### Regular Expressions {#regex} + +Keywords MAY use regular expressions to express constraints, or constrain the +instance value to be a regular expression. These regular expressions SHOULD be +valid according to the regular expression dialect described in [ECMA-262, +section 21.2.1](https://www.ecma-international.org/ecma-262/11.0/index.html). + +Unless otherwise specified by a keyword, regular expressions MUST NOT be +considered to be implicitly anchored at either end. All regular expression +keywords in this specification and its companion documents are un-anchored. + +Regular expressions SHOULD be built with the "u" flag (or equivalent) to provide +Unicode support, or processed in such a way which provides Unicode support as +defined by ECMA-262. + +Furthermore, given the high disparity in regular expression constructs support, +schema authors SHOULD limit themselves to the following regular expression +tokens: + +- individual Unicode characters, as defined by the [JSON + specification][rfc8259]; +- simple atoms: `.` (any character except line terminator); +- simple character classes (`[abc]`), range character classes (`[a-z]`); +- complemented simple character classes (`[^abc]`); +- complemented range character classes (`[^a-z]`); +- simple quantifiers: `+` (one or more), `*` (zero or more), `?` (zero or one), + and their non-greedy versions (`+?`, `*?`, `??`); +- range quantifiers: `{x}` (exactly x occurrences), `{x,y}` (at least x, at most + y, occurrences), `{x,}` (x occurrences or more), and their non-greedy versions; +- the beginning-of-input (`^`) and end-of-input (`$`) anchors; +- simple grouping (using `(` and `)`) and alternation (`|`). + +Finally, implementations MUST NOT take regular expressions to be anchored, +neither at the beginning nor at the end. This means, for instance, the pattern +"es" matches "expression". + +### Extending JSON Schema {#extending} + +Additional schema keywords MAY be defined by any entity. Save for explicit +agreement, schema authors SHALL NOT expect these additional keywords to be +supported by implementations that do not explicitly document such support. + +Extension keywords MUST NOT directly modify the operation of keywords defined by +this document or the companion JSON Schema Validation specificiation, and SHOULD +NOT directly modify the operation of keywords defined by other extension +documents.[^11] + +[^11]: JSON Schema currently does not have a namespacing mechanism, which would +allow multiple extensions to define the same keyword differently while also +giving the schema author the ability to declare which definition is intended. +Such a feature is planned for future releases. See the +[Vocabularies / Extensions project](https://github.com/orgs/json-schema-org/projects/28/views/2) +in GitHub for more information. + +Implementations MAY provide the ability to register or load handlers for +keywords that they do not support directly. The exact mechanism for registering +and implementing such handlers is implementation-dependent. + +#### Implicit annotation keywords {#implicit-annotations} + +Keywords which begin with "x-" are implicitly defined as annotation keywords. + +The values of such keywords MUST be collected as annotations. + +Implicit annotation keywords MUST NOT affect evaluation of a schema in +any way other than annotation collection. + +Consequently, the "x-" prefix is reserved for this purpose, and extension +keywords MUST NOT begin with this prefix. + +#### Handling of unrecognized or unsupported keywords {#unrecognized} + +Implementations MUST refuse to evaluate schemas which contain keywords which +they do not know how to process or explicitly choose not to process. + +## Specification Versioning and Compatibility + +This specification is identified collectively by two values: version and release +year. + +A schema written to conform with the requirements of a given version is +compatible with successive specifications, which are published with the same +version and either the same or greater release year value. Thus, JSON Schema +provides a guarantee of compatibility for future releases within a version. + +### Future Development and Support of Proposals + +Continued development of these specifications and support requirments for +proposed features is managed in the +[json-schema-org/json-schema-spec](https://github.com/json-schema-org/json-schema-spec) +GitHub repository and defined by _PROCESS.md_. + +## Keyword Behaviors {#keyword-behaviors} + +JSON Schema keywords may exhibit one or more behaviors. This specification +defines three such behaviors[^7]: + +- Assertions validate that an instance satisfies constraints, producing a + boolean result: `true` if the constraints are satisfied; `false` otherwise. +- Annotations attach information to instance locations that applications may use + in any way they see fit. +- Applicators apply subschemas to parts of the instance and combine their + results. + +[^7]: This specification also defines several operational directive keywords, +such as `$id` and `$schema`, which do not exhibit these behaviors. Instead, +these keywords provide metadata that instruct implementations on how to +interpret and process the schema. + +Extension keywords SHOULD be defined using these behaviors, keeping in mind that +annotations in particular are extremely flexible. Complex behavior is usually +better delegated to applications on the basis of annotation data than +implemented directly as schema keywords. However, extension keywords MAY define +other behaviors for specialized purposes. + +Implementations SHOULD NOT add unspecified behaviors to keywords. + +For the purposes of this document, an instance "validating against a keyword" +means that the keyword produces an assertion result of `true` if the instance +satisfies the given constraint; otherwise an assertion result of `false` is +produced. + + + +Evaluating an instance against a schema involves processing all of the keywords +in the schema against the appropriate locations within the instance. Typically, +applicator keywords are processed until a schema object with no applicators (and +therefore no subschemas) is reached. The appropriate location in the instance is +evaluated against the assertion and annotation keywords in the schema object. +The interactions of those keyword results to produce the schema object results +are governed by {{annot-assert}}, while the relationship of subschema results to +the results of the applicator keyword that applied them is described by +{{applicators}}. + +Evaluation of a parent schema object can complete once all of its subschemas +have been evaluated, although in some circumstances evaluation may be +short-circuited due to assertion results. When annotations are being collected, +some assertion result short-circuiting is not possible due to the need to +examine all subschemas for annotation collection, including those that cannot +further change the assertion result. + +### Lexical Scope and Dynamic Scope {#scopes} + +While most JSON Schema keywords can be evaluated on their own, or at most need +to take into account the values or results of adjacent keywords in the same +schema object, a few have more complex behavior. This behavior is generally +governed by the scope of the keyword. + +This specification defines two such scopes: lexical and dynamic. + +#### Lexical Scope + +The lexical scope of a keyword is determined by the nested JSON data structure +of objects and arrays. The smallest such scope is a single schema object with no +subschemas. The largest scope is an entire schema document, recursively +including all of its subschemas. + +Keywords MAY be defined with a partial value which must be resolved against +another value found within the lexical structure of the JSON document. The +`$id`, `$schema`, and `$ref` core keywords, and the `base` JSON Hyper-Schema +keyword, are some such keywords. For example, an `$id` keyword found in an +embedded schema resource may have a value that is a relative IRI. This value +must be resolved against another `$id` keyword found in an ancestor subschema, +or the root schema, to produce an absolute IRI which fully identifies that +embedded schema resource. + +Note that some keywords, such as `$schema`, apply to the lexical scope of the +entire schema resource, and therefore MUST only appear in a schema resource's +root object. + +#### Dynamic Scope + +The dynamic scope is the ordered collection of schema resources navigated during +evaluation, starting at the root and ending at the schema resource which +contains the subschema under evaluation. The outermost dynamic scope is the +schema resource at which processing begins. The path that evaluation takes, +starting from the subschema to any particular subschema (including any `$ref` +and `$dynamicRef` keywords that may have been resolved), is considered the +"evaluation path". + +Lexical and dynamic scopes align until a reference keyword is encountered. While +following the reference moves processing from one lexical scope into a different +one, from the perspective of dynamic scope, following a reference is no +different from descending into a subschema. A keyword on the far side of the +reference that resolves information through the dynamic scope will consider the +originating side of the reference to be its dynamic parent rather than examining +the local lexically enclosing parent. + +The concept of dynamic scope is primarily used with `$dynamicRef` and +`$dynamicAnchor`, and should be considered an advanced feature and used with +caution when defining additional keywords. It also appears when reporting errors +and collected annotations, as it may be possible to revisit the same lexical +scope repeatedly with different dynamic scopes. For this reason, it is important +to inform the user of the evaluation path that produced the error or annotation. + +### Keyword Interactions + +Unless otherwise specified, keywords act independently. + +Keywords MAY modify their behavior based on the presence, absence, or value of +another keyword in the same schema object. Such keywords MUST NOT result in a +circular dependency. + +Supplementary specifications are encouraged to specify any dependencies as part +of the dependent keyword (i.e. the keyword whose behavior is modified). + +Within this document, keyword dependencies are expressed using one of the +following mechanisms: + +- Static dependencies, in which the dependency relies on the presence or + contents of another keyword. +- Dynamic dependencies, in which the dependency relies on the evaluation of + another keyword against an instance. This dependency may be on either the + annotations produced by the keyword or the validation result of its + subschema(s). + +These mechanisms are used merely to describe dependencies; they are for +illustrative purposes and not prescriptive. Implementations MAY use whatever +mechanisms make sense given the needs of their architecture and language in +order to achieve the specified behaviors. + +### Default Behaviors {#default-behaviors} + +A missing keyword MUST NOT produce a false assertion result, MUST NOT produce +annotation results, and MUST NOT cause any other schema to be evaluated as part +of its own behavioral definition. However, given that missing keywords do not +contribute annotations, the lack of annotation results may indirectly change the +behavior of other keywords. + +In some cases, the missing keyword assertion behavior of a keyword is identical +to that produced by a certain value, and keyword definitions SHOULD note such +values where known. However, even if the value which produces the default +behavior would produce annotation results if present, the default behavior still +MUST NOT result in annotations. + +Because annotation collection can add significant cost in terms of both +computation and memory, implementations MAY opt out of this feature. Keywords +that are specified in terms of collected annotations SHOULD describe reasonable +alternate approaches when appropriate. This approach is demonstrated by the +[`items`](#items) and [`additionalProperties`](#additionalproperties) keywords +in this document. + +Note that when no such alternate approach is possible for a keyword, +implementations that do not support annotation collections will not be able to +support those keywords. + +### Identifiers + +Identifiers define IRIs for a schema, or affect how such IRIs are resolved in +[references](#referenced), or both. This document defines several identifying +keywords, most notably `$id`. + +Canonical schema IRIs MUST NOT change while processing an instance, but keywords +that affect IRI reference resolution MAY have behavior that is only fully +determined at runtime. + +While custom identifier keywords are possible, extension designers should take +care not to disrupt the functioning of core keywords. For example, the +`$dynamicAnchor` keyword in this specification limits its resolution behavior +to matching `$dynamicRef` keywords, leaving the behavior of `$ref` +undisturbed. + +### Applicators {#applicators} + +Applicators allow for building more complex schemas than can be accomplished +with a single schema object. Evaluation of an instance against a [schema +document](#schema-document) begins by applying the [root schema](#root) to the +complete instance document. From there, keywords known as applicators are used +to determine which additional schemas are applied. Such schemas may be applied +in-place to the current location, or to a child location. + +The schemas to be applied may be present as subschemas comprising all or part of +the keyword's value. Alternatively, an applicator may refer to a schema +elsewhere in the same schema document, or in a different one. The mechanism for +identifying such referenced schemas is defined by the keyword. + +Applicator keywords also behave as assertions, using the assertion results of +each subschema or referenced schema of the keyword. These boolean results are +modified (e.g. the `not` keyword negates its subschema's assertion) and/or +combined (e.g. `allOf` takes the conjunction of its subschemas' assertions) to +produce the boolean result of the applicator. Applicators may apply any boolean +logic operation to the assertion results of subschemas, but SHOULD NOT introduce +new assertion conditions of their own.[^2] + +[^2]: It is recommended that keywords have a single resposibility. An example of +this in action is the separation between `properties`, which verifies object +property values have the right data _if_ they exist, and `required`, which +verifies that object properties exist. Separating these concerns allows for more +reusable components. + +[Annotation](#annotations) results from subschemas are preserved in accordance +with {{collect}} so that applications can decide how to interpret multiple +values. Applicator keywords do not play a direct role in this preservation. + +#### Referenced and Referencing Schemas {#referenced} + +As noted in {{applicators}}, an applicator keyword may refer to a schema to be +applied, rather than including it as a subschema in the applicator's value. In +such situations, the schema being applied is known as the referenced schema, +while the schema containing the applicator keyword is the referencing schema. + +While root schemas and subschemas are static concepts based on a schema's +position within a schema document, referenced and referencing schemas are +dynamic. Different pairs of schemas may find themselves in various referenced +and referencing arrangements during the evaluation of an instance against a +schema. + +For some by-reference applicators, such as [`$ref`](#ref), the referenced schema +can be determined by static analysis of the schema document's lexical scope. +Others, such as `$dynamicRef` (with `$dynamicAnchor`), may make use of dynamic +scoping, and therefore only be resolvable in the process of evaluating the +schema with an instance. + +### Assertions {#assertions} + +JSON Schema can be used to assert constraints on a JSON document, which either +passes or fails the assertions. This approach can be used to validate +conformance with the constraints, or document what is needed to satisfy them. + +JSON Schema implementations produce a single boolean result when evaluating an +instance against schema assertions. + +An instance can only fail an assertion that is present in the schema. + +#### Assertions and Instance Primitive Types + +Most assertions only constrain values within a certain primitive type. When the +type of the instance is not of the type targeted by the keyword, the instance is +considered to conform to the assertion. + +For example, the `maxLength` keyword will only restrict certain strings (that +are too long) from being valid. If the instance is a number, boolean, null, +array, or object, then it is valid against this assertion. + +This behavior allows keywords to be used more easily with instances that can be +of multiple primitive types. The companion Validation specification also +includes a `type` keyword which can independently restrict the instance to one +or more primitive types. This allows for a concise expression of use cases such +as a function that might return either a string of a certain length or a null +value: + +```jsonschema +{ + "type": ["string", "null"], + "maxLength": 255 +} +``` + +If `maxLength` also restricted the instance type to be a string, then this would +be substantially more cumbersome to express because the example as written would +not actually allow null values. Each keyword is evaluated separately unless +explicitly specified otherwise, so if `maxLength` restricted the instance to +strings, then including `"null"` in `type` would not have any useful effect. + +### Annotations {#annotations} + +JSON Schema can annotate an instance with information, whenever the instance +validates against the schema object containing the annotation, and all of its +parent schema objects. The information can be a simple value, or can be +calculated based on the instance contents. + +Annotations are attached to specific locations in an instance. Since many +subschemas can be applied to any single location, applications may need to +decide how to handle differing annotation values being attached to the same +instance location by the same schema keyword in different schema objects. + +Unlike assertion results, annotation data can take a wide variety of forms, +which are provided to applications to use as they see fit. JSON Schema +implementations are not expected to make use of the collected information on +behalf of applications. + +Unless otherwise specified, a keyword's annotation value is value of the +keyword itself. However, other behaviors are possible. For example, [JSON +Hyper-Schema's](https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-hyperschema-02) +`links` keyword is a complex annotation that produces a value based in part on +the instance data. + +While "short-circuit" evaluation is possible for assertions, collecting +annotations requires examining all schemas that apply to an instance location, +even if they cannot change the overall assertion result. The only exception is +that subschemas of a schema object that has failed validation MAY be skipped, as +annotations are not retained for failing schemas. + +#### Collecting Annotations {#collect} + +Annotations are collected by keywords that explicitly define +annotation-collecting behavior. Note that boolean schemas cannot produce +annotations as they do not make use of keywords. + +A collected annotation MUST include the following information: + +- The name of the keyword that produces the annotation +- The instance location to which it is attached, as a JSON Pointer +- The evaluation path, indicating how reference keywords such as `$ref` were + followed to reach the absolute schema location. +- The absolute schema location of the attaching keyword, as a IRI. This MAY be + omitted if it is the same as the evaluation path from above. +- The attached value(s) + +##### Distinguishing Among Multiple Values + +Applications MAY make decisions on which of multiple annotation values to use +based on the schema location that contributed the value. This is intended to +allow flexible usage. Collecting the schema location facilitates such usage. + +For example, consider this schema, which uses annotations and assertions from +the [Validation specification](./jsonschema-validation.md): + +Note that some lines are wrapped for clarity. + +```jsonschema +{ + "title": "Feature list", + "type": "array", + "prefixItems": [ + { + "title": "Feature A", + "properties": { + "enabled": { + "$ref": "#/$defs/enabledToggle", + "default": true + } + } + }, + { + "title": "Feature B", + "properties": { + "enabled": { + "description": "If set to null, Feature B + inherits the enabled + value from Feature A", + "$ref": "#/$defs/enabledToggle" + } + } + } + ], + "$defs": { + "enabledToggle": { + "title": "Enabled", + "description": "Whether the feature is enabled (true), + disabled (false), or under + automatic control (null)", + "type": ["boolean", "null"], + "default": null + } + } +} +``` + +In this example, both Feature A and Feature B make use of the re-usable +"enabledToggle" schema. That schema uses the `title`, `description`, and +`default` annotations. Therefore the application has to decide how to handle the +additional `default` value for Feature A, and the additional `description` value +for Feature B. + +The application programmer and the schema author need to agree on the usage. For +this example, let's assume that they agree that the most specific `default` +value will be used, and any additional, more generic `default` values will be +silently ignored. Let's also assume that they agree that all `description` text +is to be used, starting with the most generic, and ending with the most +specific. This requires the schema author to write descriptions that work when +combined in this way. + +The application can use the evaluation path to determine which values are which. +The values in the feature's immediate "enabled" property schema are more +specific, while the values under the re-usable schema that is referenced to with +`$ref` are more generic. The evaluation path will show whether each value was +found by crossing a `$ref` or not. + +Feature A will therefore use a default value of true, while Feature B will use +the generic default value of null. Feature A will only have the generic +description from the "enabledToggle" schema, while Feature B will use that +description, and also append its locally defined description that explains how +to interpret a null value. + +Note that there are other reasonable approaches that a different application +might take. For example, an application may consider the presence of two +different values for `default` to be an error, regardless of their schema +locations. + +##### Annotations and Assertions {#annot-assert} + +Schema objects that produce a false assertion result MUST NOT produce any +annotation results, whether from their own keywords or from keywords in +subschemas. + +Note that the overall schema results may still include annotations collected +from other schema locations. Given this schema: + +```jsonschema +{ + "oneOf": [ + { + "title": "Integer Value", + "type": "integer" + }, + { + "title": "String Value", + "type": "string" + } + ] +} +``` + +Against the instance `"This is a string"`, the title annotation "Integer Value" +is discarded because the type assertion in that schema object fails. The title +annotation "String Value" is kept, as the instance passes the string type +assertions. + +### Reserved Locations + +A fourth category of keywords simply reserve a location to hold re-usable +components or data of interest to schema authors that is not suitable for +re-use. These keywords do not affect validation or annotation results. Their +purpose is to ensure that locations are available for certain purposes and will +not be redefined by extension keywords. + +While these keywords do not directly affect results, as explained in +{{non-schemas}} unrecognized extension keywords that reserve locations for +re-usable schemas may have undesirable interactions with references in certain +circumstances. + +### Loading Instance Data + +While none of the keywords defined as part of this or the associated +documents define a keyword which target and/or load instance data, it is +possible that extensions may wish to do so. + +Keywords MAY be defined to use JSON Pointers or Relative JSON Pointers to +examine parts of an instance outside the current evaluation location. + +Keywords that allow adjusting the location using a Relative JSON Pointer SHOULD +default to using the current location if a default is desireable. + +## The JSON Schema Core Keywords {#core} + +Keywords declared in this section, which all begin with a dollar sign (`$`), are +essential to processing JSON Schema. These keywords inform implementations how +to process any schema or meta-schema, including those split across multiple +documents, or exist to reserve keywords for purposes that require guaranteed +interoperability. + +Support for these keywords MUST be considered mandatory at all times as they are +necessary to navigate and process any schema. + +The `$` prefix is reserved for use by this specification. Extensions MUST NOT +define new keywords that begin with `$`. + +### Meta-Schemas + +Meta-schemas are used to inform an implementation how to interpret a schema. +Every schema has a meta-schema, which can be explicitly declared using the +`$schema` keyword. + +The meta-schema serves to describe valid schema syntax. A schema resource MUST +successfully validate against its meta-schema, which constrains the syntax of +the available keywords. (See {{compound-validation}} for information on +validating schemas which contain embedded schema resources that declare a +different meta-schema.) The syntax described for a given keyword is expected to +be compatible with the document which defines the keyword; while it is possible +to describe an incompatible syntax, such a meta-schema would be unlikely to be +useful. + +Meta-schema authoring is an advanced usage of JSON Schema, so the design of +meta-schema features emphasizes flexibility over simplicity. + +#### Dialect Determination + +When evaluation encounters a new schema resource (i.e. the lexical scope +changes), the first task is to determine the dialect used by the schema. +Implementations MUST determine the dialect using the following prioritized +steps. + +1. The `$schema` keyword - Implementations MUST process the schema according to + the dialect it declares. +2. `application/schema+json` media type with a `schema` parameter - + Implementations which support media type parameter inputs MUST process the + schema according to the dialect the parameter declares. A media type will + generally only be available if the schema has been retrieved from an external + source and only applies to the document root. +3. Parent dialect - An embedded schema resource which does not itself contain a + `$schema` keyword MUST be processed using the same dialect as the schema + which contains it. If the schema is embedded in a non-schema document, the + semantics for determining the dialect MAY be determined by any specification + which applies to that document. +4. User configuration - Implementations MAY provide means for the user to + configure the dialect under which a schema should be processed. + +(Note that steps 2 and 3 are mutually exclusive.) + +If the dialect is not specified through one of these methods, the implementation +MUST refuse to process the schema. + +#### The `$schema` Keyword {#keyword-schema} + +The `$schema` keyword is both used as a JSON Schema dialect identifier and as +the identifier of a resource which is itself a JSON Schema, which describes the +set of valid schemas written for this particular dialect. The identified dialect +applies to the resource in which it is declared as well as any embedded schema +resources, unless such a resource itself declares a different dialect by +including the `$schema` keyword with a different value. + +The value of this keyword MUST be an +[IRI](https://www.rfc-editor.org/info/rfc3987) (containing a scheme) and this +IRI MUST be normalized. + +If this IRI identifies a retrievable resource, that resource SHOULD be of media +type `application/schema+json`. + +The `$schema` keyword SHOULD be used in the document root schema object, and MAY +be used in the root schema objects of embedded schema resources. This keyword +MUST NOT appear in a subschema that is not also the root object of a schema +resource (see {{id-keyword}} for more information regarding defining embedded +schema resources.) + +Values for this property are defined elsewhere in this and other documents, and +by other parties. + +### Base IRI, Anchors, and Dereferencing + +To differentiate between schemas in a vast ecosystem, schema resources are +identified by +[absolute IRIs](https://www.rfc-editor.org/rfc/rfc3987.html#section-2.2) +(without fragments). These identifiers are used to create references between +schema resources. When comparing IRIs for the purposes of resource +identification, implementations SHOULD first follow the IRI normalization +procedures defined in [RFC 3987][rfc3987], section 5.3. + +Several keywords can accept a relative IRI reference, or a value +used to construct a relative IRI reference. For these keywords, it is necessary +to establish a base IRI in order to resolve the reference. + +#### The `$id` Keyword {#id-keyword} + +An `$id` keyword in a schema or subschema identifies that schema or subschema as +a distinct schema resource and applies to the entire lexical scope of that +schema resource. The value for this keyword MUST be a string, and MUST represent +a valid IRI reference without a fragment. + +When the value of this keyword is resolved against the current base IRI, the +resulting absolute IRI then serves as the identifier for the schema resource and +as a base IRI for relative IRI references in keywords within that schema +resource and for embedded schema resources, in accordance with [RFC 3987 section +6.5](https://www.rfc-editor.org/rfc/rfc3987.html#section-6.5) and +[RFC 3986 section 5.1.1](https://www.rfc-editor.org/rfc/rfc3986.html#section-5.1.1) +regarding base IRIs embedded in content and RFC 3986 section 5.1.2 regarding +encapsulating entities. + +Note that this IRI is an identifier and not necessarily a network locator. In +the case of a network-addressable URL, a schema need not be downloadable from +its canonical IRI. + +Also note that an `$id` consisting of an empty IRI only will result in the +embedded resource having the same IRI as the encapsulating resource, which +SHOULD be considered an error per {{duplicate-iris}}. + +If no parent schema object explicitly identifies itself as a resource with +`$id`, the base IRI is that of the entire document, as established by the steps +given in {{initial-base}}. + +##### Identifying the root schema + +The root schema of a JSON Schema document SHOULD contain an `$id` keyword with +an [absolute IRI](https://www.rfc-editor.org/rfc/rfc3987.html#section-2.2) +(containing a scheme, but no fragment). + +#### Defining location-independent identifiers {#anchors} + +Using JSON Pointers in IRI fragments to reference subschemas couples the IRI to +the structure of the schema. Using plain name fragment identifiers in IRI +fragments to identify subschemas is sometimes preferable because it is not tied +to a particular structural location. This allows a subschema to be relocated +without requiring references to be updated. + +The `$anchor` and `$dynamicAnchor` keywords are used to define +location-independent identifiers for subschemas within a schema resource. + +`$anchor` defines a plain name fragment identifier that can be used in IRI +fragments as an alternative to JSON Pointers.[^4] See {{fragments}}. + +[^4]: Note that the anchor string does not include the "#" character, as it is +just a fragment identifier not an IRI reference. To reference the "foo" +`$anchor` from the same schema resource, you would use the fragment-only IRI +`#foo`. See below for full examples. + +`$dynamicAnchor` defines a different kind of fragment identifier that only has +meaning when used with `$dynamicRef`. It's not a normal fragment identifier and +therefore can't be used anywhere other than `$dynamicRef`. Normal [fragment +identifiers](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) identify the +secondary resource (the subschema) while the rest of the IRI identifies the +primary resource (the schema resource). The fragment identifiers defined by +`$dynamicAnchor` are not normal fragment identifies because they identify both +the primary resource and the secondary resource. See {{dynamic-ref}} for +details. + +If present, the value of these keywords MUST be a string and MUST conform to the +plain name fragment identifier syntax defined in {{fragments}}. + +#### Duplicate schema identifiers {#duplicate-iris} + +A schema MAY (and likely will) have multiple IRIs, but there is no way for an +IRI to identify more than one schema. When multiple schemas attempt to identify +as the same IRI through the use of `$id`, `$anchor`, `$dynamicAnchor`, or any +other mechanism, implementations SHOULD raise an error condition. Otherwise the +result is undefined, and even if documented will not be interoperable. + +#### Schema References {#references} + +`$ref` and `$dynamicRef` can be used to reference a schema which is to be +applied to the current instance location. As such, they are considered +applicators, applying the referenced schema to the instance. + +##### Direct References with `$ref` {#ref} + +The `$ref` keyword is an applicator that is used to reference a statically +identified schema. Its results are the results of the referenced schema.[^5] + +[^5]: Note that this definition of how the results are determined means that +other keywords can appear alongside of `$ref` in the same schema object. + +The value of the `$ref` keyword MUST be a string which is an IRI reference. +Resolved against the current IRI base, it produces the IRI of the schema to +apply. This resolution is safe to perform on schema load, as the process of +evaluating an instance cannot change how the reference resolves. + +The resolved IRI produced by `$ref` is not necessarily a network locator, only +an identifier. A schema need not be downloadable from the address if it is a +network-addressable URL. Implementations which can access the network SHOULD +default to operating offline. + +##### Dynamic References with `$dynamicRef` {#dynamic-ref} + +The `$dynamicRef` keyword is an applicator that is used when the referencing +schema might need to override where a reference in the referenced schema will +resolve. This is useful for cases such as authoring a recursive schema that can +be extended or a generic schema such as a list whose items are defined by the +referencing schema. + +The value of the `$dynamicRef` property MUST be formatted as a valid +[fragment-only IRI](#fragments).[^3] + +[^3]: `$dynamicAnchor` defines the anchor with plain text, e.g. `foo`. Although, +for historical reasons, the value of `$dynamicRef` still uses a fragment-only +IRI syntax, e.g. `#foo`. + +Resolution of `$dynamicRef` begins by identifying the outermost schema resource +in the [dynamic scope](#scopes) which defines a matching `$dynamicAnchor`. The +schema to apply is the subschema of this resource which contains the matching +`$dynamicAnchor`. If no matching `$dynamicAnchor` is found, see {{failed-refs}}. + +For a full example using these keywords, see {{dynamic-example}}.[^6] + +[^6]: The differences in the hyper-schema meta-schemas from draft-07 and draft +2019-09 dramatically demonstrates the utility of these keywords. + +#### Schema Re-Use With `$defs` {#defs} + +The `$defs` keyword reserves a location for schema authors to inline re-usable +JSON Schemas into a more general schema. The keyword does not directly affect +the validation result. + +This keyword's value MUST be an object. Each member value of this object MUST be +a valid JSON Schema. + +As an example, here is a schema describing an array of positive integers, where +the positive integer constraint is a subschema in `$defs`: + +```jsonschema +{ + "type": "array", + "items": { "$ref": "#/$defs/positiveInteger" }, + "$defs": { + "positiveInteger": { + "type": "integer", + "exclusiveMinimum": 0 + } + } +} +``` + +### Comments With `$comment` + +This keyword reserves a location for comments from schema authors to readers or +maintainers of the schema. + +The value of this keyword MUST be a string. Implementations MUST NOT present +this string to end users. Tools for editing schemas SHOULD support displaying +and editing this keyword. The value of this keyword MAY be used in debug or +error output which is intended for developers making use of schemas. + +Tools that translate other media types or programming languages to and from +`application/schema+json` MAY choose to convert that media type or programming +language's native comments to or from `$comment` values. The behavior of such +translation when both native comments and `$comment` properties are present is +implementation-dependent. + +Implementations MAY strip `$comment` values at any point during processing. In +particular, this allows for shortening schemas when the size of deployed schemas +is a concern. + +Implementations MUST NOT take any other action based on the presence, absence, +or contents of `$comment` properties. In particular, the value of `$comment` +MUST NOT be collected as an annotation result. + +## Loading and Processing Schemas + +### Loading a Schema + +#### Initial Base IRI {#initial-base} + +[RFC 3987 Section 6.5](https://www.rfc-editor.org/rfc/rfc3987.html#section-6.5) +and +[RFC 3986 Section 5.1](https://www.rfc-editor.org/rfc/rfc3986.html#section-5.1) +defines how to determine the default base IRI of a document. + +Informatively, the initial base IRI of a schema is the IRI at which it was +found, whether that was a network location, a local filesystem, or any other +situation identifiable by a IRI of any known scheme. + +If a schema document defines no explicit base IRI with `$id` (embedded in +content), the base IRI is that determined per RFC 3987 Section 6.5 +and RFC 3986 section 5. + +If no source is known, or no IRI scheme is known for the source, a suitable +implementation-specific default IRI MAY be used as described in RFC 3987 Section +6.5 and RFC 3986 Section 5.1.4. It is RECOMMENDED that implementations document +any default base IRI that they assume. + +If a schema object is embedded in a document of another media type, then the +initial base IRI is determined according to the rules of that media type. + +Unless the `$id` keyword described in an earlier section is present in the root +schema, this base IRI SHOULD be considered the canonical IRI of the schema +document's root schema resource. + +#### Loading a referenced schema + +The use of IRIs to identify remote schemas does not necessarily mean anything is +downloaded, but instead JSON Schema implementations SHOULD understand ahead of +time which schemas they will be using, and the IRIs that identify them. + +Implementations SHOULD be able to associate arbitrary IRIs with an arbitrary +schema and/or automatically associate a schema's `$id`-given IRI, depending on +the trust that the validator has in the schema. Such IRIs and schemas can be +supplied to an implementation prior to processing instances, or may be noted +within a schema document as it is processed, producing associations as shown in +{{idexamples}}. + +Implementations MAY provide functionality to automatically fetch schemas based +on location semantics expressed by the IRI, however such functionality SHOULD be +disabled by default to prefer offline operation. When schemas are downloaded, +for example by a generic user-agent that does not know until runtime which +schemas to download, see {{hypermedia}}. + +#### Detecting a Meta-Schema + +Implementations MUST recognize a schema as a meta-schema if it is being examined +because it was identified as such by another schema's `$schema` keyword. This +means that a single schema document might sometimes be considered a regular +schema, and other times be considered a meta-schema. + +In the case of examining a schema which is its own meta-schema, when an +implementation begins processing it as a regular schema, it is processed under +those rules. However, when loaded a second time as a result of checking its own +`$schema` value, it is treated as a meta-schema. So the same document is +processed both ways in the course of one session. + +Implementations MAY allow a schema to be explicitly passed as a meta-schema, for +implementation-specific purposes, such as pre-loading a commonly used +meta-schema and checking its requirements up front. Meta-schema authors MUST NOT +expect such features to be interoperable across implementations. + +### Dereferencing + +Schemas can be identified by any IRI that has been given to them, including a +JSON Pointer or their IRI given directly by `$id`. In all cases, dereferencing a +`$ref` reference involves first resolving its value as a IRI reference against +the current base IRI per [RFC 3986][rfc3986]. + +If the resulting IRI identifies a schema within the current document, or within +another schema document that has been made available to the implementation, then +that schema SHOULD be used automatically. + +For example, consider this schema: + +```jsonschema +{ + "$id": "https://example.net/root.json", + "type": "array", + "items": { "$ref": "#item" }, + "$defs": { + "single": { + "$anchor": "item", + "type": "object", + "additionalProperties": { "$ref": "other.json" } + } + } +} +``` + +When an implementation encounters the `#/$defs/single` schema, it resolves the +`$anchor` value as a fragment name against the current base IRI to form +`https://example.net/root.json#item`. + +When an implementation then looks inside the `#/items` schema, it encounters the +`#item` reference, and resolves this to `https://example.net/root.json#item`, +which it has seen defined in this same document and can therefore use +automatically. + +When an implementation encounters the reference to "other.json", it resolves +this to `https://example.net/other.json`, which is not defined in this document. +If an implementation has been configured to resolve that identifier to a schema +via pre-loading or other means, it can be used automatically; otherwise, the +behavior described in {{failed-refs}} MUST be used. + +#### JSON Pointer fragment identifiers and embedded schema resources {#embedded} + +Since JSON Pointer fragment identifiers are based on the structure of the schema +document, an embedded schema resource and its subschemas can be identified using +JSON Pointer IRI fragments relative to either its own IRI, or relative to any +containing resource's IRI. + +Conceptually, a set of linked schema resources should behave identically whether +each resource is a separate document connected with [schema +references](#referenced), or is structured as a single document with one or more +schema resources embedded as subschemas. + +Since IRIs with JSON Pointer fragments are relative to the parent schema +resource's IRI, they cease to be valid when the embedded schema is moved to a +separate document and referenced. Because of this, applications and schemas +SHOULD NOT use such IRIs to identify embedded schema resources or locations +within them. + +Consider the following schema document that contains another schema resource +embedded within it: + +```jsonschema +{ + "$id": "https://example.com/foo", + "items": { + "$id": "https://example.com/bar", + "additionalProperties": { } + } +} +``` + +The IRI `https://example.com/foo#/items` points to the `items` schema, which is +an embedded resource. The canonical IRI of that schema resource, however, is +`https://example.com/bar`. + +For the `additionalProperties` schema within that embedded resource, the IRI +`https://example.com/foo#/items/additionalProperties` points to the correct +object, but that object's IRI relative to its resource's canonical IRI is +`https://example.com/bar#/additionalProperties`. + +Now consider the following two schema resources linked by reference using an IRI +value for `$ref`: + +```jsonschema +{ + "$id": "https://example.com/foo", + "items": { + "$ref": "bar" + } +} +``` + +```jsonschema +{ + "$id": "https://example.com/bar", + "additionalProperties": {} +} +``` + +Here we see that `https://example.com/bar#/additionalProperties`, using a JSON +Pointer fragment identifier appended to the canonical IRI of the "bar" schema +resource, is still valid, while +`https://example.com/foo#/items/additionalProperties`, which relied on a JSON +Pointer fragment identifier appended to the canonical IRI of the "foo" schema +resource, no longer resolves to anything. + +Note also that `https://example.com/foo#/items` is valid in both arrangements, +but resolves to a different value. This IRI ends up functioning similarly to a +retrieval IRI for a resource. While this IRI is valid, it is more robust to use +the `$id` of the embedded or referenced resource unless it is specifically +desired to identify the object containing the `$ref` in the second +(non-embedded) arrangement. + +Due to the potential break in functionality described above, the behavior for +using JSON Pointer fragments that point to or cross a resource boundary is +undefined. Schema authors SHOULD NOT rely on such IRIs, as using them may +reduce interoperability.[^8] + +[^8]: This is to avoid requiring implementations to keep track of a whole stack + of possible base IRIs and JSON Pointer fragment identifiers for each, given +that all but one will be fragile if the schema resources are reorganized. Some +have argued that this is easy so there is no point in forbidding it, while +others have argued that it complicates schema identification and should be +forbidden. Feedback on this topic is encouraged. After some discussion, we feel +that we need to remove the use of "canonical" in favour of talking about JSON +Pointers which reference across schema resource boundaries as undefined or even +forbidden behavior +(, +) + +Further examples of such non-canonical IRI construction, as well as the +appropriate canonical IRI-based fragments to use instead, are provided in +{{idexamples}}. + +### Compound Documents + +A Compound Schema Document is defined as a JSON document (sometimes called a +"bundled" schema) which has multiple embedded JSON Schema Resources bundled into +the same document to ease transportation. + +Each embedded Schema Resource MUST be treated as an individual Schema Resource, +following standard schema loading and processing requirements, including +determining keyword support. + +#### Bundling + +The bundling process for creating a Compound Schema Document is defined as +taking references (such as `$ref`) to an external Schema Resource and embedding +the referenced Schema Resources within the referring document. Bundling SHOULD +be done in such a way that all IRIs (used for referencing) in the base document +and any referenced/embedded documents do not require altering. + +Each embedded JSON Schema Resource MUST identify itself with a IRI using the +`$id` keyword, and SHOULD make use of the `$schema` keyword to identify the +dialect it is using, in the root of the schema resource. It is RECOMMENDED that +the IRI identifier value of `$id` be an Absolute IRI. + +When the Schema Resource referenced by a by-reference applicator is bundled, it +is RECOMMENDED that the Schema Resource be located as a value of a `$defs` +object at the containing schema's root. The key of the `$defs` for the now +embedded Schema Resource MAY be the `$id` of the bundled schema or some other +form of application defined unique identifier (such as a UUID). This key is not +intended to be referenced in JSON Schema, but may be used by an application to +aid the bundling process. + +A Schema Resource MAY be embedded in a location other than `$defs` where the +location is defined as a schema value. + +A Bundled Schema Resource MUST NOT be bundled by replacing the schema object +from which it was referenced, or by wrapping the Schema Resource in other +applicator keywords. + +In order to produce identical output, references in the containing schema +document to the previously external Schema Resources MUST NOT be changed, and +now resolve to a schema using the `$id` of an embedded Schema Resource. Such +identical output includes validation evaluation and IRIs or paths used in +resulting annotations or errors. + +While the bundling process will often be the main method for creating a Compound +Schema Document, it is also possible and expected that some will be created by +hand, potentially without individual Schema Resources existing on their own +previously. + +#### Differing and Default Dialects + +When multiple schema resources are present in a single document, schema +resources which do not define with which dialect they should be processed MUST +be processed with the same dialect as the enclosing resource. + +Since any schema that can be referenced can also be embedded, embedded schema +resources MAY specify different processing dialects using the `$schema` values +from their enclosing resource. + +#### Validating {#compound-validation} + +Given that a Compound Schema Document may have embedded resources which identify +as using different dialects, these documents SHOULD NOT be validated by applying +a meta-schema to the Compound Schema Document as an instance. It is RECOMMENDED +that an alternate validation process be provided in order to validate Schema +Documents. Each Schema Resource SHOULD be separately validated against its +associated meta-schema.[^9] + +[^9]: If you know a schema is what's being validated, you can identify if the +schemas is a Compound Schema Document or not, by way of use of `$id`, which +identifies an embedded resource when used not at the document's root. + +A Compound Schema Document in which all embedded resources identify as using the +same dialect, or in which `$schema` is omitted and therefore defaults to that of +the enclosing resource, MAY be validated by applying the appropriate +meta-schema. + +### Caveats + +#### Guarding Against Infinite Recursion + +A schema MUST NOT be run into an infinite loop against an instance. For example, +if two schemas `#alice` and `#bob` both have an `allOf` property that refers to +the other, a naive validator might get stuck in an infinite recursive loop +trying to validate the instance. Schemas SHOULD NOT make use of infinite +recursive nesting like this; the behavior is undefined. + +#### References to Possible Non-Schemas {#non-schemas} + +Subschema objects (or booleans) are recognized by their use with known +applicator keywords or with location-reserving keywords, such as +[`$defs`](#defs), that take one or more subschemas as a value. These keywords +include the standard applicators from this document or implementation-specific +custom keywords. + +A reference target under a keyword for which the value is not explicitly known +to be a schema results in undefined behavior. Implementations MAY support +references to these locations, however such behavior is not considered +interoperable and should not be relied upon.[^10] + +[^10]: These scenarios are analogous to fetching a schema over HTTP but +receiving a response with a Content-Type other than `application/schema+json`. +An implementation can certainly try to interpret it as a schema, but the origin +server offered no guarantee that it actually is any such thing. Therefore, +interpreting it as such has security implication and may produce unpredictable +results. + +#### Failure to resolve references {#failed-refs} + +If for any reason a reference cannot be resolved, the evaluation MUST halt and +return an indeterminant result. Specifically, it MUST NOT return a passing or +failing validation result or any annotations. Instead it MUST inform the +consuming application or user of the evaluation failure via other means. It is +RECOMMENDED that implementations utilize native functionality for this purpose, +such as, but not limited to, raising an exception or other error. + +In the cases where optimizations are enabled and a schema containing a +non-resolvable reference would be skipped, as in the example below, behavior is +implementation-defined. + +```json +{ + "anyOf": [ + true, + { "$ref": "https://json-schema.org/does-not-exist" } + ] +} +``` + +Here, an optimized evaluation may recognize that `/anyOf/0` will satisfy the +`anyOf` constraint, regardless of the validation result of `/anyOf/1`, and so +`/anyOf/1` may be skipped altogether. + +However, an unoptimized evaluation of this schema (for example one that expects +all annotation results), would result in a resolution failure. + +### Associating Instances and Schemas + +#### Usage for Hypermedia {#hypermedia} + +JSON has been adopted widely by HTTP servers for automated APIs and robots. This +section describes how to enhance processing of JSON documents in a more RESTful +manner when used with protocols that support media types and [Web +linking][rfc8288]. + +##### Linking to a Schema + +It is RECOMMENDED that instances described by a schema provide a link to a +downloadable JSON Schema using the link relation "describedby", as defined by +[Linked Data Protocol 1.0, section 8.1](https://www.w3.org/TR/2015/REC-ldp-20150226/#link-relation-describedby). + +In HTTP, such links can be attached to any response using the [Link +header][rfc8288]. An example of such a header would be: + +``` +Link: ; rel="describedby" +``` + +##### Usage Over HTTP + +When used for hypermedia systems over a network, +[HTTP](https://www.rfc-editor.org/info/rfc7231) is frequently the protocol of +choice for distributing schemas. Misbehaving clients can pose problems for +server maintainers if they pull a schema over the network more frequently than +necessary, when it's instead possible to cache a schema for a long period of +time. + +HTTP servers SHOULD set long-lived caching headers on JSON Schemas. HTTP clients +SHOULD observe caching headers and not re-request documents within their +freshness period. Distributed systems SHOULD make use of a shared cache and/or +caching proxy. + +Clients SHOULD set or prepend a User-Agent header specific to the JSON Schema +implementation or software product. Since symbols are listed in decreasing order +of significance, the JSON Schema library name/version should precede the more +generic HTTP library name (if any). For example: + +``` +User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0 +``` + +Clients SHOULD be able to make requests with a "From" header so that server +operators can contact the owner of a potentially misbehaving script. + +## Keywords for Applying Subschemas + +This section defines a set of applicator keywords that enable schema +combinations and composition. + +### Keywords for Applying Subschemas in Place {#in-place} + +These keywords apply subschemas to the same location in the instance as the +parent schema is being applied. They allow combining or modifying the subschema +results in various ways. + +Subschemas of these keywords evaluate the instance completely independently such +that the results of one such subschema MUST NOT impact the results of sibling +subschemas. Therefore subschemas may be applied in any order. + +#### Keywords for Applying Subschemas With Logic {#logic} + +These keywords correspond to logical operators for combining or modifying the +boolean assertion results of the subschemas. They have no direct impact on +annotation collection, although they enable the same annotation keyword to be +applied to an instance location with different values. Annotation keywords +define their own rules for combining such values. + +##### `allOf` {#allof} + +This keyword's value MUST be a non-empty array. Each item of the array MUST be a +valid JSON Schema. + +An instance validates successfully against this keyword if it validates +successfully against all schemas defined by this keyword's value. + +##### `anyOf` + +This keyword's value MUST be a non-empty array. Each item of the array MUST be a +valid JSON Schema. + +An instance validates successfully against this keyword if it validates +successfully against at least one schema defined by this keyword's value. Note +that when annotations are being collected, all subschemas MUST be examined so +that annotations are collected from each subschema that validates successfully. + +##### `oneOf` + +This keyword's value MUST be a non-empty array. Each item of the array MUST be a +valid JSON Schema. + +An instance validates successfully against this keyword if it validates +successfully against exactly one schema defined by this keyword's value. + +##### `not` {#not} + +This keyword's value MUST be a valid JSON Schema. + +An instance is valid against this keyword if it fails to validate successfully +against the schema defined by this keyword. + +#### Keywords for Applying Subschemas Conditionally {#conditional} + +Three of these keywords work together to implement conditional application of a +subschema based on the outcome of another subschema. The fourth is a shortcut +for a specific conditional case. + +`if`, `then`, and `else` MUST NOT interact with each other across subschema +boundaries. In other words, an `if` in one branch of an `allOf` MUST NOT have an +impact on a `then` or `else` in another branch. + +There is no default behavior for `if`, `then`, or `else` when they are not +present. In particular, they MUST NOT be treated as if present with an empty +schema, and when `if` is not present, both `then` and `else` MUST be entirely +ignored. + +##### `if` + +This keyword's value MUST be a valid JSON Schema. + +This validation outcome of this keyword's subschema has no direct effect on the +overall validation result. Rather, it controls which of the `then` or `else` +keywords are evaluated. + +Instances that successfully validate against this keyword's subschema MUST also +be valid against the subschema value of the `then` keyword, if present. + +Instances that fail to validate against this keyword's subschema MUST also be +valid against the subschema value of the `else` keyword, if present. + +If [annotations](#annotations) are being collected, they are collected from this +keyword's subschema in the usual way, including when the keyword is present +without either `then` or `else`. + +##### `then` + +This keyword's value MUST be a valid JSON Schema. + +When `if` is present, and the instance successfully validates against its +subschema, then validation succeeds against this keyword if the instance also +successfully validates against this keyword's subschema. + +This keyword has no effect when `if` is absent, or when the instance fails to +validate against the `if` subschema. Implementations MUST NOT evaluate the +instance against this keyword, for either validation or annotation collection +purposes, in such cases. + +##### `else` + +This keyword's value MUST be a valid JSON Schema. + +When `if` is present, and the instance fails to validate against its subschema, +then validation succeeds against this keyword if the instance successfully +validates against this keyword's subschema. + +This keyword has no effect when `if` is absent, or when the instance +successfully validates against the `if` subschema. Implementations MUST NOT +evaluate the instance against this keyword, for either validation or annotation +collection purposes, in such cases. + +##### `dependentSchemas` {#dependent-schemas} + +This keyword specifies subschemas that are evaluated if the instance is an +object and contains a certain property. + +This keyword's value MUST be an object. Each value in the object MUST be a valid +JSON Schema. + +If the object key is a property in the instance, the entire instance must +validate against the subschema. Its use is dependent on the presence of the +property. + +Omitting this keyword has the same behavior as an empty object. + +### Keywords for Applying Subschemas to Child Instances + +Each of these keywords defines a rule for applying its subschema(s) to child +instances, specifically object properties and array items, and combining their +results. + +#### Keywords for Applying Subschemas to Arrays + +##### Indexing Arrays {#array-index} + +When working with arrays and indices, JSON Schema uses zero-based indexing. This +aligns with both JSON's JavaScript heritage and its usage of JSON Pointer for +references and annotations. + +##### `prefixItems` + +The value of `prefixItems` MUST be a non-empty array of valid JSON Schemas. + +Validation succeeds if each element of the instance validates against the +subschema at the same position, if any. This keyword does not constrain the +length of the array. Only array positions present in both the keyword's value +and the instance value are affected by this keyword. + +This keyword produces an annotation value which is the largest index to which +this keyword applied a subschema. The value MAY be a boolean true if a subschema +was applied to every index of the instance, such as is produced by the `items` +keyword. + +The presence of this keyword affects the behaviors of [`items`](#items) and +[`unevaluatedItems`](#unevaluateditems). + +##### `items` {#items} + +The value of `items` MUST be a valid JSON Schema. + +This keyword ignores elements in the instance array equal to the number of +subschemas found in the `prefixItems` array in the same schema object, starting +from the beginning of the instance array. It then applies its subschema to +remaining elements. + +If `prefixItems` contains more subschemas than the number of elements in the +instance array, `items` applies its subschema to no elements. + +If `prefixItems` does not exist within the same schema object, `items` applies +its subschema to all elements. + +If the `items` subschema is applied to any positions within the instance array, +it produces an annotation result of boolean true, indicating that all remaining +array elements have been evaluated against this keyword's subschema. + +Omitting this keyword has the same assertion behavior as an empty schema. + +The presence of this keyword affects the behavior of +[`unevaluatedItems`](#unevaluateditems). + +#### Keywords for Applying Subschemas to Objects + +##### `properties` + +The value of `properties` MUST be an object. Each value of this object MUST be a +valid JSON Schema. + +Validation succeeds if, for each name that appears in both the instance and as a +name within this keyword's value, the child instance for that name successfully +validates against the corresponding schema. + +Omitting this keyword has the same assertion behavior as an empty object. + +The annotation result of this keyword is the set of instance property names +which are also present under this keyword. + +The presence of this keyword affects the behaviors of +[`additionalProperties`(#additionalProperties) and [`unevaluatedProperties`](#unevaluatedproperties). + +##### `patternProperties` + +The value of `patternProperties` MUST be an object. Each property name of this +object SHOULD be a valid regular expression as indicated in {{regex}}. Each +property value of this object MUST be a valid JSON Schema. + +Validation succeeds if, for each instance name that matches any regular +expressions that appear as a property name in this keyword's value, the child +instance for that name successfully validates against each schema that +corresponds to a matching regular expression. Recall: regular expressions are +not implicitly anchored. + +Omitting this keyword has the same assertion behavior as an empty object. + +The annotation result of this keyword is the set of instance property names +matched by at least one property under this keyword. + +The presence of this keyword affects the behaviors of +[`additionalProperties`(#additionalproperties) and +[`unevaluatedProperties`](#unevaluatedproperties). + +##### `additionalProperties` {#additionalproperties} + +The value of `additionalProperties` MUST be a valid JSON Schema. + +The behavior of this keyword depends on the presence of `properties` and +`patternProperties` within the same schema object. Validation with +`additionalProperties` applies only to the property values for which neither +`properties` nor `patternProperties` apply. + +For all such properties, validation succeeds if the child instance validates +against the `additionalProperties` schema. + +Omitting this keyword has the same assertion behavior as an empty schema. + +The annotation result of this keyword is the set of instance property names +validated by this keyword's subschema. + +The presence of this keyword affects the behavior of +[`unevaluatedProperties`](#unevaluatedproperties). + +##### `propertyNames` + +The value of `propertyNames` MUST be a valid JSON Schema. + +If the instance is an object, this keyword validates if every property name in +the instance validates against the provided schema. Note the property name that +the schema is testing will always be a string. + +Omitting this keyword has the same behavior as an empty schema. + +#### Other Keywords for Applying Subschemas + +##### `maxContains` + +The value of this keyword MUST be a non-negative integer. + +This keyword modifies the behavior of `contains` within the same schema object, +as described below in the section for that keyword. + +This keyword produces no assertion result. The value of this keyword is used as +its annotation result. + +##### `minContains` + +The value of this keyword MUST be a non-negative integer. + +This keyword modifies the behavior of `contains` within the same schema object, +as described below in the section for that keyword. + +This keyword has no assertion behavior. The value of this keyword is used as +its annotation result. + +Per {{default-behaviors}}, omitted keywords MUST NOT produce annotation results. +However, as described in {{contains}}, the absence of this keyword's annotation +causes `contains` to assume a minimum value of 1. + +##### `contains` {#contains} + +The value of this keyword MUST be a valid JSON Schema. + +This keyword applies to array instances by applying its subschema to the array's +elements. + +An instance is valid against `contains` if the number of elements that are valid +against its subschema is within the inclusive range of the minimum and (if any) +maximum number of occurrences. + +The maximum number of occurrences is provided by the `maxContains` keyword +within the same schema object as `contains`. If `maxContains` is absent, the +maximum number of occurrences MUST be unbounded. + +The minimum number of occurrences is provided by the `minContains` keyword +within the same schema object as `contains`. If `minContains` is absent, the +minimum number of occurrences MUST be 1. + +This keyword produces an annotation value which is an array of the zero-based +indices for which this keyword validates successfully when applying its +subschema, in ascending order. The value MAY be a boolean `true` if the +subschema validates successfully when applied to every index of the instance. +The annotation MUST be present if the instance array to which this keyword's +schema applies is empty. + +The presence of this keyword affects the behavior of +[`unevaluatedItems`](#unevaluateditems). + +Under most circumstances, the `contains` subschema MAY be short-circuited. +However, for the following cases, the `contains` subschema MUST be applied to +every array element. + +- If `unevaluatedItems` appears in any subschema in the dynamic scope that + applies to the same instance location, to ensure that all evaluated items are + accounted for. +- When collecting annotations, to ensure that all annotations are found. + +## Keywords for Unevaluated Locations {#unevaluated} + +The purpose of these keywords is to enable schema authors to apply subschemas to +array items or object properties that have not been successfully evaluated +against any dynamic-scope subschema of any adjacent keywords. + +These instance items or properties may have been unsuccessfully evaluated +against one or more adjacent keyword subschemas, such as when an assertion in a +branch of an `anyOf` fails. Such failed evaluations are not considered to +contribute to whether or not the item or property has been evaluated. Only +successful evaluations are considered. + +If an item in an array or an object property is "successfully evaluated", it is +logically considered to be valid in terms of the representation of the object or +array that's expected. For example if a subschema represents a car, which +requires between 2-4 wheels, and the value of "wheels" is 6, the instance object +is not "evaluated" to be a car, and thus the "wheels" property is considered +"unevaluated". + +Recall that adjacent keywords are keywords within the same schema object, and +that the dynamic-scope subschemas include reference targets as well as lexical +subschemas. + +The behaviors of these keywords depend on adjacent keywords as well as any +keywords in successfully validated subschemas that apply to the same instance +location. + +### `unevaluatedItems` {#unevaluateditems} + +The value of `unevaluatedItems` MUST be a valid JSON Schema. + +This keyword applies to array instances by applying its subschema to the array's +elements. + +The behavior of this keyword depends on all adjacent keywords as well as +keywords in successfully validated subschemas that apply to the same instance +location by evaluating the instance's elements. This includes, but is not +limited to, `prefixItems`, `items`, and `contains`, itself, and all +[in-place applicators](#in-place) defined in this document. + +This keyword applies its subschema to any array elements which have not been +deemed "evaluated" per {{unevaluated}}. Validation passes if the keyword's +subschema validates against all applicable array elements. + +If the `unevaluatedItems` subschema is applied to any positions within the +instance array, it produces an annotation result of boolean true, analogous to +the behavior of `items`. + +The presence of this keyword affects the behavior of other `unevaluatedItems` +keywords found earlier in the dynamic scope that apply to the same instance +location. + +Omitting this keyword has the same assertion behavior as an empty schema. + +### `unevaluatedProperties` {#unevaluatedproperties} + +The value of `unevaluatedProperties` MUST be a valid JSON Schema. + +This keyword applies to object instances by applying its subschema to the +object's property values. + +The behavior of this keyword depends on all adjacent keywords as well as +keywords in successfully validated subschemas that apply to the same instance +location by evaluating the instance's property values. This includes, but is not +limited to, `properties`, `patternProperties`, and `additionalProperties`, +itself, and all [in-place applicators](#in-place) defined in this document. + +This keyword applies its subschema to any property values which have not been +deemed "evaluated" per {{unevaluated}}. Validation passes if the keyword's +subschema validates against all applicable property values. + +The annotation result of this keyword is the set of instance property names +validated by this keyword's subschema. + +The presence of this keyword affects the behavior of other +`unevaluatedProperties` keywords found earlier in the dynamic scope that apply +to the same instance location. + +Omitting this keyword has the same assertion behavior as an empty schema. + +## Output Formatting {#output} + +In order to foster increased usability and interoperability, implementations +SHOULD adhere to well-defined output formats. + +Because JSON Schema has multiple uses cases, and those uses cases have different +intended consumers, this specification defers the details of any output formats +to other documents. Implementations are encouraged to support multiple output +formats as required by their target user base. + +The scope of this section, therefore, is limited to defining common terms that +SHOULD be used in JSON Schema output specifications in order to align the +vernacular across differing formats. Output specifications which use this +information MUST use this terminology to describe it. Conversely, output +specifications which use these terms MUST maintain their meaning. + +### Evaluation path + +The evaluation path is the set of keys, starting from the schema root, through +which evaluation passes to reach the schema object that produced a specific +result. The value MUST be expressed as a JSON Pointer, and it MUST include any +by-reference applicators such as `$ref` or `$dynamicRef`. + +``` +/properties/width/$ref/allOf/1 +``` + +Note that this pointer may not be resolvable on the root schema by the normal +JSON Pointer process. It is intended as an indication of the traversal path +only. + +When represented in JSON, the key for this information MUST be "evaluationPath". + +### Schema Location + +The schema location is the canonical URI of the schema object plus a JSON +Pointer fragment indicating the subschema that produced a result. In contrast +with the evaluation path, the schema location MUST NOT include by-reference +applicators such as `$ref` or `$dynamicRef`. + +``` +https://example.com/schemas/common#/$defs/allOf/1 +``` + +### Instance Location + +The instance location is the location of the JSON value within the root instance +being validated. The value MUST be expressed as a JSON Pointer. + +### Errors + +Errors are textual representations of individual validation failures, often +intended for human consumers. This specification contains no requirements for +the content of these errors. + +Output specifications which include errors SHOULD be written such that the +sources (schema and instance) of a given error is easily identifiable and SHOULD +use the terms defined by this document to do so. + +### Annotations + +Many keywords are defined to produce annotations, whether intended for +inter-keyword communication (e.g. between `properties` and +`unevaluatedProperties`) or for application consumption (e.g. `title` or +`readOnly`). Annotation values may be of any type and are defined by the +keywords that produced them. + +Output specifications which include annotations SHOULD be written such that they +can be easily associated with the data defined in {{collect}} and SHOULD use the +terms defined by this document to do so. + +### Dropped Annotations + +A dropped annotation is any annotation produced and subsequently dropped by the +evaluation due to an unsuccessful validation result of the containing subschema. +This information MAY be included if the validation result of the containing +subschema was unsuccessful. It MUST NOT be included if the local validation +result of the containing subschema was successful. + +As the intended purpose for including these annotations is debugging, +implementations that wish to provide dropped annotations SHOULD NOT provide them +as their default behavior. Dropped annotations SHOULD only be included when the +implementation is explicitly configured to do so or if the implementation is +specifically intended to be used as a debugging tool. + +Output specifications which include dropped annotations SHOULD be written such +that they can be easily associated with the data defined in {{collect}} and +SHOULD use the terms defined by this document to do so. + +## Security Considerations {#security} + +Both schemas and instances are JSON values. As such, all security considerations +defined in [RFC 8259][rfc8259] apply. + +Instances and schemas are both frequently written by untrusted third parties, to +be deployed on public Internet servers. Implementations should take care that +the parsing and evaluating against schemas does not consume excessive system +resources. Implementations MUST NOT fall into an infinite loop. + +A malicious party could cause an implementation to repeatedly collect a copy of +a very large value as an annotation. Implementations SHOULD guard against +excessive consumption of system resources in such a scenario. + +Servers MUST ensure that malicious parties cannot change the functionality of +existing schemas by uploading a schema with a pre-existing or very similar +`$id`. + +Individual JSON Schema extensions are liable to also have their own security +considerations. Consult the respective specifications for more information. + +Schema authors should take care with `$comment` contents, as a malicious +implementation can display them to end-users in violation of a spec, or fail to +strip them if such behavior is expected. + +A malicious schema author could place executable code or other dangerous +material within a `$comment`. Implementations MUST NOT parse or otherwise take +action based on `$comment` contents. + +## IANA Considerations + +### `application/schema+json` + +The proposed MIME media type for JSON Schema is defined as follows: + +Type name:: application + +Subtype name:: schema+json + +Required parameters:: N/A + +Encoding considerations:: Encoding considerations are identical to those +specified for the `application/json` media type. See [JSON][rfc8259]. + +Security considerations:: See {{security}} above. + +Interoperability considerations:: See Sections [6.2](#language), +[6.3](#data-model), and [6.4](#regex) above. + +Fragment identifier considerations:: See {{fragments}} + +### `application/schema-instance+json` + +The proposed MIME media type for JSON Schema Instances that require a JSON +Schema-specific media type is defined as follows: + +Type name:: application + +Subtype name:: schema-instance+json + +Required parameters:: N/A + +Encoding considerations:: Encoding considerations are identical to those +specified for the `application/json` media type. See [JSON][rfc8259]. + +Security considerations:: See {{security}} above. + +Interoperability considerations:: See Sections [6.2](#language), +[6.3](#data-model), and [6.4](#regex) above. + +Fragment identifier considerations:: See {{fragments}} + +## %appendix% Schema identification examples {#idexamples} + +Consider the following schema, which shows `$id` being used to identify both the +root schema and various subschemas, and `$anchor` being used to define plain +name fragment identifiers. + +```jsonschema +{ + "$id": "https://example.com/root.json", + "$defs": { + "A": { "$anchor": "foo" }, + "B": { + "$id": "other.json", + "$defs": { + "X": { "$anchor": "bar" }, + "Y": { + "$id": "t/inner.json", + "$anchor": "bar" + } + } + }, + "C": { + "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f" + } + } +} +``` + +The schemas at the following locations (indicated by plain +[JSON Pointers][rfc6901] relative to the root document) have the following base +IRIs, and are identifiable by any listed IRI in accordance with {{fragments}} +and {{embedded}} above. + +Document root: +- canonical (and base) IRI: `https://example.com/root.json` +- canonical resource IRI plus pointer fragment: `https://example.com/root.json#` + +Document location `/$defs/A`: +- base IRI: `https://example.com/root.json` +- canonical resource IRI plus plain fragment: + `https://example.com/root.json#foo` +- canonical resource IRI plus pointer fragment: + `https://example.com/root.json#/$defs/A` + +Document location `/$defs/B`: +- canonical (and base) `IRI: https://example.com/other.json` +- canonical resource IRI plus pointer fragment: + `https://example.com/other.json#` + +Document location `/$defs/B/$defs/X`: +- base IRI: `https://example.com/other.json` +- canonical resource IRI plus plain fragment: + `https://example.com/other.json#bar` +- canonical resource IRI plus pointer fragment: + `https://example.com/other.json#/$defs/X` + +Document location `/$defs/B/$defs/Y`: +- canonical (and base) IRI: +`https://example.com/t/inner.json` +- canonical IRI plus plain fragment: `https://example.com/t/inner.json#bar` +- canonical IRI plus pointer fragment: `https://example.com/t/inner.json#` + +Document location `/$defs/C`: +- canonical (and base) IRI: +`urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f` +- canonical IRI plus pointer fragment: + `urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#` + +Note: The fragment part of the IRI does not make it canonical or non-canonical, +rather, the base IRI used (as part of the full IRI with any fragment) is what +determines the canonical nature of the resulting full IRI.[^18] + +[^18]: Multiple "canonical" IRIs? We Acknowledge this is potentially confusing, +and direct you to read the CREF located in {{embedded}} for further comments. + +While the following IRIs do correctly indicate specific schemas, per the reasons +outlined in {{embedded}}, they are to be avoided as they may not work in all +implementations: + +Document location `/$defs/B`: +- canonical (and base) `IRI: https://example.com/other.json` +- base IRI of enclosing (root.json) resource plus fragment: + `https://example.com/root.json#/$defs/B` + +Document location `/$defs/B/$defs/X`: +- base IRI: `https://example.com/other.json` +- base IRI of enclosing (root.json) resource plus fragment: + `https://example.com/root.json#/$defs/B/$defs/X` + +Document location `/$defs/B/$defs/Y`: +- canonical (and base) IRI: +`https://example.com/t/inner.json` +- base IRI of enclosing (other.json) resource plus fragment: + `https://example.com/other.json#/$defs/Y` +- base IRI of enclosing (root.json) resource plus fragment: + `https://example.com/root.json#/$defs/B/$defs/Y` + +Document location `/$defs/C`: +- canonical (and base) IRI: +`urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f` +- base IRI of enclosing (root.json) resource plus fragment: + `https://example.com/root.json#/$defs/C` + +## %appendix% Manipulating schema documents and references + +Various tools have been created to rearrange schema documents based on how and +where references (`$ref`) appear. This appendix discusses which use cases and +actions are compliant with this specification. + +### Bundling schema resources into a single document + +A set of schema resources intended for use together can be organized with each +in its own schema document, all in the same schema document, or any granularity +of document grouping in between. + +Numerous tools exist to perform various sorts of reference removal. A common +case of this is producing a single file where all references can be resolved +within that file. This is typically done to simplify distribution, or to +simplify coding so that various invocations of JSON Schema libraries do not have +to keep track of and load a large number of resources. + +This transformation can be safely and reversibly done as long as all static +references (e.g. `$ref`) use IRI references that resolve to IRIs using the +canonical resource IRI as the base, and all schema resources have an +absolute IRI as the `$id` in their root schema. + +With these conditions met, each external resource can be copied under `$defs`, +without breaking any references among the resources' schema objects, and without +changing any aspect of validation or annotation results. The names of the +schemas under `$defs` do not affect behavior, assuming they are each unique, as +they do not appear in the canonical IRIs for the embedded resources. + +### Reference removal is not always safe + +Attempting to remove all references and produce a single schema document does +not, in all cases, produce a schema with identical behavior to the original +form. + +Since `$ref` is now treated like any other keyword, with other keywords allowed +in the same schema objects, fully supporting non-recursive `$ref` removal in all +cases can require relatively complex schema manipulations. It is beyond the +scope of this specification to determine or provide a set of safe `$ref` removal +transformations, as they depend not only on the schema structure but also on the +intended usage. + +## %appendix% Example of recursive schema extension {#dynamic-example} + +Consider the following two schemas describing a simple recursive tree structure, +where each node in the tree can have a "data" field of any type. The first +schema allows and ignores other instance properties. The second is more strict +and only allows the "data" and "children" properties. An example instance with +"data" misspelled as "daat" is also shown. + +```jsonschema "Tree schema, extensible" +{ + "$schema": "https://json-schema.org/1/2025", + "$id": "https://example.com/tree", + "$dynamicAnchor": "node", + + "type": "object", + "properties": { + "data": true, + "children": { + "type": "array", + "items": { + "$dynamicRef": "#node" + } + } + } +} +``` + +```jsonschema "Strict-tree schema, guards against misspelled properties" +{ + "$schema": "https://json-schema.org/1/2025", + "$id": "https://example.com/strict-tree", + "$dynamicAnchor": "node", + + "$ref": "tree", + "unevaluatedProperties": false +} +``` + +```jsonschema "Instance with misspelled field" +{ + "children": [ { "daat": 1 } ] +} +``` + +When we load these two schemas, we will notice the `$dynamicAnchor` named "node" +(note the lack of "#" as this is just the name) present in each, resulting in +the following full schema IRIs: + +- `https://example.com/tree#node` +- `https://example.com/strict-tree#node` + +In addition, JSON Schema implementations keep track of the fact that these +fragment identifiers were created with `$dynamicAnchor`. + +If we apply the "strict-tree" schema to the instance, we will follow the `$ref` +to the "tree" schema, examine its "children" subschema, and find the +`$dynamicRef`: to "#node" (note the `#` for IRI fragment syntax) in its `items` +subschema. That reference resolves to `https://example.com/tree#node`, which is +a IRI with a fragment created by `$dynamicAnchor`. Therefore we must examine the +dynamic scope before following the reference. + +At this point, the evaluation path is +`/$ref/properties/children/items/$dynamicRef`, with a dynamic scope containing +(from the outermost scope to the innermost): + +1. `https://example.com/strict-tree#` +1. `https://example.com/tree#` +1. `https://example.com/tree#/properties/children` +1. `https://example.com/tree#/properties/children/items` + +Since we are looking for a plain name fragment identifier, which can be defined +anywhere within a schema resource, the JSON Pointer IRI fragments are irrelevant +to this check. That means that we can remove the fragments and eliminate +consecutive duplicates, producing: + +1. `https://example.com/strict-tree` +1. `https://example.com/tree` + +In this case, the outermost resource also has a "node" fragment identifier +defined by `$dynamicAnchor`. Therefore instead of resolving the `$dynamicRef` to +`https://example.com/tree#node`, we resolve it to +`https://example.com/strict-tree#node`. + +The reference in the "tree" schema resolves to the root of "strict-tree", so +"strict-tree" is applied not only to the tree instance's root, but also its +children. + +This example shows both `$dynamicAnchor`s in the same place in each schema, +specifically the resource root schema. Since plain-name fragment identifiers are +independent of the JSON structure, this would work just as well if one or both +of the node schema objects were moved under `$defs`. It is the matching +`$dynamicAnchor` values which tell us how to resolve the dynamic reference, not +any sort of correlation in JSON structure. + +## %appendix% References and generative use cases + +While the presence of references is expected to be transparent to validation +results, generative use cases such as code generators and UI renderers often +consider references to be semantically significant. + +To make such use case-specific semantics explicit, the best practice is to +create an annotation keyword for use in the same schema object alongside of a +reference keyword such as `$ref`. + +For example, here is a hypothetical keyword for determining whether a code +generator should consider the reference target to be a distinct class, and how +those classes are related. Note that this example is solely for illustrative +purposes, and is not intended to propose a functional code generation keyword. + +```jsonschema +{ + "allOf": [ + { + "classRelation": "is-a", + "$ref": "classes/base.json" + }, + { + "$ref": "fields/common.json" + } + ], + "properties": { + "foo": { + "classRelation": "has-a", + "$ref": "classes/foo.json" + }, + "date": { + "$ref": "types/dateStruct.json", + } + } +} +``` + +Here, this schema represents some sort of object-oriented class. The first +reference in the `allOf` is noted as the base class. The second is not assigned +a class relationship, meaning that the code generator should combine the +target's definition with this one as if no reference were involved. + +Looking at the properties, "foo" is flagged as object composition, while the +"date" property is not. It is simply a field with sub-fields, rather than an +instance of a distinct class. + +This style of usage requires the annotation to be in the same object as the +reference, which must be recognizable as a reference. + +## %appendix% Acknowledgments + +Thanks to Gary Court, Francis Galiegue, Kris Zyp, Geraint Luff, and Henry +Andrews for their work on the initial drafts of JSON Schema. + +Thanks to Jason Desrosiers, Daniel Perrett, Erik Wilde, Evgeny Poberezkin, Brad +Bowman, Gowry Sankar, Donald Pipowitch, Dave Finlay, Denis Laxalde, Phil +Sturgeon, Shawn Silverman, and Karen Etheridge for their submissions and patches +to the document. + +## %appendix% Change Log[^19] + +### draft-bhutton-json-schema-next +- Use IRIs instead of URIs, including allowing unicode in plain-name fragments +- Clarify that detecting duplicate IRIs for different schemas SHOULD raise an + error +- Consolidate and clarify the syntax and rationale for plain-name fragments +- "$id" MUST be an absolute IRI, without any fragment, even an empty one +- Note that an empty string "$id" results in duplicate IRIs for different + schemas +- Define empty schemas as empty (no longer allowing unrecognized keywords) +- Clarify that if unknown properties are not treated as annotations, they MUST + be ignored +- Remove outdated pre-annotation-collection section on annotation-applicator + interaction +- Clarify that regular expressions are not anchored +- Specify valid implementation-defined options for handling schemas without + "$schema" +- Clarify that vocabularies omitted from "$vocabulary" MUST NOT be available for + use +- Clarify that standard keywords are only available as vocabulary keywords, + subject to "$vocabulary" control +- Clarify the nature and purpose of optional (set to false in "$vocabulary") + vocabularies +- Clarify that optional simple-annotation-only vocabularies can be supported + without custom code +- Fix typo that "$vocabulary" can only be in a document root; it is legal in + resource roots +- Remove bookending requirement for `$dynamicRef` +- Clarify that "prefixItems" does not constrain the length of an array +- Move "minContains" and "maxContains" to the applicator vocabulary from + validation +- "minContains" and "maxContains" no longer have their own assertion results +- "contains" assertion result now depends on "minContains" and "maxContains" +- Affirm that no keyword can un-fail an adjacent keyword ("minContains" + previously violated this) +- "contains", "minContains", and "maxContains" now apply to objects as well as + arrays +- As an object keyword, "contains" now affects "unevaluatedProperties" +- Add `propertyDependencies` keyword +- Add new "list" and "hierarchical" output formats in place of "basic", + "detailed", and "verbose" +- Rename "absoluteKeywordLocation" and "keywordLocation" to "schemaLocation" and + "evaluationPath" +- Output units in new format group by "schemaLocation", "instanceLocation", and + "evaluationPath" +- Add "droppedAnnotations" to output formats + +### draft-bhutton-json-schema-01 +- Improve and clarify the `type`, `contains`, `unevaluatedProperties`, and + `unevaluatedItems` keyword explanations +- Clarify various aspects of "canonical URIs" +- Comment on ambiguity around annotations and `additionalProperties` +- Clarify Vocabularies need not be formally defined +- Remove references to remaining media-type parameters +- Fix multiple examples + +### draft-bhutton-json-schema-00 +- `$schema` MAY change for embedded resources +- Array-value `items` functionality is now `prefixItems` +- `items` subsumes the old function of `additionalItems` +- `contains` annotation behavior, and `contains` and `unevaluatedItems` + interactions now specified +- Rename $recursive* to $dynamic*, with behavior modification +- $dynamicAnchor defines a fragment like $anchor +- $dynamic* (previously $recursive) no longer use runtime base URI determination +- Define Compound Schema Documents (bundle) and processing +- Reference ECMA-262, 11th edition for regular expression support +- Regular expression should support unicode +- Remove media type parameters +- Specify Unknown keywords are collected as annotations +- Moved `unevaluatedItems` and `unevaluatedProperties` from core into their own + vocabulary + +### draft-handrews-json-schema-02 +- Update to RFC 8259 for JSON specification +- Moved `definitions` from the Validation specification here as `$defs` +- Moved applicator keywords from the Validation specification as their own + vocabulary +- Moved the schema form of `dependencies` from the Validation specification as + `dependentSchemas` +- Formalized annotation collection +- Specified recommended output formats +- Defined keyword interactions in terms of annotation and assertion results +- Added `unevaluatedProperties` and `unevaluatedItems` +- Define `$ref` behavior in terms of the assertion, applicator, and annotation + model +- Allow keywords adjacent to `$ref` +- Note undefined behavior for `$ref` targets involving unknown keywords +- Add recursive referencing, primarily for meta-schema extension +- Add the concept of formal vocabularies, and how they can be recognized through + meta-schemas +- Additional guidance on initial base URIs beyond network retrieval +- Allow "schema" media type parameter for `application/schema+json` +- Better explanation of media type parameters and the HTTP Accept header +- Use `$id` to establish canonical and base absolute-URIs only, no fragments +- Replace plain-name-fragment-only form of `$id` with `$anchor` +- Clarified that the behavior of JSON Pointers across `$id` boundary is + unreliable + +### draft-handrews-json-schema-01 +- This draft is purely a clarification with no functional changes +- Emphasized annotations as a primary usage of JSON Schema +- Clarified $id by use cases +- Exhaustive schema identification examples +- Replaced "external referencing" with how and when an implementation might know + of a schema from another document +- Replaced "internal referencing" with how an implementation should recognized + schema identifiers during parsing +- Dereferencing the former "internal" or "external" references is always the + same process +- Minor formatting improvements + +### draft-handrews-json-schema-00 +- Make the concept of a schema keyword vocabulary more clear +- Note that the concept of "integer" is from a vocabulary, not the data model +- Classify keywords as assertions or annotations and describe their general + behavior +- Explain the boolean schemas in terms of generalized assertions +- Reserve `$comment` for non-user-visible notes about the schema +- Wording improvements around `$id` and fragments +- Note the challenges of extending meta-schemas with recursive references +- Add `application/schema-instance+json` media type +- Recommend a "schema" link relation / parameter instead of "profile" + +### draft-wright-json-schema-01 +- Updated intro +- Allowed for any schema to be a boolean +- `$schema` SHOULD NOT appear in subschemas, although that may change +- Changed `id` to `$id`; all core keywords prefixed with "$" +- Clarify and formalize fragments for `application/schema+json` +- Note applicability to formats such as CBOR that can be represented in the JSON + data model + +### draft-wright-json-schema-00 +- Updated references to JSON +- Updated references to HTTP +- Updated references to JSON Pointer +- Behavior for `id` is now specified in terms of RFC3986 +- Aligned vocabulary usage for URIs with RFC3986 +- Removed reference to draft-pbryan-zyp-json-ref-03 +- Limited use of `$ref` to wherever a schema is expected +- Added definition of the "JSON Schema data model" +- Added additional security considerations +- Defined use of subschema identifiers for `id` +- Rewrote section on usage with HTTP +- Rewrote section on usage with rel="describedBy" and rel="profile" +- Fixed numerous invalid examples + +### draft-zyp-json-schema-04 +- Salvaged from draft v3. +- Split validation keywords into separate document. +- Split hypermedia keywords into separate document. +- Initial post-split draft. +- Mandate the use of JSON Reference, JSON Pointer. +- Define the role of `id`. Define URI resolution scope. +- Add interoperability considerations. + +### draft-zyp-json-schema-00 +- Initial draft. + +## Authors' Addresses +| Author | Company | Email | URI | +| ------------------------ | ------- | ----------------------- | -------------------------------- | +| Austin Wright (*editor*) | | | | +| Ben Hutton (*editor*) | Postman | | | +| Greg Dennis | | | | + +[^19]: This section to be removed before leaving Internet-Draft status. + +[rfc3986]: https://www.rfc-editor.org/info/rfc3986 +[rfc3987]: https://www.rfc-editor.org/info/rfc3987 +[rfc6901]: https://www.rfc-editor.org/info/rfc6901 +[rfc8259]: https://www.rfc-editor.org/info/rfc8259 +[rfc8288]: https://www.rfc-editor.org/info/rfc8288 diff --git a/specs/jsonschema-use-cases.xml b/specs/jsonschema-use-cases.xml new file mode 100644 index 00000000..7269533d --- /dev/null +++ b/specs/jsonschema-use-cases.xml @@ -0,0 +1,310 @@ + + + + + +]> + + + + + + + + + + + JSON Schema: Use Cases and Requirements + + +
+ aaa@bzfx.net +
+
+ + + JSON Schema + JSON + Schema + Hyper Schema + Hypermedia + + + + To foster development of JSON Schema, this document contains a list of use cases and requirements that may be used to inform its development and evolution. + + + + + The issues list for this document can be found at + . + + + For additional information, see . + + + To provide feedback, use this issue tracker, the communication methods listed on the + homepage, or email the document editors. + + +
+ + +
+ + JSON Schema is a JSON media type for defining the structure of JSON data. JSON Schema + is intended to define validation, documentation, hyperlink navigation, and interaction + control of JSON data. + + + This document elaborates in detail what this means, and the specific use cases that shall be supported. + +
+ +
+ + Objectives specify the class of problems that are in the scope of the specification. + + + + Use Cases catalog a variety of personal objectives that users may have, due to various motivations and constraints, that the specification shall accommodate, but without prescribing a specific design or implementation. + + + + Requirements list functional, non-functional, and quality requirements, the use cases they may be derived from/related to, and reference how each use case is implemented. Requirements are not detailed at this time but may be specified in the future. + +
+ +
+ + JSON Schema shall be built to support the following objectives, supporting expansion into uses not currently described by any use case, but which fall within the objectives. + + +
+ + The first objective of JSON Schema is to describe sets of JSON documents; specifically, to notate a language of JSON documents using a machine-readable, set-builder notation. + This covers the key use case of validating input using a validator, as well as numerous other tools that depend on describing to each other which kinds of JSON documents are and are not acceptable. + +
+ +
+ + The second objective of JSON Schema is to map an input JSON document to an arbitrary output described by the user. + Annotations may be combined with validation (in the same schema) to specify the domain of inputs for which an output is defined. + This covers the key use case of documenting the meaning of properties and values in JSON documents, and other uses where the input document is being interpreted in some fashion. + +
+ +
+ + JSON is a technology standardized as a part of a larger ecosystem of Internet technology, and likewise, JSON Schema may also specify its role in this ecosystem; for example, use in HTTP, or the meaning of media type parameters. + +
+ +
+ + Use cases or requirements that do not advance these objectives are likely out of scope, and better suited in separate work that references JSON Schema. + + + For example, a method of describing an API interface would exceed the scope of JSON Schema, although JSON Schema may be used as a part of such a description, such as when the API is using JSON and needs a way to describe these JSON documents. + +
+ +
+ +
+ + JSON Schema shall be written to standardize these use cases, or shall accommodate implementations targeted at these uses. + + +
+ + Structural validation refers to the "structure" that a JSON document is supposed to follow, such as which properties must exist, what types of values are expected where, and what they must look like. Constraints cannot read values elsewhere in the document (e.g. to compare two values for equality), though constraints may depend on "where" the value is found (e.g. specific properties or array items must be a number). + + + More specifically, structural validation is any validation that can be performed with a context-free grammar that follows JSON semantics, such that any forms that are equal according to JSON will produce the same result. + + + Validators that support structural validation can entirely replace generic grammar languages such as ABNF, and will guarantee compliance with JSON semantics. Likewise, schemas whose validation rules are limited to structural validation can be executed using a deterministic pushdown automata, guaranteeing a result in proportional time without error. + + + The following features of JSON are structural validation: + + + JSON primitive type (string, object, etc) + Minimum or maximum in a linear range of values + Minimum or maximum lengths (number of characters, digits, items, or properties) + Literal/constant values or alternate/enumerated values + Pattern matching strings by a regular expression (including object keys) + Logic operators (union, intersection, difference) + Descent into object properties and array items (recursively) + + + Multiple forms that are value-equal according to JSON are not distinguishable under this use-case. This includes the ordering of properties in an object, character escapes in strings, and whitespace. + +
+ +
+ + There is a need to annotate values within a JSON document: for machine readability, and for documentation purposes. + Given a document and directions for annotating it, you should should be able to: + + + document the meaning of a property, + suggest a default value for new documents of a given type, + fill in missing values (in objects or arrays) with values of equivalent meaning, + generate a list of hyperlinks, + or declare relationships between data. + + + A schema may be used to describe a machine-readable profile of JSON document. Even when two schemas identify the same set of JSON documents; depending on the context, a given JSON document may be a profile of one but not the other. + +
+ +
+ + Developers may write an application that uses a JSON Schema internally as a domain-specific language, so that the schema is only used inside a single application by a single party. By using a declarative language, the application requirements can be optimized better than a human could do. + + + Application authors may use a schema to define custom hooks and processing for the JSON (without need for standardizing the customization). + + + The only interoperability consideration here is that updates to the validator library must not change the validation result of any JSON documents, unless the developer specifically opts into such a breaking change (e.g. by upgrading the library to a new major version number). + +
+ +
+ + A development team maintains two similar applications, but for different platforms, in different languages. The application downloads and reads from a common repository of JSON documents. They want to make sure that both applications accept or reject JSON with identical behavior, so they write a single JSON Schema and deploy it to both applications. + + + The only interoperability consideration here is that the two applications, given the same schema, must both be reasonably expected to support the same behavior and operate in the same manner. + +
+ +
+ + When a server declares constraints that a submission must meet, there is a need for the user interface to receive these constraints to provide model-driven validation of permissible values, making the form more accessible to the user. + + + For example, if a value is specified to be a date, the form field where the value is specified can provide immediate feedback if an invalid date is entered, and even offer a date picker to help the user input a correct value. + + + Weak interoperability requirements can hamper the user experience within this use case. If the schema is ambiguous in any way, or is up to the discretion of the customer's user-agent, some customers may have a difficult time submitting a correct request. + +
+ +
+ + Security applications need to generate examples of JSON documents within the valid set, and outside the valid set. + +
+ +
+ + A database that uses JSON may need a way to declare, enforce, or guarantee certain constraints on the JSON document being stored. The database may also use JSON Schema as a way to annotate certain fields as having a special meaning for uniqueness or indexing purposes. + +
+ +
+ + Due to technical limitations, some JSON parsers may only be able to understand a subset of the JSON value space, and it makes sense to validate the value read by the application, instead of the JSON document provided to the JSON parser. For example: + + + Many JSON parsers cast the arbitrary-precision decimal numbers to an IEEE floating point, validating the number after it has lost some precision. + Some programming languages cannot distinguish between an ordered array of values and a key-value map; or an empty array is identical to an empty object. + Other validators may have a limited amount of memory and cannot support assertions more complicated than a deterministic context-free grammar. + + + Users of these validators need a way to determine if the missing functionality is essential to correctly validating input, and if not, get a validation result that would be correct but-for the unimplemented functionality. + + + + There's two directions this can work: an application should be able to determine if a third-party schema is making a distinction that it does not support; and an application may want to publish a schema indicating it works in a reduced value space. + + +
+ +
+ + A Web server that offers a JSON document should be able to link to a profile document that describes the meaning of the data in a machine-readable form. + +
+ +
+ + Generic user-agents must be able to make use of the schema as it evolves, including Web browsers, spiders, and automated tooling. It should support loose coupling (like an HTML homepage); so a schema should be able to change, add, and remove features with minimal breakage for compatible clients. + +
+ +
+ + The party that is providing the schema and input may not be the same party that is performing the validation; in this case, there should be a standard way to abstract away the validator interface, and report the results of a validation operation (validation result, annotations, and errors). + +
+ +
+ + Not every feature needs to be supported by every implementation. + To accommodate a wide variety of niche audiences, it should be possible to specify features that are optional to implement. + This includes standardized features that are optional to implement, bespoke or user-defined features that are not standardized, and new features added to future publications of the specification. + For forward compatibility, implementations that do not support optional extensions must degrade in a predictable fashion. + +
+ +
+ + Authors may embed resources of other media types, such as text documents, or base64 or hex-encoded binary documents; and may wish to pass off validation of these documents to another software tool. + +
+ +
+ + A JSON document may carry relational data that must be internally consistent. Example constraints include: + +
    +
  • One-to-one calculations, like that children's birthdates come after their parent's birthdates;
  • +
  • One-to-many calculations, like a reference to an anchor points to an anchor defined somewhere in the same document.
  • +
+
+ +
+ + A JSON document may carry relational data that must be verified against outside data sources. Example constraints include: + +
    +
  • References to a user ID points to a user in a central users database.
  • +
  • A supplied email address has been verified by the user.
  • +
+
+ +
+ + Sometimes it's desirable to require formatting that does not impact the application-level meaning of the document, but instead specifies requirements purely for aesthetic or compatibility reasons. + + + For example, for security reasons, an application may want to verify a JSON document does not contain the string "</script" but is written instead with a character escape such as "<\/script". This would ensure that, if the JSON were to be embedded in a <script> tag, it could not close the tag and be interpreted as HTML. + + + This is not a standard part of JSON Schema because it may violate the semantics of JSON, by adding an ability to distinguish between encodings which are supposed to be equivalent to receiving applications. + +
+
+ +
+ + This document does not make any normative requirements. + +
+
+ + + + + &RFC5234; + &RFC6906; + + + +
diff --git a/specs/jsonschema-validation.md b/specs/jsonschema-validation.md new file mode 100644 index 00000000..e658f3a4 --- /dev/null +++ b/specs/jsonschema-validation.md @@ -0,0 +1,919 @@ + +# JSON Schema Validation: A Vocabulary for Structural Validation of JSON + +## Abstract + +JSON Schema (application/schema+json) has several purposes, one of which is JSON +instance validation. This document specifies a vocabulary for JSON Schema to +describe the meaning of JSON documents, provide hints for user interfaces +working with JSON data, and to make assertions about what a valid document must +look like. + +## Note to Readers + +The issues list for this draft can be found at +. + +For additional information, see . + +To provide feedback, use this issue tracker, the communication methods listed on +the homepage, or email the document editors. + +## Table of Contents + +## Introduction + +JSON Schema can be used to require that a given JSON document (an instance) +satisfies a certain number of criteria. These criteria are asserted by using +keywords described in this specification. In addition, a set of keywords is also +defined to assist in interactive user interface instance generation. + +This specification will use the concepts, syntax, and terminology defined by the +[JSON Schema core](./jsonschema-core.md) specification. + +## Conventions and Terminology +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in [RFC 2119](https://www.rfc-editor.org/info/rfc2119). + +This specification uses the term "container instance" to refer to both array and +object instances. It uses the term "children instances" to refer to array +elements or object member values. + +Elements in an array value are said to be unique if no two elements of this +array are [equal](./jsonschema-core.md). + +## Overview + +JSON Schema validation asserts constraints on the structure of instance data. +An instance location that satisfies all asserted constraints is then annotated +with any keywords that contain non-assertion information, such as descriptive +metadata and usage hints. If all locations within the instance satisfy all +asserted constraints, then the instance is said to be valid against the schema. + +Each schema object is independently evaluated against each instance location to +which it applies. This greatly simplifies the implementation requirements for +validators by ensuring that they do not need to maintain state across the +document-wide validation process. + +This specification defines a set of assertion keywords, as well as a number of +metadata keywords that can be used to annotate the JSON instance with useful +information. The {{format}} keyword is intended primarily as an annotation, but +can optionally be used as an assertion. The {{content}} keywords are annotations +for working with documents embedded as JSON strings. + +## Keyword Behaviors + +The keywords defined by this document exhibit one or more behaviors as defined by +the [JSON Schema Core Specification](./jsonschema-core.md#keyword-behaviors). + +Keywords which are not defined to exhibit a particular behavior MUST NOT affect +that aspect of the evaluation outcome. In particular, the keywords defined in +{{annotations}} produce no assertion result and therefore are not considered +during validation. + +For the purposes of this document, an instance "validating against a keyword" +means that the keyword produces an assertion result of `true` if the instance +satisfies the given constraint; otherwise an assertion result of `false` is +produced. + +## Interoperability Considerations + +### Validation of String Instances + +It should be noted that the nul character (\u0000) is valid in a JSON string. An +instance to validate may contain a string value with this character, regardless +of the ability of the underlying programming language to deal with such data. + +### Validation of Numeric Instances + +The JSON specification allows numbers with arbitrary precision, and JSON Schema +does not add any such bounds. This means that numeric instances processed by +JSON Schema can be arbitrarily large and/or have an arbitrarily long decimal +part, regardless of the ability of the underlying programming language to deal +with such data. + +### Regular Expressions {#regexinterop} + +Keywords that use regular expressions, or constrain the instance value to be a +regular expression, are subject to the interoperability considerations for +regular expressions in the [JSON Schema Core](./jsonschema-core.md) +specification. + +## Meta-Schema {#meta-schema} + +The current IRI for the default JSON Schema dialect meta-schema is +`https://json-schema.org/1/2025`. This IRI encodes the specification's version +and release year. Because all schemas written to conform to a given version are +guaranteed to be compatible with later releases within the same version, the +meta-schema IRI `https://json-schema.org/1` is also recognized to represent the +latest release within the indicated version. + +The meta-schema describes a dialect consisting of all keywords defined in this +specification and the JSON Schema Core specification. Certain keywords specify +some functionality which is optional to support and is explained in detail in +the relevant sections. + +Where the meta-schema conflicts with either this specification or the JSON +Schema Core specification, the specifications take precedence, and the +meta-schema is to be considered in error. The meta-schema may be occasionally +updated to correct any such errors. + +Although the IRI for the default JSON Schema dialect meta-schema is also a valid +URL, implementations MUST NOT assume that a document is provided at this +location. Rather than performing a network request to retrieve the meta-schema, +implementations SHOULD include a copy of the meta-schema and MAY encode it as +required by the language or framework used by the implementation. + +## Keywords for Structural Validation + +Validation keywords in a schema impose requirements for successful validation of +an instance. These keywords are all assertions without any annotation behavior. + +### Validation Keywords for Any Instance Type {#general} + +#### `type` + +The value of this keyword MUST be either a string or an array. If it is an +array, it MUST be non-empty, and elements of the array MUST be strings and MUST +be unique. + +String values MUST be one of the six primitive types ("null", "boolean", +"object", "array", "number", or "string"), or "integer" which matches any number +with a zero fractional part. + +If the value of `type` is a string, then an instance validates successfully if +its type matches the type represented by the value of the string. + +If the value of `type` is an array, then an instance validates successfully if +its type matches any of the types indicated by the strings in the array. + +#### `enum` {#enum} + +The value of this keyword MUST be an array. This array SHOULD have at least one +element. Elements in the array SHOULD be unique. + +An instance validates successfully against this keyword if its value is equal to +one of the elements in this keyword's array value. + +Elements in the array might be of any type, including null. + +#### `const` + +The value of this keyword MAY be of any type, including null. + +Use of this keyword is functionally equivalent to an [`enum`](#enum) with a +single value. + +An instance validates successfully against this keyword if its value is equal to +the value of the keyword. + +### Validation Keywords for Numeric Instances (number and integer) {#numeric} + +#### `multipleOf` + +The value of `multipleOf` MUST be a number, strictly greater than 0. + +A numeric instance is valid only if division by this keyword's value results in +an integer. + +#### `maximum` + +The value of `maximum` MUST be a number, representing an inclusive upper limit +for a numeric instance. + +If the instance is a number, then this keyword validates only if the instance is +less than or exactly equal to `maximum`. + +#### `exclusiveMaximum` + +The value of `exclusiveMaximum` MUST be a number, representing an exclusive +upper limit for a numeric instance. + +If the instance is a number, then the instance is valid only if it has a value +strictly less than (not equal to) `exclusiveMaximum`. + +#### `minimum` + +The value of `minimum` MUST be a number, representing an inclusive lower limit +for a numeric instance. + +If the instance is a number, then this keyword validates only if the instance is +greater than or exactly equal to `minimum`. + +#### `exclusiveMinimum` + +The value of `exclusiveMinimum` MUST be a number, representing an exclusive +lower limit for a numeric instance. + +If the instance is a number, then the instance is valid only if it has a value +strictly greater than (not equal to) `exclusiveMinimum`. + +### Validation Keywords for Strings {#string} + +#### `maxLength` + +The value of this keyword MUST be a non-negative integer. + +A string instance is valid against this keyword if its length is less than, or +equal to, the value of this keyword. + +The length of a string instance is defined as the number of its characters as +defined by [RFC 8259][rfc8259]. + +#### `minLength` + +The value of this keyword MUST be a non-negative integer. + +A string instance is valid against this keyword if its length is greater than, +or equal to, the value of this keyword. + +The length of a string instance is defined as the number of its characters as +defined by [RFC 8259][rfc8259]. + +Omitting this keyword has the same behavior as a value of 0. + +#### `pattern` {#pattern} + +The value of this keyword MUST be a string. This string SHOULD be a valid +regular expression as indicated in +[JSON Schema Core, section 6.3](./jsonschema-core.md#regex). + + +A string instance is considered valid if the regular expression matches the +instance successfully. Recall: regular expressions are not implicitly anchored. + +### Validation Keywords for Arrays + +#### `maxItems` + +The value of this keyword MUST be a non-negative integer. + +An array instance is valid against `maxItems` if its size is less than, or equal +to, the value of this keyword. + +#### `minItems` + +The value of this keyword MUST be a non-negative integer. + +An array instance is valid against `minItems` if its size is greater than, or +equal to, the value of this keyword. + +Omitting this keyword has the same behavior as a value of 0. + +#### `uniqueItems` + +The value of this keyword MUST be a boolean. + +If this keyword has boolean value `false`, the instance validates successfully. +If it has boolean value `true`, the instance validates successfully if all of +its elements are unique. + +Omitting this keyword has the same behavior as a value of `false`. + +### Validation Keywords for Objects + +#### `maxProperties` + +The value of this keyword MUST be a non-negative integer. + +An object instance is valid against `maxProperties` if its number of properties +is less than, or equal to, the value of this keyword. + +#### `minProperties` + +The value of this keyword MUST be a non-negative integer. + +An object instance is valid against `minProperties` if its number of properties +is greater than, or equal to, the value of this keyword. + +Omitting this keyword has the same behavior as a value of 0. + +#### `required` + +The value of this keyword MUST be an array. Elements of this array, if any, MUST +be strings, and MUST be unique. + +An object instance is valid against this keyword if every item in the array is +the name of a property in the instance. + +Omitting this keyword has the same behavior as an empty array. + +#### `dependentRequired` + +The value of this keyword MUST be an object. Properties in this object, if any, +MUST be arrays. Elements in each array, if any, MUST be strings, and MUST be +unique. + +This keyword specifies properties that are required if a specific other property +is present. Their requirement is dependent on the presence of the other +property. + +Validation succeeds if, for each name that appears in both the instance and as a +name within this keyword's value, every item in the corresponding array is also +the name of a property in the instance. + +Omitting this keyword has the same behavior as an empty object. + +## Semantic Content With `format` {#format} + +### Foreword + +Structural validation alone may be insufficient to allow an application to +correctly utilize certain values. The `format` annotation keyword is defined to +allow schema authors to convey semantic information for a fixed subset of values +which are accurately described by authoritative resources, be they RFCs or other +external specifications. Format values defined externally to this document +SHOULD also be based on such authoritative resources in order to foster +interoperability. + +The value of this keyword MUST be a string. While this keyword can validate any +type, each distinct value will generally only validate a given set of instance +types. If the type of the instance to validate is not in this set, validation +for this keyword SHOULD succeed. All format values defined in this section apply +to strings, but a format value can be specified to apply to any instance types +defined in the data model defined in the [core JSON +Schema](./jsonschema-core.md) specification[^1]. + +[^1]: Note that the `type` keyword in this specification defines an "integer" +type which is not part of the data model. Therefore a format attribute can be +limited to numbers, but not specifically to integers. However, a numeric format +can be used alongside the `type` keyword with a value of "integer", or it could +be explicitly defined to always pass if the number is not an integer, which +produces essentially the same behavior as only applying to integers. + +Implementations SHOULD provide assertion behavior for the format values defined +by this document[^2] and MUST refuse to process any schema which contains a +format value it doesn't support. + +[^2]: Assertion behavior is called out very explicitly because it is a departure +from previous iterations of this specification. Previously, `format` was an +annotation-only keyword by default and implementations that supported assertion +were required to offer some configuration that allowed users to explicitly +enable assertion. Assertion is now a requirement in order to meet user +expectations. See +[json-schema-org/json-schema-spec #1520](https://github.com/json-schema-org/json-schema-spec/issues/1520) +for more. + +In addition to the assertion behavior, this keyword also produces its value as +an annotation. + +Implementations: + +- SHOULD provide validation for each format attribute defined in this document; +- are encouraged to provide validation for format attributes listed in the + {{format-registry}}; +- MAY support format values not defined in this document or listed in the + registry, but such support MUST be configurable and disabled by default; +- SHOULD use a common parsing library or a well-known regular expression for + each format; +- SHOULD clearly document any limitations regarding format validation. + +The requirement for validation of format values in general is limited to +syntactic checking; implementations SHOULD NOT attempt to send an email, connect +to a URL, or otherwise check the existence of an entity identified by a format +instance. + +#### Format Registry {#format-registry} + +In addition to the formats defined by this document, JSON Schema also maintains +a registry of formats defined by other specifications and organizations. As of +the publication of this document, the format registry can be found at +. + +Implementations SHOULD support the formats listed in this registry as if they +were defined by this document. + +#### Custom `format` Values + +Implementations MAY support custom format values. Save for agreement between +parties, schema authors SHALL NOT expect a peer implementation to support such +custom format values. + +### Defined Formats + +#### Dates, Times, and Duration + +These attributes apply to string instances. + +Date and time format names are derived from +[RFC 9557, section 4.1](https://www.rfc-editor.org/info/rfc9557) which extends +[RFC 3339, section 5.6](https://www.rfc-editor.org/info/rfc3339). The duration +format is from ISO 8601 as formalized into ABNF by RFC 3339 Appendix A. + +- *date-time*: A string instance is valid against this attribute if it is a + valid representation of the "date-time-ext" rule in RFC 9557 +- *date*: A string instance is valid against this attribute if it is a valid + representation according to the "full-date" ABNF rule in RFC 3339 +- *time*: A string instance is valid against this attribute if it is a valid + representation according to the "full-time" ABNF rule in RFC 3339 +- *duration*: A string instance is valid against this attribute if it is a valid + representation according to the "duration" ABNF rule in RFC 3339 Appendix A + +Implementations MAY support additional attributes using the other format names +defined anywhere in that RFC. Implementations SHOULD NOT define extension +attributes with any name matching an RFC 3339, RFC 9557, or ISO 8601 format +unless it validates according to the rules of that format.[^5] + +[^5]: There is not currently consensus on the need for supporting all RFC 3339 +formats, so this approach of reserving the namespace will encourage +experimentation without committing to the entire set. Either the format +implementation requirements will become more flexible in general, or these will +likely either be promoted to fully specified attributes or dropped. + +#### Email Addresses + +These attributes apply to string instances. + +A string instance is valid against these format values if it is a valid Internet +email address as follows: + +- *email:* As defined by the "Mailbox" ABNF rule in [RFC 5321, section + 4.1.2](https://www.rfc-editor.org/info/rfc5321). +- *idn-email:* As defined by the extended "Mailbox" ABNF rule in [RFC 6531, + section 3.3](https://www.rfc-editor.org/info/rfc6531). Note that all strings + valid against the "email" attribute are also valid against the "idn-email" + attribute. + +#### Hostnames + +These attributes apply to string instances. + +A string instance is valid against these attributes if it is a valid +representation for an Internet hostname as follows: + +- *hostname:* As defined by + [RFC 1123, section 2.1](https://www.rfc-editor.org/info/rfc1123), including + host names produced using the Punycode algorithm specified in [RFC 5891, + section 4.4](https://www.rfc-editor.org/info/rfc5891). +- *idn-hostname:* As defined by either RFC 1123 as for hostname, or an + internationalized hostname as defined by [RFC 5890, section + 2.3.2.3](https://www.rfc-editor.org/info/rfc5890). Note that all strings valid + against the "hostname" attribute are also valid against the "idn-hostname" + attribute. + +#### IP Addresses + +These attributes apply to string instances. + +A string instance is valid against these attributes if it is a valid +representation of an IP address as follows: + +- *ipv4:* An IPv4 address according to the "dotted-quad" ABNF syntax as defined + in [RFC 2673, section 3.2](https://www.rfc-editor.org/info/rfc2673). +- *ipv6:* An IPv6 address as defined in + [RFC 4291, section 2.2](https://www.rfc-editor.org/info/rfc4291). + +#### Resource Identifiers These attributes apply to string instances. + +- *uri:* A string instance is valid against this attribute if it is a valid IRI, + according to [RFC 3987][rfc3987]. +- *uri-reference:* A string instance is valid against this attribute if it is a + valid URI Reference (either a URI or a relative-reference), according to + [RFC 3986](https://www.rfc-editor.org/info/rfc3986). +- *iri:* A string instance is valid against this attribute if it is a valid IRI, + according to [RFC 3987][rfc3987]. +- *iri-reference:* A string instance is valid against this attribute if it is a + valid IRI Reference (either an IRI or a relative-reference), according to + [RFC 3987][rfc3987]. +- *uuid:* A string instance is valid against this attribute if it is a valid + string representation of a UUID, according to + [RFC 4122](https://www.rfc-editor.org/info/rfc4122). + +Note that all valid URIs are valid IRIs, and all valid URI References are also +valid IRI References. + +Note also that the "uuid" format is for plain UUIDs, not UUIDs in URNs. An +example is "f81d4fae-7dec-11d0-a765-00a0c91e6bf6". For UUIDs as URNs, use the +"uri" format, with a "pattern" regular expression of "^urn:uuid:" to indicate +the URI scheme and URN namespace. + +#### uri-template + +This attribute applies to string instances. + +A string instance is valid against this attribute if it is a valid URI Template +(of any level), according to +[RFC 6570](https://www.rfc-editor.org/info/rfc6570). + +Note that URI Templates may be used for IRIs; there is no separate IRI Template +specification. + +#### JSON Pointers + +These attributes apply to string instances. + +- *json-pointer:* A string instance is valid against this attribute if it is a + valid JSON string representation of a JSON Pointer, according to [RFC 6901, + section 5](https://www.rfc-editor.org/info/rfc6901). +- *relative-json-pointer:* A string instance is valid against this attribute if + it is a valid + [Relative JSON Pointer](https://datatracker.ietf.org/doc/html/draft-handrews-relative-json-pointer-01). + To allow for both absolute and relative JSON Pointers, use `anyOf` or `oneOf` + to indicate support for either format. + +#### regex + +This attribute applies to string instances. + +A regular expression, which SHOULD be valid according to the +[ECMA-262](https://www.ecma-international.org/ecma-262/11.0/index.html) regular +expression dialect. + +Implementations that validate formats MUST accept at least the subset of +ECMA-262 defined in {{regexinterop}}, and SHOULD accept all valid ECMA-262 +expressions. + +## Keywords for the Contents of String-Encoded Data {#content} + +### Foreword + +Annotations defined in this section indicate that an instance contains non-JSON +data encoded in a JSON string. + +These properties provide additional information required to interpret JSON data +as rich multimedia documents. They describe the type of content, how it is +encoded, and/or how it may be validated. They do not function as validation +assertions; a malformed string-encoded document MUST NOT cause the containing +instance to be considered invalid. + +### Implementation Requirements + +Due to security and performance concerns, as well as the open-ended nature of +possible content types, implementations MUST NOT automatically decode, parse, +and/or validate the string contents. Applications are expected to use these +annotations to invoke the appropriate libraries separately. + +All keywords in this section apply only to strings, and have no effect on other +data types. + +### `contentEncoding` + +If the instance value is a string, this property defines that the string SHOULD +be interpreted as encoded binary data and applications wishing to decode it +SHOULD do so using the encoding named by this property. + +Possible values indicating base 16, 32, and 64 encodings with several variations +are listed in [RFC 4648](https://www.rfc-editor.org/info/rfc4648). Additionally, +sections 6.7 and 6.8 of [RFC 2045](https://www.rfc-editor.org/info/rfc2045) +provide encodings used in MIME. This keyword is derived from MIME's +Content-Transfer-Encoding header, which was designed to map binary data into +ASCII characters. It is not related to HTTP's Content-Encoding header, which is +used to encode (e.g. compress or encrypt) the content of HTTP request and +responses. + +As "base64" is defined in both RFCs, the definition from RFC 4648 SHOULD be +assumed unless the string is specifically intended for use in a MIME context. +Note that all of these encodings result in strings consisting only of 7-bit +ASCII characters. Therefore, this keyword has no meaning for strings containing +characters outside of that range. + +If this keyword is absent, but `contentMediaType` is present, this indicates +that the encoding is the identity encoding, meaning that no transformation was +needed in order to represent the content in a UTF-8 string. + +The value of this property MUST be a string. + +### `contentMediaType` + +If the instance is a string, this property indicates the media type of the +contents of the string. If `contentEncoding` is present, this property describes +the decoded string. + +The value of this property MUST be a string, which MUST be a media type, as +defined by [RFC 2046](https://www.rfc-editor.org/info/rfc2046). + +### `contentSchema` + +If the instance is a string, and if `contentMediaType` is present, this +keyword's subschema describes the structure of the string. + +This keyword MAY be used with any media type that can be mapped into JSON +Schema's data model. Specifying such mappings is outside of the scope of this +specification. + +The value of this property MUST be a valid JSON schema. The subschema is +produced as an annotation. + +Since `contentMediaType` is required to provide instruction on how to interpret +string content, `contentSchema` SHOULD NOT produce an annotation if +`contentMediaType` is not present. + +Note that evaluating the `contentSchema` subschema in-place (i.e. as part of its +parent schema) will ensure that it is correctly processed. Independent use of +the extracted subschema (as returned in an annotation) is only safe if the +subschema is an embedded resource which defines both a `$schema` and an absolute +IRI `$id`.[^7] + +[^7] Processing a non-resource subschema in place will ensure that any +references (e.g. `$ref`) are always resolved properly. This isn't a problem when +the subschema is itself a resource. See +https://github.com/json-schema-org/json-schema-spec/issues/1381 for several +examples where processing this subschema independently can cause `$ref` +resolution failure. + +### Example + +Here is an example schema, illustrating the use of `contentEncoding` and +`contentMediaType`: + +```jsonschema +{ + "type": "string", + "contentEncoding": "base64", + "contentMediaType": "image/png" +} +``` + +Instances described by this schema are expected to be strings, and their values +should be interpretable as base64-encoded PNG images. + +Another example: + +```jsonschema +{ + "type": "string", + "contentMediaType": "text/html" +} +``` + +Instances described by this schema are expected to be strings containing HTML, +using whatever character set the JSON string was decoded into. Per section 8.1 +of [RFC 8259][rfc8259], outside of an entirely closed system, this MUST be +UTF-8. + +This example describes a JWT that is MACed using the HMAC SHA-256 algorithm, and +requires the "iss" and "exp" fields in its claim set. + +```jsonschema +{ + "type": "string", + "contentMediaType": "application/jwt", + "contentSchema": { + "type": "array", + "minItems": 2, + "prefixItems": [ + { + "const": { + "typ": "JWT", + "alg": "HS256" + } + }, + { + "type": "object", + "required": ["iss", "exp"], + "properties": { + "iss": {"type": "string"}, + "exp": {"type": "integer"} + } + } + ] + } +} +``` + +Note that `contentEncoding` does not appear. While the `application/jwt` media +type makes use of base64url encoding, that is defined by the media type, which +determines how the JWT string is decoded into a list of two JSON data +structures: first the header, and then the payload. Since the JWT media type +ensures that the JWT can be represented in a JSON string, there is no need for +further encoding or decoding. + +## Keywords for Basic Meta-Data Annotations {#annotations} + +These general-purpose annotation keywords provide commonly used information for +documentation and user interface display purposes. They are not intended to form +a comprehensive set of features. Rather, additional keywords can be defined +for more complex annotation-based applications. + +### `title` and `description` + +The value of both of these keywords MUST be a string. + +Both of these keywords can be used to decorate a user interface with information +about the data produced by this user interface. A title will preferably be +short, whereas a description will provide explanation about the purpose of the +instance described by this schema. + +### `default` + +There are no restrictions placed on the value of this keyword. When multiple +occurrences of this keyword are applicable to a single sub-instance, +implementations SHOULD remove duplicates. + +This keyword can be used to supply a default JSON value associated with a +particular schema. It is RECOMMENDED that a default value be valid against the +associated schema. + +### `deprecated` + +The value of this keyword MUST be a boolean. When multiple occurrences of this +keyword are applicable to a single sub-instance, applications SHOULD consider +the instance location to be deprecated if any occurrence specifies a `true` +value. + +If `deprecated` has a value of boolean `true`, it indicates that applications +SHOULD refrain from usage of the declared property. It may mean the property is +going to be removed in the future. + +A root schema containing `deprecated` with a value of `true` indicates that the +entire resource being described may be removed in the future. + +The `deprecated` keyword applies to each instance location to which the schema +object containing the keyword successfully applies. This can result in scenarios +where every array item or object property is deprecated even though the +containing array or object is not. + +Omitting this keyword has the same behavior as a value of `false`. + +### `readOnly` and `writeOnly` + +The value of these keywords MUST be a boolean. When multiple occurrences of +these keywords are applicable to a single sub-instance, the resulting behavior +SHOULD be as for a `true` value if any occurrence specifies a `true` value, and +SHOULD be as for a `false` value otherwise. + +If `readOnly` has a value of boolean `true`, it indicates that the +corresponding value in the instance is +managed exclusively by the owning authority, and attempts by an +application to modify the value are expected to be ignored or +rejected by that owning authority. + +An instance document that is marked as `readOnly` for the entire document may be +ignored if sent to the owning authority, or may result in an error, at the +authority's discretion. + +If `writeOnly` has a value of boolean `true`, it indicates that the value is +never present when the instance is retrieved from the owning authority. It can +be present when sent to the owning authority to update or create the document +(or the resource it represents), but it will not be included in any updated or +newly created version of the instance. + +An instance document that is marked as `writeOnly` for the entire document may +be returned as a blank document of some sort, or may produce an error upon +retrieval, or have the retrieval request ignored, at the authority's discretion. + +For example, `readOnly` would be used to mark a database-generated serial number +as read-only, while `writeOnly` would be used to mark a password input field. + +These keywords can be used to assist in user interface instance generation. In +particular, an application MAY choose to use a widget that hides input values as +they are typed for write-only fields. + +Omitting these keywords has the same behavior as values of `false`. + +### `examples` + +The value of this keyword MUST be an array. There are no restrictions placed on +the values within the array. When multiple occurrences of this keyword are +applicable to a single sub-instance, implementations MUST provide a flat array +of all values rather than an array of arrays. + +This keyword can be used to provide sample JSON values associated with a +particular schema, for the purpose of illustrating usage. It is RECOMMENDED that +these values be valid against the associated schema. + +Implementations MAY use the value(s) of `default`, if present, as an additional +example. If `examples` is absent, `default` MAY still be used in this manner. + +## Security Considerations {#security} + +JSON Schema Validation assumes all the security considerations listed in the +JSON Schema Core specification. + +JSON Schema Validation allows the use of Regular Expressions, which have +numerous different (often incompatible) implementations. Some implementations +allow the embedding of arbitrary code, which is outside the scope of JSON Schema +and MUST NOT be permitted. Regular expressions can often also be crafted to be +extremely expensive to compute (with so-called "catastrophic backtracking"), +resulting in a denial-of-service attack. + +Implementations that support validating or otherwise evaluating instance string +data based on `contentEncoding` and/or `contentMediaType` are at risk of +evaluating data in an unsafe way based on misleading information. Applications +can mitigate this risk by only performing such processing when a relationship +between the schema and instance is established (e.g., they share the same +authority). + +Processing a media type or encoding is subject to the security considerations of +that media type or encoding. For example, the security considerations of [RFC +4329 Scripting Media Types](https://www.rfc-editor.org/info/rfc4329) apply when +processing JavaScript or ECMAScript encoded within a JSON string. + +## %appendix% Acknowledgments + +Thanks to Gary Court, Francis Galiegue, Kris Zyp, Geraint Luff, and Henry +Andrews for their work on the initial drafts of JSON Schema. + +Thanks to Jason Desrosiers, Daniel Perrett, Erik Wilde, Evgeny Poberezkin, Brad +Bowman, Gowry Sankar, Donald Pipowitch, Dave Finlay, Denis Laxalde, Phil +Sturgeon, Shawn Silverman, and Karen Etheridge for their submissions and patches +to the document. + +## %appendix% Change Log[^6] + +- *draft-next* + - Use IRIs instead of URIs + - Move "minContains" and "maxContains" to the applicator vocabulary (see also + that changelog) + - Remove the optional automatic second-pass validation of "content*" keywords + - Clarify that "contentSchema"'s value is a schema just like any other + subschema +- *draft-bhutton-json-schema-validation-01* + - Improve and clarify the `minContains` keyword explanation + - Remove the use of "production" in favour of "ABNF rule" +- *draft-bhutton-json-schema-validation-00* + - Correct email format RFC reference to 5321 instead of 5322 + - Clarified the set and meaning of `contentEncoding` values + - Reference ECMA-262, 11th edition for regular expression support + - Split `format` into an annotation only vocabulary and an assertion + vocabulary + - Clarify `deprecated` when applicable to arrays +- *draft-handrews-json-schema-validation-02* + - Grouped keywords into formal vocabularies + - Update `format` implementation requirements in terms of vocabularies + - By default, `format` MUST NOT be validated, although validation can be + enabled + - A vocabulary declaration can be used to require `format` validation + - Moved `definitions` to the core spec as `$defs` + - Moved applicator keywords to the core spec + - Renamed the array form of `dependencies` to `dependentRequired`, moved the + schema form to the core spec + - Specified all `content*` keywords as annotations, not assertions + - Added `contentSchema` to allow applying a schema to a string-encoded + document + - Also allow RFC 4648 encodings in `contentEncoding` + - Added `minContains` and `maxContains` + - Update RFC reference for nhostname" and "idn-hostname" + - Add "uuid" and "duration" formats +- *draft-handrews-json-schema-validation-01* + - This draft is purely a clarification with no functional changes + - Provided the general principle behind ignoring annotations under `not` and + similar cases + - Clarified `if`/`then`/`else` validation interactions + - Clarified `if`/`then`/`else` behavior for annotation + - Minor formatting and cross-referencing improvements +- *draft-handrews-json-schema-validation-00* + - Added `if`/`then`/`else` + - Classify keywords as assertions or annotations per the core spec + - Warn of possibly removing `dependencies` in the future + - Grouped validation keywords into sub-sections for readability + - Moved `readOnly` from hyper-schema to validation meta-data + - Added `writeOnly` + - Added string-encoded media section, with former hyper-schema `media` + keywords + - Restored "regex" format (removal was unintentional) + - Added "date" and "time" formats, and reserved additional RFC 3339 format + names + - I18N formats: "iri", "iri-reference", "idn-hostname", "idn-email" + - Clarify that "json-pointer" format means string encoding, not URI fragment + - Fixed typo that inverted the meaning of `minimum` and `exclusiveMinimum` + - Move format syntax references into Normative References + - JSON is a normative requirement +- *draft-wright-json-schema-validation-01* + - Standardized on hyphenated format names with full words ("uriref" becomes + "uri-reference") + - Add the formats "uri-template" and "json-pointer" + - Changed `exclusiveMaximum`/`exclusiveMinimum` from boolean modifiers of + `maximum`/`minimum` to independent numeric fields. + - Split the additionalItems/items into two sections + - Reworked properties/patternProperties/additionalProperties definition + - Added `examples` keyword + - Added `contains` keyword + - Allow empty `required` and `dependencies` arrays + - Fixed `type` reference to primitive types + - Added `const` keyword + - Added `propertyNames` keyword +- *draft-wright-json-schema-validation-00* + - Added additional security considerations + - Removed reference to "latest version" meta-schema, use numbered version + instead + - Rephrased many keyword definitions for brevity + - Added "uriref" format that also allows relative URI references +- *draft-fge-json-schema-validation-00* + - Initial draft. + - Salvaged from draft v3. + - Redefine the `required` keyword. + - Remove `extends`, `disallow` + - Add `anyOf`, `allOf`, `oneOf`, `not`, `definitions`, `minProperties`, + `maxProperties`. + - `dependencies` member values can no longer be single strings; at least one + element is required in a property dependency array. + - Rename `divisibleBy` to `multipleOf`. + - `type` arrays can no longer have schemas; remove `any` as a possible value. + - Rework the `format` section; make support optional. + - `format": remove attributes "phone", "style", "color"; rename "ip-address" + to "ipv4"; add references for all attributes. + - Provide algorithms to calculate schema(s) for array/object instances. + - Add interoperability considerations. + +## Authors' Addresses +| Author | Company | Email | URI | +| ------------------------ | ------- | -------------------- | ------------------------ | +| Austin Wright (*editor*) | | | | +| Ben Hutton (*editor*) | Postman | | | + +[^6]: This section to be removed before leaving Internet-Draft status. + +[rfc3987]: https://www.rfc-editor.org/info/rfc3987 +[rfc8259]: https://www.rfc-editor.org/info/rfc8259 diff --git a/specs/meta/README.md b/specs/meta/README.md new file mode 100644 index 00000000..709c56d8 --- /dev/null +++ b/specs/meta/README.md @@ -0,0 +1,77 @@ +# JSON Schema Meta-Schema + +The *meta.json* file contains the meta-schema for the in-progress JSON Schema +specifications. You can find the latest published version on the [JSON Schema +website](https://json-schema.org). + +## Table of Contents + +## Meta-Schemas + +A meta-schema is a schema that itself describes a schema. This is possible +because JSON Schema can be written as JSON. + +Furthermore, the JSON Schema meta-schema is self-validating. That is, its JSON +form validates against the meta-schema. + +## Extensions and Unknown Keywords + +The JSON Schema specification allows for extension keywords to be introduced, +however it also disallows unknown keywords. While seemingly contradictory, the +meta-schema has been set up to allow for extension. + +For this example, we'll add two hypothetical keywords: `odds` and `evens`, which +validate the odd and even indexed values in an array, respectively. + +First, create a schema that just defines the new keywords. + +```json +{ + "$schema": "https://json-schema.org/1", + "$id": "https://example.com/schema/odds-evens", + + "properties": { + "odds": { "$dynamicRef": "#meta" }, + "evens": { "$dynamicRef": "#meta" } + } +} +``` + +Second, create a new meta-schema that + +- references the above schema +- references the JSON Schema meta-schema +- includes an extension point in a `$defs` + +```json +{ + "$schema": "https://json-schema.org/1", + "$id": "https://example.com/schema/odds-evens-extension", + + "$ref": "https://json-schema.org/1", + + "$defs": { + "extension": { + "$dynamicAnchor": "extension", + "$ref": "https://example.com/schema/odds-evens" + } + } +} +``` + +Now you can use `https://example.com/schema/odds-evens-extension` in your +schemas to make use of the new `odds` and `evens` keywords. + +```json +{ + "$schema": "https://example.com/schema/odds-evens-extension", + "$id": "https://example.com/schema/model", + + "type": "array", + "odds": { "type": "string" }, + "evens": { "type": "number" } +} +``` + +This schema will validate arrays whose items alternate between strings and +numbers. diff --git a/schema.json b/specs/meta/meta.json similarity index 55% rename from schema.json rename to specs/meta/meta.json index 281912c6..f86e16c9 100644 --- a/schema.json +++ b/specs/meta/meta.json @@ -1,49 +1,27 @@ { - "$schema": "http://json-schema.org/draft-08/schema#", - "$id": "http://json-schema.org/draft-08/schema#", - "$recursiveAnchor": true, - "$recursiveRef": "core", + "$schema": "https://json-schema.org/1/2025", + "$id": "https://json-schema.org/1/2025", + "$dynamicAnchor": "meta", - "title": "Core and Validation specifications meta-schema", - "$defs": { - "schemaArray": { - "type": "array", - "minItems": 1, - "items": { "$recursiveRef": "#" } - }, - "nonNegativeInteger": { - "type": "integer", - "minimum": 0 - }, - "nonNegativeIntegerDefault0": { - "$ref": "#/$defs/nonNegativeInteger", - "default": 0 - }, - "simpleTypes": { - "enum": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ] - }, - "stringArray": { - "type": "array", - "items": { "type": "string" }, - "uniqueItems": true, - "default": [] - } - }, + "title": "JSON Schema Core and Validation specification meta-schema", "type": ["object", "boolean"], "properties": { - "definitions": { - "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.", + "$id": { + "$ref": "#/$defs/iriReferenceString", + "$comment": "Fragments not allowed.", + "pattern": "^[^#]*$" + }, + "$schema": { "$ref": "#/$defs/iriString" }, + "$ref": { "$ref": "#/$defs/iriReferenceString" }, + "$anchor": { "$ref": "#/$defs/anchorString" }, + "$dynamicRef": { "$ref": "#/$defs/iriReferenceString" }, + "$dynamicAnchor": { "$ref": "#/$defs/anchorString" }, + "$comment": { + "type": "string" + }, + "$defs": { "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "default": {} + "additionalProperties": { "$dynamicRef": "#meta" } }, "title": { "type": "string" @@ -52,14 +30,73 @@ "type": "string" }, "default": true, + "deprecated": { + "type": "boolean", + "default": false + }, "readOnly": { "type": "boolean", "default": false }, + "writeOnly": { + "type": "boolean", + "default": false + }, "examples": { "type": "array", "items": true }, + "prefixItems": { "$ref": "#/$defs/schemaArray" }, + "items": { "$dynamicRef": "#meta" }, + "maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, + "minContains": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 1 + }, + "contains": { "$dynamicRef": "#meta" }, + "additionalProperties": { "$dynamicRef": "#meta" }, + "properties": { + "type": "object", + "additionalProperties": { "$dynamicRef": "#meta" }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { "$dynamicRef": "#meta" }, + "propertyNames": { "format": "regex" }, + "default": {} + }, + "dependentSchemas": { + "type": "object", + "additionalProperties": { "$dynamicRef": "#meta" }, + "default": {} + }, + "propertyNames": { "$dynamicRef": "#meta" }, + "if": { "$dynamicRef": "#meta" }, + "then": { "$dynamicRef": "#meta" }, + "else": { "$dynamicRef": "#meta" }, + "allOf": { "$ref": "#/$defs/schemaArray" }, + "anyOf": { "$ref": "#/$defs/schemaArray" }, + "oneOf": { "$ref": "#/$defs/schemaArray" }, + "not": { "$dynamicRef": "#meta" }, + "unevaluatedItems": { "$dynamicRef": "#meta" }, + "unevaluatedProperties": { "$dynamicRef": "#meta" }, + "type": { + "anyOf": [ + { "$ref": "#/$defs/simpleTypes" }, + { + "type": "array", + "items": { "$ref": "#/$defs/simpleTypes" }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "const": true, + "enum": { + "type": "array", + "items": true + }, "multipleOf": { "type": "number", "exclusiveMinimum": 0 @@ -82,90 +119,86 @@ "type": "string", "format": "regex" }, - "additionalItems": { "$recursiveRef": "#" }, - "items": { - "anyOf": [ - { "$recursiveRef": "#" }, - { "$ref": "#/$defs/schemaArray" } - ] - }, "maxItems": { "$ref": "#/$defs/nonNegativeInteger" }, "minItems": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, "uniqueItems": { "type": "boolean", "default": false }, - "contains": { "$recursiveRef": "#" }, - "maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, - "minContains": { - "$ref": "#/$defs/nonNegativeInteger", - "default": 1 - }, "maxProperties": { "$ref": "#/$defs/nonNegativeInteger" }, "minProperties": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, "required": { "$ref": "#/$defs/stringArray" }, - "additionalProperties": { "$recursiveRef": "#" }, - "properties": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "default": {} - }, - "patternProperties": { - "type": "object", - "additionalProperties": { "$recursiveRef": "#" }, - "propertyNames": { "format": "regex" }, - "default": {} - }, - "dependentSchemas": { - "type": "object", - "additionalProperties": { - "$recursiveRef": "#" - } - }, "dependentRequired": { "type": "object", "additionalProperties": { "$ref": "#/$defs/stringArray" } }, - "dependencies": { - "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"", - "type": "object", - "additionalProperties": { - "anyOf": [ - { "$recursiveRef": "#" }, - { "$ref": "#/$defs/stringArray" } - ] - } + "format": { "type": "string" }, + "contentEncoding": { "type": "string" }, + "contentMediaType": { "type": "string" }, + "contentSchema": { "$dynamicRef": "#meta" }, + + "$vocabulary": { + "$comment": "Proposed keyword: https://github.com/json-schema-org/json-schema-spec/blob/main/specs/proposals/vocabularies.md" }, - "propertyNames": { "$recursiveRef": "#" }, - "const": true, - "enum": { + "propertyDependencies": { + "$comment": "Proposed keyword: https://github.com/json-schema-org/json-schema-spec/blob/main/specs/proposals/propertyDependencies.md" + } + }, + "patternProperties": { + "^x-": true + }, + "propertyNames": { + "pattern": "^[^$]|^\\$(id|schema|ref|anchor|dynamicRef|dynamicAnchor|comment|defs)$" + }, + "$dynamicRef": "#extension", + "unevaluatedProperties": false, + "$defs": { + "extension": { + "$dynamicAnchor": "extension" + }, + "anchorString": { + "type": "string", + "pattern": "^[A-Za-z_][-A-Za-z0-9._]*$" + }, + "iriString": { + "type": "string", + "format": "iri" + }, + "iriReferenceString": { + "type": "string", + "format": "iri-reference" + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "$ref": "#/$defs/nonNegativeInteger", + "default": 0 + }, + "schemaArray": { "type": "array", - "items": true, "minItems": 1, - "uniqueItems": true + "items": { "$dynamicRef": "#meta" } }, - "type": { - "anyOf": [ - { "$ref": "#/$defs/simpleTypes" }, - { - "type": "array", - "items": { "$ref": "#/$defs/simpleTypes" }, - "minItems": 1, - "uniqueItems": true - } + "simpleTypes": { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" ] }, - "format": { "type": "string" }, - "contentMediaType": { "type": "string" }, - "contentEncoding": { "type": "string" }, - "if": { "$recursiveRef": "#" }, - "then": { "$recursiveRef": "#" }, - "else": { "$recursiveRef": "#" }, - "allOf": { "$ref": "#/$defs/schemaArray" }, - "anyOf": { "$ref": "#/$defs/schemaArray" }, - "oneOf": { "$ref": "#/$defs/schemaArray" }, - "not": { "$recursiveRef": "#" } + "stringArray": { + "type": "array", + "items": { "type": "string" }, + "uniqueItems": true, + "default": [] + } } } diff --git a/specs/output/jsonschema-validation-output-machines.md b/specs/output/jsonschema-validation-output-machines.md new file mode 100644 index 00000000..2043b7a4 --- /dev/null +++ b/specs/output/jsonschema-validation-output-machines.md @@ -0,0 +1,620 @@ + +# A Specification for Machine-Readable Output for JSON Schema Validation and Annotation + +JSON Schema is defined to be platform-independent. As such, to increase +compatibility across platforms, implementations SHOULD conform to a standard +validation output format. This specification describes the minimum requirements +for machine consumers to properly interpret validation results. + +## Table of Contents + +## Schema Identifiers + +The output defined in this specification requires that the evaluation root be +defined with an absolute IRI, i.e. using the `$id` keyword. In the event an +absolute IRI has not been defined, the implementation MUST generate one. + +There are no requirements on the form of IRI itself, except that it MUST be +absolute. + +## Textual Format and Encoding + +JSON Schema output is defined using the JSON Schema data instance model as +described in [JSON Schema](../jsonschema-core.md) "Instance Data Model". +Implementations MAY deviate from this in their internal modelling, as supported +by their specific languages and platforms, however it is RECOMMENDED that the +output be convertible to the JSON format defined herein via serialization or +other means. + +## Minimum Information + +Beyond the simplistic "flag" output, additional information is useful to aid in +debugging evaluation of an instance by a schema. + +The output of a subschema validation is considered an "output unit." The +contents of each output unit is specified by this section. + +Each output unit MUST contain the [validation result](#validation-result) for +the associated subschema as well as the following information defined by +[JSON Schema](../jsonschema-core.md) "Output Formatting": + +- Evaluation Path +- Schema Location +- Instance Location + +The following information MAY be included conditionally: + +- When subschema validation has succeeded + - Annotations +- When subschema validation has failed + - Errors + - Dropped Annotations + +Implementations MAY elect to provide additional information. + +### Validation Result {#validation-result} + +The validation result is a boolean that indicates whether the local instance +passed validation by the local subschema. + +The JSON key for these additional results is `valid`. + +### Results from Subschemas + +Evaluation results generated by applying a subschema to the instance or a child +of the instance. Keywords which have multiple subschemas (e.g. `anyOf`) will +generally generate an output unit for each subschema. In order to accommodate +potentially multiple results, the value of this property MUST be an array of +output units, even if only a single output unit is produced. + +For "list", this property will appear only at the root output unit and will hold +all output units in a flat list. + +For "hierarchical", this property will contain results in a tree structure where +each output unit may itself have further nested results. + +The sequence of output units within this list is not specified and MAY be +determined by the implementation. Sets of output units are considered equivalent +if they contain the same units, in any order. + + + +The JSON key for these additional results is `details`. + +## Output Structure {#output-structure} + +This specification defines three output formats. + +- **Flag** - A boolean which simply indicates the overall validation result with + no further details. +- **List** - Provides validation information in a flat list structure. +- **Hierarchical** - Provides validation information in a hierarchical structure + that follows the evaluation paths generated while processing the schema. + +An implementation MUST provide the "flag" format and SHOULD provide at least one +of the "list" or "hierarchical" formats. Implementations SHOULD specify in their +documentation which formats they support. + +For these examples, the following schema and instances will be used. + +```jsonschema "Example Schema" +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://json-schema.org/schemas/example", + "type": "object", + "title": "root", + "properties": { + "foo": { + "allOf": [ + { "required": ["unspecified-prop"] }, + { + "type": "object", + "title": "foo-title", + "properties": { + "foo-prop": { + "const": 1, + "title": "foo-prop-title" + } + }, + "additionalProperties": { "type": "boolean" } + } + ] + }, + "bar": { "$ref": "#/$defs/bar" } + }, + "$defs": { + "bar": { + "type": "object", + "title": "bar-title", + "properties": { + "bar-prop": { + "type": "integer", + "minimum": 10, + "title": "bar-prop-title" + } + } + } + } +} +``` + +```json "Failing Instance" +{ + "foo": { "foo-prop": "not 1", "other-prop": false }, + "bar": { "bar-prop": 2 } +} +``` + +```json "Passing Instance" +{ + "foo": { + "foo-prop": 1, + "unspecified-prop": true + }, + "bar": { "bar-prop": 20 } +} +``` + +The failing instance will produce the following errors: + +- The instance value at `/foo` + evaluated at `/properties/foo/allOf/0` + by following the path `/properties/foo/allOf/0` + by the `required` keyword + is missing the property `unspecified-prop`. +- The value at `/foo/foo-prop` + evaluated at `/properties/foo/allOf/1/properties/foo-prop` + by following the path `/properties/foo/allOf/1/properties/foo-prop` + by the `const` keyword + is not the constant value 1. +- The value at `/bar/bar-prop` + evaluated at `/$defs/bar/properties/bar-prop` + by following the path `/properties/bar/$ref/properties/bar-prop` + by the `type` keyword + is not a number. + + + + +The passing instance will produce the following annotations: + +- The keyword `title` + evaluated at `` + by following the path `` + will produce `"root"`. +- The keyword `properties` + evaluated at `` + by following the path `` + will produce `["foo", "bar"]`. +- The keyword `title` + evaluated at `/properties/foo` + by following the path `/properties/foo` + will produce `"foo-title"`. +- The keyword `properties` + evaluated at `/properties/foo/allOf/1` + by following the path `/properties/foo/allOf/1` + will produce `["foo-prop"]`. +- The keyword `additionalProperties` + evaluated at `/properties/foo/allOf/1` + by following the path `/properties/foo/allOf/1` + will produce `["unspecified-prop"]`. +- The keyword `title` + evaluated at `/properties/foo/allOf/1/properties/foo-prop` + by following the path `/properties/foo/allOf/1/properties/foo-prop` + will produce `"foo-prop-title"`. +- The keyword `title` + evaluated at `/$defs/bar` + by following the path `/properties/bar/$ref` + will produce `"bar-title"`. +- The keyword `properties` + evaluated at `/$defs/bar` + by following the path `/properties/var/$ref` + will produce `["bar-prop"]`. +- The keyword `title` + evaluated at `/$defs/bar/properties/bar-prop` + by following the path `/properties/bar/$ref/properties/bar-prop` + will produce `"bar-prop-title"`. + +### Flag + +In the simplest case, merely the boolean result for the `valid` valid property +needs to be fulfilled. For this format, all other information is explicitly +omitted. + +```json "Flag Results" +{ + "valid": false +} +``` + +Because no errors or annotations are returned with this format, it is +RECOMMENDED that implementations use short-circuiting logic to return failure or +success as soon as the outcome can be determined. For example, if an `anyOf` +keyword contains five subschemas, and the second one passes, there is no need to +check the other three. The logic can simply return with success. + +### List + +The "list" structure is a flat list of output units contained within a root +output unit. + +The root output unit contains `valid` for the overall result and `details` for +the list of specific results. All other information is explicitly omitted from +the root output unit. If the root schema produces errors or annotations, then +the output node for the root MUST be present within the root output unit's +`details` list with those errors or annotations. + +Output units which do not contain errors or annotations SHOULD be excluded from +this format, however implementations MAY choose to include them for +completeness. + +```json "Failing Results" +{ + "valid": false, + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/0", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/0", + "instanceLocation": "/foo", + "errors": { + "required": "Required properties [\"unspecified-prop\"] were not present" + } + }, + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "errors": { + "const": "Expected \"1\"" + } + }, + { + "valid": false, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "errors": { + "minimum": "2 is less than or equal to 10" + } + } + ] +} +``` + +```json "Passing Results" +{ + "valid": true, + "details": [ + { + "valid": true, + "evaluationPath": "", + "schemaLocation": "https://json-schema.org/schemas/example#", + "instanceLocation": "", + "annotations": { + "title": "root", + "properties": [ + "foo", + "bar" + ] + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1", + "instanceLocation": "/foo", + "annotations": { + "title": "foo-title", + "properties": [ + "foo-prop" + ], + "additionalProperties": [ + "unspecified-prop" + ] + } + }, + { + "valid": true, + "evaluationPath": "/properties/bar/$ref", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar", + "instanceLocation": "/bar", + "annotations": { + "title": "bar-title", + "properties": [ + "bar-prop" + ] + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "annotations": { + "title": "foo-prop-title" + } + }, + { + "valid": true, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "annotations": { + "title": "bar-prop-title" + } + } + ] +} +``` + +### Hierarchical + +The "Hierarchical" structure is a tree structure that follows the evaluation +path during the validation process. Typically, it will resemble the schema as if +all referenced schemas were inlined in place of their associated by-reference +keywords. + +All output units are included in this format. + +The location properties of the root output unit MAY be omitted. + +```json "failing Results +{ + "valid": false, + "evaluationPath": "", + "schemaLocation": "https://json-schema.org/schemas/example#", + "instanceLocation": "", + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo", + "instanceLocation": "/foo", + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/0", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/0", + "instanceLocation": "/foo", + "errors": { + "required": "Required properties [\"unspecified-prop\"] were not present" + } + }, + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/1", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1", + "instanceLocation": "/foo", + "droppedAnnotations": { + "properties": [ "foo-prop" ], + "title": "foo-title" + }, + "details": [ + { + "valid": false, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "errors": { + "const": "Expected \"1\"" + }, + "droppedAnnotations": { + "title": "foo-prop-title" + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/additionalProperties", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/additionalProperties", + "instanceLocation": "/foo/other-prop" + } + ] + } + ] + }, + { + "valid": false, + "evaluationPath": "/properties/bar", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/bar", + "instanceLocation": "/bar", + "details": [ + { + "valid": false, + "evaluationPath": "/properties/bar/$ref", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar", + "instanceLocation": "/bar", + "droppedAnnotations": { + "properties": [ "bar-prop" ], + "title": "bar-title" + }, + "details": [ + { + "valid": false, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "errors": { + "minimum": "2 is less than or equal to 10" + }, + "droppedAnnotations": { + "title": "bar-prop-title" + } + } + ] + } + ] + } + ] +} +``` + +```json "Passing Results +{ + "valid": true, + "evaluationPath": "", + "schemaLocation": "https://json-schema.org/schemas/example#", + "instanceLocation": "", + "annotations": { + "title": "root", + "properties": [ + "foo", + "bar" + ] + }, + "details": [ + { + "valid": true, + "evaluationPath": "/properties/foo", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo", + "instanceLocation": "/foo", + "details": [ + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/0", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/0", + "instanceLocation": "/foo" + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1", + "instanceLocation": "/foo", + "annotations": { + "title": "foo-title", + "properties": [ + "foo-prop" + ], + "additionalProperties": [ + "unspecified-prop" + ] + }, + "details": [ + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/properties/foo-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/properties/foo-prop", + "instanceLocation": "/foo/foo-prop", + "annotations": { + "title": "foo-prop-title" + } + }, + { + "valid": true, + "evaluationPath": "/properties/foo/allOf/1/additionalProperties", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/foo/allOf/1/additionalProperties", + "instanceLocation": "/foo/unspecified-prop" + } + ] + } + ] + }, + { + "valid": true, + "evaluationPath": "/properties/bar", + "schemaLocation": "https://json-schema.org/schemas/example#/properties/bar", + "instanceLocation": "/bar", + "details": [ + { + "valid": true, + "evaluationPath": "/properties/bar/$ref", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar", + "instanceLocation": "/bar", + "annotations": { + "title": "bar-title", + "properties": [ + "bar-prop" + ] + }, + "details": [ + { + "valid": true, + "evaluationPath": "/properties/bar/$ref/properties/bar-prop", + "schemaLocation": "https://json-schema.org/schemas/example#/$defs/bar/properties/bar-prop", + "instanceLocation": "/bar/bar-prop", + "annotations": { + "title": "bar-prop-title" + } + } + ] + } + ] + } + ] +} +``` + +## Output validation schemas + +For convenience, JSON Schema has been provided to validate output generated by +implementations. Its IRI is: + +## Filtering + +For various reasons, including human readability and performance during +evaluation, a user may desire to omit certain details from the output. To +address this, implementations MAY provide filtering output information. + +This section defines several RECOMMENDED approaches to filtering, however +implementations MAY choose to provide these features in a way that suits them +and their users best. + +For those implementations which support filtering behaviors, the behaviors MUST +be configurable and disabled by default. + +### Annotation Filtering + +Collecting and storing annotations can require increasing amounts of system +resources as evaluation proceeds. The strain on systems can be reduced by only +collecting those annotations which users care about. + +For annotation filtering, implementations SHOULD provide a mechanism which +allows users to configure either the set annotations they would like to keep or +the set they would like to ignore. + +For a "keep" list, an implementation MUST include in the output only those +annotations which are configured. + +For an "ignore" list, an implementation MUST NOT include in the output those +annotations which are configured. + +#### Annotations Required for Evaluation + +Some implementations may be annotation-driven. That is, the evaluation of some +keywords depends on the annotation results of other keywords. For example, which +properties are seen by `additionalProperties` can be determined by looking at +the annotation results of `properties` and `patternProperties`. + +For these implementations, the annotation results of these dependent keywords +must still be collected for proper evaluation. However, these annotations MUST +NOT be included in the output unless they are configured accordingly. + +### Output Unit Pruning + +In many cases, the output structures defined herein produce output units for +more than is necessary to identify evaluation issues. Implementations SHOULD +provide a mechanism which removes unimportant output units from the final +structure in order to highlight those units which impact the final result. + +Reasons to omit output units may include, but are not limited to: + +- Child output units whose validation result does not impact the validation + result of the parent. For example, a subschema of an `anyOf` which has a false + validation result when there exists a sibling subschema with a true validation + result. +- Child output units which have a true validation result but contain no + annotations. + +Output units which include annotations MUST NOT be pruned. + +Implementations which provide this behavior SHOULD provide configuration +mechanisms appropriate for their users' needs. diff --git a/specs/output/schema.json b/specs/output/schema.json new file mode 100644 index 00000000..b4cc9cec --- /dev/null +++ b/specs/output/schema.json @@ -0,0 +1,95 @@ +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://json-schema.org/draft/next/output/schema", + "description": "A schema that validates the minimum requirements for validation output", + + "anyOf": [ + { "$ref": "#/$defs/flag" }, + { "$ref": "#/$defs/list" }, + { "$ref": "#/$defs/hierarchical" } + ], + "$defs": { + "outputUnit":{ + "properties": { + "valid": { "type": "boolean" }, + "evaluationPath": { + "type": "string", + "format": "json-pointer" + }, + "schemaLocation": { + "type": "string", + "format": "uri" + }, + "instanceLocation": { + "type": "string", + "format": "json-pointer" + }, + "details": { + "$ref": "#/$defs/outputUnitArray" + }, + "annotations": { + "type": "object", + "additionalProperties": true + }, + "droppedAnnotations": { + "type": "object", + "additionalProperties": true + }, + "errors": { + "type": "object", + "additionalProperties": { "type": "string" } + } + }, + "required": [ "valid", "evaluationPath", "schemaLocation", "instanceLocation" ], + "allOf": [ + { + "if": { + "anyOf": [ + { + "required": [ "errors" ] + }, + { + "required": [ "droppedAnnotations" ] + } + ] + }, + "then": { + "properties": { + "valid": { "const": false } + } + } + }, + { + "if": { + "required": [ "annotations" ] + }, + "then": { + "properties": { + "valid": { "const": true } + } + } + } + ] + }, + "outputUnitArray": { + "type": "array", + "items": { "$ref": "#/$defs/outputUnit" } + }, + "flag": { + "properties": { + "valid": { "type": "boolean" } + }, + "required": [ "valid" ] + }, + "list": { + "properties": { + "valid": { "type": "boolean" }, + "details": { + "$ref": "#/$defs/outputUnitArray" + } + }, + "required": [ "valid", "details" ] + }, + "hierarchical": { "$ref": "#/$defs/outputUnit" } + } +} diff --git a/specs/proposals/propertyDependencies-adr.md b/specs/proposals/propertyDependencies-adr.md new file mode 100644 index 00000000..04db71fc --- /dev/null +++ b/specs/proposals/propertyDependencies-adr.md @@ -0,0 +1,300 @@ +# Add New Keyword: `propertyDependencies` + +- Status: proposed +- Deciders: @gregsdennis, @jdesrosiers, @relequestual +- Date: 2022-04-07 + +Technical Story: + +- Issue discussing feature - +- PR to add to the spec - +- ADR to extract from the spec and use feature life cycle - + +## Table of Contents + +## Context and Problem Statement + +A common need in JSON Schema is to select between one schema or another to +validate an instance based on the value of some property in the JSON instance. +There are a several patterns people use to accomplish this, but they all have +significant [problems](#problems). + +OpenAPI solves this problem with the `discriminator` keyword. However, their +approach is more oriented toward code generation concerns, is poorly specified +when it comes to validation, and is coupled to OpenAPI concepts that don't exist +is JSON Schema. Therefore, it's necessary to define something new rather than +adopt or redefine `discriminator`. + +## Decision Drivers + +- Ease of use +- Readability +- Coverage of most common use cases +- Coverage of all use cases +- Ease of implementation + +## Considered Options + +All of the following options have the same validation result as the following +schema. + +```json +{ + "if": { + "properties": { + "foo": { "const": "aaa" } + }, + "required": ["foo"] + }, + "then": { "$ref": "#/$defs/foo-aaa" } +} +``` + + +### Option 1 + +The `dependentSchemas` keyword is very close to what is needed except it checks +for the presence of a property rather than it's value. This option builds on +that concept to solve this problem. + +```json +{ + "propertyDependencies": { + "foo": { + "aaa": { "$ref": "#/$defs/foo-aaa" } + } + } +} +``` + +- Good, because it handle the most common use case: string property values +- Good, because all property values are grouped together +- Good, because it's less verbose +- Bad, because it doesn't handle non-string property values + +### Option 2 + +This version uses an array of objects. Each object is a collection of the +variables needed to express a property dependency. This doesn't fit the style of +JSON Schema. There aren't any keywords remotely like this. It's also still too +verbose. It's a little more intuitive than `if`/`then` and definitely less error +prone. + +```jsonschema +{ + "propertyDependencies": [ + { + "propertyName": "foo", + "propertySchema": { "const": "aaa" }, + "apply": { "$ref": "#/$defs/foo-aaa" } + }, + { + "propertyName": "foo", + "propertySchema": { "const": "bbb" }, + "apply": { "$ref": "#/$defs/foo-bbb" } + } + ] +} +``` + +* Good, because it supports all use cases +* Bad, because properties are not naturally grouped together +* Bad, because it's quite verbose +* Bad, because we have no precedent for a keyword which explicitly defines its + own properties. This would be new operational functionality, which we try to + avoid if we can. + +### Option 3 + +A slight variation on that example is to make it a map of keyword to dependency +object. It's still too verbose. + +```jsonschema +{ + "propertyDependencies": { + "foo": [ + { + "propertySchema": { "const": "aaa" }, + "apply": { "$ref": "#/$defs/foo-aaa" } + }, + { + "propertySchema": { "const": "bbb" }, + "apply": { "$ref": "#/$defs/foo-bbb" } + } + ] + } +} +``` + +* Good, because it supports all use cases +* Good, because all property values are grouped together +* Bad, because it's quite verbose +* Bad, because we have no precedent for a keyword which explicitly defines its + own properties. This would be new operational functionality, which we try to + avoid if we can. + +### Option 4 + +This one is a little more consistent with the JSON Schema style (poor keyword +naming aside), but otherwise has all the same problems as the other examples. + +```jsonschema +{ + "allOf": [ + { + "propertyDependencyName": "foo", + "propertyDependencySchema": { "const": "aaa" }, + "propertyDependencyApply": { "$ref": "#/$defs/foo-aaa" } + }, + { + "propertyDependencyName": "foo", + "propertyDependencySchema": { "const": "bbb" }, + "propertyDependencyApply": { "$ref": "#/$defs/foo-bbb" } + } + ] +} +``` + +- Good, because it supports all use cases +- Bad, because properties are not naturally grouped together +- Bad, because it's very verbose +- Bad, because it introduces a lot of inter-keyword dependencies, which we'd + have to exhaustively define + +### Option 5 + +This one is a variation of `if` that combines `if`, `properties`, and `required` +to reduce boilerplate. It's also essentially a variation of the previous example +with better names. This avoids to error proneness problem, but it's still too +verbose. + +```jsonschema +{ + "allOf": [ + { + "ifProperties": { + "foo": { "const": "aaa" } + }, + "then": { "$ref": "#/$defs/foo-aaa" } + }, + { + "ifProperties": { + "foo": { "const": "bbb" } + }, + "then": { "$ref": "#/$defs/foo-aaa" } + } + ] +} +``` + +* Good, because it supports all use cases +* Good, because it's a familiar syntax +* Bad, because properties are not naturally grouped together +* Bad, because it's very verbose +* Bad, because `ifProperties` is very niche. Will this spawn a new series of + `if*` keywords? How would it interact with `if`? + +### Option 6 + +All of the previous alternatives use a schema as the discriminator. This +alternative is a little less powerful in that it can only match on exact values, +but it successfully addresses the problems we're concerned about with the +current approaches. The only issue with this alternative is that it's not as +intuitive as the chosen solution. + +```jsonschema +{ + "propertyDependencies": { + "foo": [ + ["aaa", { "$ref": "#/$defs/foo-aaa" }], + ["bbb", { "$ref": "#/$defs/foo-bbb" }] + ] + } +} +``` + +* Good, because it supports all use cases +* Bad, because it's an unintuitive syntax and easy to get wrong +* Bad, because properties are not naturally grouped together + +## Decision Outcome + +Option 1 was chosen because it satisfies the most common use cases while being +sufficiently readable and easy to implement, even though it does not satisfy +_all_ use cases, such as those where the property value is not a string. As +these cases are significantly less common, the requirement to support all use +cases carried a lower priority. + +### Positive Consequences + +- Some level of built-in support for a `discriminator`-like keyword that aligns + with the existing operation of JSON Schema. + +### Negative Consequences + +- Properties with non-string values cannot be supported using this keyword and + the `allOf`-`if`-`then` pattern must still be used. + +## %appendix% Problems With Existing Patterns {#problems} + +### `oneOf`/`anyOf` + +The pattern of using `oneOf` to describe a choice between two schemas has become +ubiquitous. + +```jsonschema +{ + "oneOf": [ + { "$ref": "#/$defs/aaa" }, + { "$ref": "#/$defs/bbb" } + ] +} +``` + +However, this pattern has several shortcomings. The main problem is that it +tends to produce confusing error messages. Some implementations employ +heuristics to guess the user's intent and provide better messaging, but that's +not wide-spread or consistent behavior, nor is it expected or required from +implementations. + +This pattern is also inefficient. Generally, there is a single value in the +object that determines which alternative to chose, but the `oneOf` pattern has +no way to specify what that value is and therefore needs to evaluate the entire +schema. This is made worse in that every alternative needs to be fully validated +to ensure that only one of the alternative passes and all the others fail. This +last problem can be avoided by using `anyOf` instead, but that pattern is much +less used. + +### `if`/`then` + +We can describe this kind of constraint more efficiently and with with better +error messaging by using `if`/`then`. This allows the user to explicitly specify +the constraint to be used to select which alternative the schema should be used +to validate the schema. However, this pattern has problems of it's own. It's +verbose, error prone, and not particularly intuitive, which leads most people to +avoid it. + +```jsonschema +{ + "allOf": [ + { + "if": { + "properties": { + "foo": { "const": "aaa" } + }, + "required": ["foo"] + }, + "then": { "$ref": "#/$defs/foo-aaa" } + }, + { + "if": { + "properties": { + "foo": { "const": "bbb" } + }, + "required": ["foo"] + }, + "then": { "$ref": "#/$defs/foo-bbb" } + } + ] +} +``` diff --git a/specs/proposals/propertyDependencies.md b/specs/proposals/propertyDependencies.md new file mode 100644 index 00000000..2e7685f7 --- /dev/null +++ b/specs/proposals/propertyDependencies.md @@ -0,0 +1,142 @@ +# JSON Schema Proposal: The `propertyDependencies` Keyword + +## Abstract + +The `propertyDependencies` keyword is a more friendly way to select between two +or more schemas to validate an instance against than is currently supported by +JSON Schema. + +## Current Status + +This proposal is complete and awaiting integration into the specification. + +As some additional context, this proposal has been written prior to the stable +specification's initial release. As such, it will not be integrated until at +least the spec's second release at the earliest. It is also operating as a +proving grounds, of sorts, for the SDLC's Feature Life Cycle. + +## Note to Readers + +The issues list for this document can be found at +. + +For additional information, see . + +To provide feedback, use this issue tracker or any of the communication methods +listed on the homepage. + +## Table of Contents + +## Conventions and Terminology + +All conventions and terms used and defined by the [JSON Schema Core +specification](../jsonschema-core.md) also apply to this document. + +## Overview + +### Problem Statement + +A common need in JSON Schema is to select between one schema or another to +validate an instance based on the value of some property in the JSON instance. +There are a several patterns people use to accomplish this, but they all have +significant [problems](propertyDependencies-adr.md#problems). + +OpenAPI solves this problem with the `discriminator` keyword. However, their +approach is more oriented toward code generation concerns, is poorly specified +when it comes to validation, and is coupled to OpenAPI concepts that don't exist +is JSON Schema. Therefore, it's necessary to define something new rather than +adopt or redefine `discriminator`. + +### Solution + +The `dependentSchemas` keyword is very close to what is needed except it checks +for the presence of a property rather than it's value. The chosen solution is to +build on that concept to solve this problem. + +```json +{ + "propertyDependencies": { + "foo": { + "aaa": { "$ref": "#/$defs/foo-aaa" } + } + } +} +``` + +The validation result is equivalent to the following schema. + +```json +{ + "if": { + "properties": { + "foo": { "const": "aaa" } + }, + "required": ["foo"] + }, + "then": { "$ref": "#/$defs/foo-aaa" } +} +``` + +### Limitations + +The problem of choosing an alternative based on a property value could apply for +a value of any JSON type, but `propertyDependencies` only solves this problem +when the value is a string. One of the main goals of this keyword is to define +something that's intuitive enough and easy enough to use that people will +actually use it rather than fallback to `oneOf` because it's simple. Achieving +those goals means that some trade-offs need to be made. + +## Change Description + +The `propertyDependencies` keyword will be added to the +`https://json-schema.org/vocab/applicator` [applicator +vocabulary](../jsonschema-core.md#applicators). + +1. The following will be added to the JSON Schema Core specification as a + subsection of "Keywords for Applying Subschemas Conditionally". + + > ### `propertyDependencies` + > + > This keyword specifies subschemas that are evaluated if the instance is an + > object and contains a certain property with a certain string value. + > + > This keyword's value MUST be an object. Each value in the object MUST be + > an object whose values MUST be valid JSON Schemas. + > + > If the outer object key is a property in the instance and the inner object + > key is equal to the value of that property, the entire instance must + > validate against the schema. Its use is dependent on the presence and + > value of the property. + > + > Omitting this keyword has the same behavior as an empty object. + +1. The following subschema will be added to the Applicator Vocabulary schema, + `https://json-schema.org///meta/applicator` at + `/properties/propertyDependencies`: + + ```json + { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "$dynamicRef": "#meta", + "default": true + }, + "default": {} + } + } + ``` + +## %appendix% Change Log + +- \[March 2021\] - Initially proposed +- \[October 2021\] Added to specification document +- \[May 2024\] Extracted from specification document as experimental feature + +## Champions + +| Champion | Company | Email | URI | +| -------------------------- | ------- | -------------------- | -------------------------------- | +| Jason Desrosiers | Postman | | | diff --git a/specs/proposals/proposal-template.md b/specs/proposals/proposal-template.md new file mode 100644 index 00000000..e187380d --- /dev/null +++ b/specs/proposals/proposal-template.md @@ -0,0 +1,92 @@ +# JSON Schema Proposal: + +## Abstract + + + +This document proposes a change to the ??? specification by adding ???. + +## Current Status + + + +## Note to Readers + + + +The issues list for this proposal can be found at +. + +For additional information, see . + +To provide feedback, use this issue tracker or any of the communication methods +listed on the homepage. + +## Table of Contents + +## Conventions and Terminology + +All conventions and terms used and defined by the JSON Schema Core specification +also apply to this document. + +## Overview + +### Problem Statement + + + +### Solution + + + +### Limitations + + + +## Change Details + + + +## %appendix% Change Log + +- \[MMMM YYYY\] Created + +## %appendix% Champions + +| Champion | Company | Email | URI | +| -------------------------- | ------- | ----------------------- | -------------------------------- | +| Your Name | | | < GitHub profile page > | diff --git a/specs/proposals/vocabularies-adr.md b/specs/proposals/vocabularies-adr.md new file mode 100644 index 00000000..3e12eaa3 --- /dev/null +++ b/specs/proposals/vocabularies-adr.md @@ -0,0 +1,81 @@ +# Add Vocabulary System + +- Status: proposed +- Deciders: @gregsdennis, @jdesrosiers +- Date: 2024-06-10 + +Technical Story: + +- Issues discussing feature - +- ADR to extract from the spec and use feature life cycle - + +## Table of Contents + +## Context and Problem Statement + +The current approach to extending JSON Schema by providing custom keywords is +very implementation-specific and therefore not interoperable. + +To address this deficiency, this document proposes vocabularies as a concept +and a new Core keyword, `$vocabulary` to support it. + +## Decision Drivers + +- Language-agnostic +- Ease of use +- Ease of implementation + +## Considered Options + +### Current design as included in 2019-09 and 2020-12. + +A vocabulary is a collection of keywords and is defined by a vocabulary +document. For the 2019-09 and 2020-12 vocabularies, the documents are integrated +into the specifications themselves. + +With vocabularies as the primary method for defining individual keywords, +dialects can be created by combining different vocabularies. + +Users must confirm with an implementation's documentation whether a given +vocabulary is supported. + +`$vocabulary` keyword is an object with URI keys and boolean values. The URIs +identify each vocab, and the values indicate whether the implementation must +"understand" that vocab in order to process the schema. This keyword is only +processed when it is found as part of a meta-schema. + +- Good because it provides a language-agnostic method of defining extension + keywords that's built into JSON Schema itself +- Bad because unknown keywords are now unsupported, which implies that + [unknown vocabularies are implicitly + unsupported](https://github.com/orgs/json-schema-org/discussions/342) + +### [option 2] + +[example | description | pointer to more information | …] + +- Good, because [argument a] +- Good, because [argument b] +- Bad, because [argument c] +- ... + +### [option 3] + +[example | description | pointer to more information | …] + +- Good, because [argument a] +- Good, because [argument b] +- Bad, because [argument c] +- ... + +## Decision Outcome + +*TBD* + +### Positive Consequences + +*TBD* + +### Negative Consequences + +*TBD* diff --git a/specs/proposals/vocabularies.md b/specs/proposals/vocabularies.md new file mode 100644 index 00000000..2ddd86ea --- /dev/null +++ b/specs/proposals/vocabularies.md @@ -0,0 +1,269 @@ +# JSON Schema Proposal: + +## Abstract + +The current approach to extending JSON Schema by providing custom keywords is +very implementation-specific and therefore not interoperable. + +To address this deficiency, this document proposes vocabularies as a concept +and a new Core keyword, `$vocabulary`, to support it. + +While the Core specification will define and describe vocabularies in general, +the Validation specification will also need to change to incorporate some of +these ideas. This proposal will be updated as necessary to reflect the changes +in both documents. + +## Current Status + +This proposal was originally integrated into both specifications, starting with +the 2019-09 release. For the upcoming stable release, the feature has been +extracted as it is incomplete. The feature, at best effort, was extracted in +such a way as to retain the functionality present in the 2020-12 release. + +Trying to fit the 2020-12 version into the current specification, however, +raises some problems, and further discussion around the design of +this concept is needed. + +## Note to Readers + +The issues list for this proposal can be found at +. + +For additional information, see . + +To provide feedback, use this issue tracker or any of the communication methods +listed on the homepage. + +## Table of Contents + +## Conventions and Terminology + +All conventions and terms used and defined by the JSON Schema Core specification +also apply to this document. + +## Overview + +### Problem Statement + +To support extensibility, the specification allows implementations to support +keywords that are not defined in the specifications themselves. However, this +vague and open allowance has drawbacks. + +1. Such support is not a requirement; it is a permission. An implementation + could just as easily (_more_ easily) choose _not_ to support extension + keywords. +2. There is no prescribed mechanism by which an implementation should provide + this support. As a result, each implementation that _does_ have the feature + supports it in different ways. +3. Support for any given user-defined keyword will be limited to the + implementations which are explicitly configured for that keyword. For a user + defining their own keyword, this becomes difficult and/or impossible + depending on the varying support for extension keywords offered by the + implementations the user is using. + +This exposes a need for an implementation-agnostic approach to +externally-defined keywords as well as a way for implementations to declare +support for them. + +### Solution + +This proposal introduces vocabularies as a new concept to be added to the Core +specification. + +A vocabulary is identified by an absolute URI and is used to define a set of +keywords. A vocabulary is generally defined in a human-readable _vocabulary +description document_. (The URI for the vocabulary may be the same as the URL of +where this vocabulary description document can be found, but no recommendation +is made either for or against this practice.) + +A new keyword, `$vocabulary`, will be introduced into the Core specification as +well. This keyword's value is an object with vocabulary URIs as keys and +booleans as values. This keyword only has meaning within a meta-schema. A +meta-schema which includes a vocabulary's URI in its `$vocabulary` keyword is +said to "include" that vocabulary. + +```jsonc +{ + "$schema": "https://example.org/draft/next/schema", + "$id": "https://example.org/schema", + "$vocabulary": { + "https://example.org/vocab/vocab1": true, + "https://example.org/vocab/vocab2": true, + "https://example.org/vocab/vocab3": false + }, + // ... +} +``` + +Whereas in the current specification, a dialect is merely the set of keywords +used by a schema, with this proposal a dialect is defined by the set of +vocabularies listed by a meta-schema. It is ephemeral and carries no identifier. + +_**NOTE** It is possible for two meta-schemas, which would have different `$id` +values, to share a common dialect if they both declare the same set of +vocabularies._ + +A schema that declares a meta-schema (via `$schema`) which contains +`$vocabulary` is declaring that only those keywords defined by the included +vocabularies are to be processed when evaluating the schema. All other keywords +are to be considered "unknown" and handled accordingly. + +The boolean values in `$vocabulary` signify implementation requirements for each +vocabulary. + +- A `true` value indicates that the implementation must recognize the vocabulary + and be able to process each of the keywords defined in it. If an + implementation does not recognize the vocabulary or cannot process all of its + defined keywords, the implementation must refuse to process the schema. These + vocabularies are also known as "required" vocabularies. +- A `false` value indicates that the implementation is not required to recognize + the vocabulary or its keywords and may continue processing the schema anyway. + However, keywords that are not recognized or supported must be considered + "unknown" and handled accordingly. These vocabularies are also known as + "optional" vocabularies. + +Typically, but not required, a schema will accompany the vocabulary description +document. This _vocabulary schema_ should carry an `$id` value which is distinct +from the vocabulary URI. The purpose of the vocabulary schema is to provide +syntactic validation for the the vocabulary's keywords' values for when the +schema is being validated by a meta-schema that includes the vocabulary. (A +vocabulary schema is not itself a meta-schema since it does not validate entire +schemas.) To facilitate this extra validation, when a vocabulary schema is +provided, any meta-schema which includes the vocabulary should also contain a +reference (via `$ref`) to the vocabulary schema's `$id` value. + +```jsonc +{ + "$schema": "https://example.org/draft/next/schema", + "$id": "https://example.org/schema", + "$vocabulary": { + "https://example.org/vocab/vocab1": true, + "https://example.org/vocab/vocab2": true, + "https://example.org/vocab/vocab3": false + }, + "allOf": { + {"$ref": "meta/vocab1"}, // https://example.org/meta/vocab1 + {"$ref": "meta/vocab2"}, // https://example.org/meta/vocab2 + {"$ref": "meta/vocab3"} // https://example.org/meta/vocab3 + } + // ... +} +``` + +Finally, the keywords in both the Core and Validation specifications will be +divided into multiple vocabularies. The keyword definitions will be removed from +the meta-schema and added to vocabulary schemas to which the meta-schema will +contain references. In this way, the meta-schema's functionality remains the +same. + +```json +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://json-schema.org/draft/next/schema", + "$vocabulary": { + "https://json-schema.org/draft/next/vocab/core": true, + "https://json-schema.org/draft/next/vocab/applicator": true, + "https://json-schema.org/draft/next/vocab/unevaluated": true, + "https://json-schema.org/draft/next/vocab/validation": true, + "https://json-schema.org/draft/next/vocab/meta-data": true, + "https://json-schema.org/draft/next/vocab/format-annotation": true, + "https://json-schema.org/draft/next/vocab/content": true + }, + "$dynamicAnchor": "meta", + + "title": "Core and Validation specifications meta-schema", + "allOf": [ + {"$ref": "meta/core"}, + {"$ref": "meta/applicator"}, + {"$ref": "meta/unevaluated"}, + {"$ref": "meta/validation"}, + {"$ref": "meta/meta-data"}, + {"$ref": "meta/format-annotation"}, + {"$ref": "meta/content"} + ], +} +``` + +The division of keywords among the vocabularies will be in accordance with the +2020-12 specification (for now). + +### Limitations + +#### Unknown Keywords and Unsupported Vocabularies + +This proposal, in its current state, seeks to mimic the behavior defined in the +2020-12 specification. However, the current specification's disallowance of +unknown keywords presents a problem for schemas that use keywords from optional +vocabularies. (This is the topic of the discussion at +https://github.com/orgs/json-schema-org/discussions/342.) + +#### Machine Readability + +The vocabulary URI is an opaque value. There is no data that an implementation +can reference to identify the keywords defined by the vocabulary. The vocabulary +schema _implies_ this, but scanning a `properties` keyword isn't very reliable. +Moreover, such a system cannot provide metadata about the keywords. + +Having some sort of "vocabulary definition" file could alleviate this. + +One reason for _not_ having such a file is that, at least for functional +keywords, the user generally needs to provide custom code to the implementation +to process the keywords, thus performing that same explicit configuration +anyway. (Such information cannot be gleaned from a vocabulary specification. For +example, an implementation can't know what to do with a hypothetical `minDate` +keyword.) + +Several ideas have been offered for this sort of document: + +- https://github.com/json-schema-org/json-schema-spec/issues/1523 +- https://github.com/json-schema-org/json-schema-spec/issues/1423 +- https://github.com/json-schema-org/json-schema-spec/pull/1257 + +#### Implicit Inclusion of Core Vocabulary + +Because the Core keywords (the ones that start with `$`) instruct an +implementation on how a schema should be processed, its inclusion is mandatory +and assumed. As such, while excluding the Core Vocabulary from the `$vocabulary` +keyword has no effect, it is generally advised as common practice to include the +Core Vocabulary explicitly. + +This can be confusing and difficult to use/implement, and we probably need +something better here. + +## Change Details + + + +***NOTE** Since the design of vocabularies will be changing anyway, it's not +worth the time and effort to fill in this section just yet. As such, please +read the above sections for loose requirements. For tighter requirements, +please assume conformance with the 2020-12 Core and Validation specifications.* + +## %appendix% Change Log + +- 2024-06-10 - Created + +## %appendix% Champions + +| Champion | Company | Email | URI | +| ----------- | ------- | ------------------------------ | ------------------------------- | +| Greg Dennis | | | | diff --git a/specs/registries/format.json b/specs/registries/format.json new file mode 100644 index 00000000..b1426b16 --- /dev/null +++ b/specs/registries/format.json @@ -0,0 +1,375 @@ +{ + "base64url": { + "description": "Binary data encoded as a url-safe string as defined in RFC4648", + "types": ["string"], + "examples": ["U3dhZ2dlciByb2Nrcw"], + "deprecated": true, + "supportedBy": [] + }, + "binary": { + "description": "Any sequence of octets", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/v3.0.3.html#data-types", + "types": ["string"], + "examples": ["binary data"], + "deprecated": true, + "supportedBy": [] + }, + "byte": { + "description": "Base64 encoded data as defined in RFC4648", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/v3.0.3.html#data-types", + "types": ["string"], + "examples": ["U3dhZ2dlciByb2Nrcw=="], + "deprecated": true, + "supportedBy": [] + }, + "char": { + "description": "A single character", + "types": ["string"], + "examples": ["a"], + "deprecated": false, + "supportedBy": [] + }, + "commonmark": { + "description": "Commonmark-formatted text", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/latest.html#data-types", + "types": ["string"], + "examples": ["# Heading\n\nSome **bold** text."], + "deprecated": false, + "supportedBy": [] + }, + "date": { + "description": "Date as defined by full-date - RFC3339", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-dates-times-and-duration", + "types": ["string"], + "examples": ["2017-07-21"], + "deprecated": false, + "supportedBy": [] + }, + "date-time": { + "description": "Date and time as defined by date-time - RFC3339", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-dates-times-and-duration", + "types": ["string"], + "examples": ["2017-07-21T17:32:28Z"], + "deprecated": false, + "supportedBy": [] + }, + "decimal": { + "description": "A fixed point decimal number of unspecified precision and range", + "types": ["string", "number"], + "examples": ["123.45"], + "deprecated": false, + "supportedBy": [] + }, + "decimal128": { + "description": "A decimal floating-point number with 34 significant decimal digits", + "types": ["string", "number"], + "examples": ["123.4567890123456789012345678901234"], + "deprecated": false, + "supportedBy": [] + }, + "double": { + "description": "Double precision floating point number", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/latest.html#data-types", + "types": ["number"], + "examples": [-1.7976931348623157e+308, -1, -4.9406564584124654e-324, 0, 4.9406564584124654e-324, 1, 1.7976931348623157e+308], + "deprecated": false, + "supportedBy": [] + }, + "double-int": { + "description": "An integer that can be stored in an IEEE 754 double-precision number without loss of precision", + "types": ["number"], + "examples": [9007199254740991], + "deprecated": false, + "supportedBy": [] + }, + "duration": { + "description": "Duration as defined by duration - RFC3339", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-dates-times-and-duration", + "types": ["string"], + "examples": ["P3Y6M4DT12H30M5S"], + "deprecated": false, + "supportedBy": [] + }, + "email": { + "description": "An email address as defined as Mailbox in RFC5321", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-email-addresses", + "types": ["string"], + "examples": ["user@example.com"], + "deprecated": false, + "supportedBy": [] + }, + "float": { + "description": "Single precision floating point number", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/latest.html#data-types", + "types": ["number"], + "examples": [-3.40282347e+38, -1, -1.17549435e-38, 0, 1.17549435e-38, 1, 3.40282347e+38], + "deprecated": false, + "supportedBy": [] + }, + "hostname": { + "description": "A host name as defined by RFC1123", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-hostnames", + "types": ["string"], + "examples": ["example.com"], + "deprecated": false, + "supportedBy": [] + }, + "html": { + "description": "HTML-formatted text", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/latest.html#data-types", + "types": ["string"], + "examples": ["

This is a paragraph.

"], + "deprecated": false, + "supportedBy": [] + }, + "http-date": { + "description": "Date and time as defined by HTTP-date - RFC7231", + "types": ["string"], + "examples": ["Sun, 06 Nov 1994 08:49:37 GMT"], + "deprecated": false, + "supportedBy": [] + }, + "idn-email": { + "description": "An email address as defined as Mailbox in RFC6531", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-email-addresses", + "types": ["string"], + "examples": ["user@exämple.com"], + "deprecated": false, + "supportedBy": [] + }, + "idn-hostname": { + "description": "An internationalized host name as defined by RFC5890", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-hostnames", + "types": ["string"], + "examples": ["exämple.com"], + "deprecated": false, + "supportedBy": [] + }, + "int16": { + "description": "Signed 16-bit integer", + "types": ["number"], + "examples": [-32768, -1, 0, 1, 32767], + "deprecated": false, + "supportedBy": [] + }, + "int32": { + "description": "Signed 32-bit integer", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/v3.1.1.html#data-type-format", + "types": ["number"], + "examples": [-2147483648, -1, 0, 1, 2147483647], + "deprecated": false, + "supportedBy": [] + }, + "int64": { + "description": "Signed 64-bit integer", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/v3.1.1.html#data-type-format", + "types": ["number"], + "examples": [-9223372036854775808, -1, 0, 1, 9223372036854775807], + "deprecated": false, + "supportedBy": [] + }, + "int8": { + "description": "Signed 8-bit integer", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/latest.html#data-types", + "types": ["number"], + "examples": [-128, -1, 0, 1, 127], + "deprecated": false, + "supportedBy": [] + }, + "ipv4": { + "description": "An IPv4 address as defined as dotted-quad by RFC2673", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-ip-addresses", + "types": ["string"], + "examples": ["192.168.0.1"], + "deprecated": false, + "supportedBy": [] + }, + "ipv6": { + "description": "An IPv6 address as defined by RFC4673", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-ip-addresses", + "types": ["string"], + "examples": ["2001:0db8:85a3:0000:0000:8a2e:0370:7334"], + "deprecated": false, + "supportedBy": [] + }, + "iri": { + "description": "An Internationalized Resource Identifier as defined in RFC3987", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-resource-identifiers", + "types": ["string"], + "examples": ["https://example.com/rosé"], + "deprecated": false, + "supportedBy": [] + }, + "iri-reference": { + "description": "An Internationalized Resource Identifier as defined in RFC3987", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-resource-identifiers", + "types": ["string"], + "examples": ["../resource.json"], + "deprecated": false, + "supportedBy": [] + }, + "json-pointer": { + "description": "A JSON string representation of a JSON Pointer as defined in RFC6901", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-json-pointers", + "types": ["string"], + "examples": ["/foo/bar"], + "deprecated": false, + "supportedBy": [] + }, + "media-range": { + "description": "A media type as defined by the media-range ABNF production in RFC9110.", + "definingBody": "OpenAPI", + "definition": "https://www.rfc-editor.org/rfc/rfc9110#field.accept", + "types": ["string"], + "examples": ["text/html"], + "deprecated": false, + "supportedBy": [] + }, + "regex": { + "description": "A regular expression as defined in ECMA-262", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-regex", + "types": ["string"], + "examples": ["^[a-zA-Z0-9]+$"], + "deprecated": false, + "supportedBy": [] + }, + "relative-json-pointer": { + "description": "A JSON string representation of a relative JSON Pointer as defined in draft RFC 01", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-json-pointers", + "types": ["string"], + "examples": ["1/0"], + "deprecated": false, + "supportedBy": [] + }, + "sf-binary": { + "description": "Structured fields byte sequence as defined in RFC8941", + "definingBody": "RFC 8941", + "definition": "https://www.rfc-editor.org/rfc/rfc8941#name-byte-sequences", + "types": ["string"], + "examples": ["U3dhZ2dlciByb2Nrcw=="], + "deprecated": false, + "supportedBy": [] + }, + "sf-boolean": { + "description": "Structured fields boolean as defined in RFC8941", + "definingBody": "RFC 8941", + "definition": "https://www.rfc-editor.org/rfc/rfc8941#name-booleans", + "types": ["string"], + "examples": ["true", "false"], + "deprecated": false, + "supportedBy": [] + }, + "sf-decimal": { + "description": "Structured fields decimal as defined in RFC8941", + "definingBody": "RFC 8941", + "definition": "https://www.rfc-editor.org/rfc/rfc8941#name-decimals", + "types": ["number"], + "examples": ["123.45"], + "deprecated": false, + "supportedBy": [] + }, + "sf-integer": { + "description": "Structured fields integer as defined in RFC8941", + "definingBody": "RFC 8941", + "definition": "https://www.rfc-editor.org/rfc/rfc8941#name-integers", + "types": ["number"], + "examples": [123], + "deprecated": false, + "supportedBy": [] + }, + "sf-string": { + "description": "Structured fields string as defined in RFC8941", + "definingBody": "RFC 8941", + "definition": "https://www.rfc-editor.org/rfc/rfc8941#name-strings", + "types": ["string"], + "examples": ["example"], + "deprecated": false, + "supportedBy": [] + }, + "sf-token": { + "description": "Structured fields token as defined in RFC8941", + "definingBody": "RFC 8941", + "definition": "https://www.rfc-editor.org/rfc/rfc8941#name-tokens", + "types": ["string"], + "examples": ["token"], + "deprecated": false, + "supportedBy": [] + }, + "time": { + "description": "Time as defined by full-time - RFC3339", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-dates-times-and-duration", + "types": ["string"], + "examples": ["13:45:30Z", "13:45:30+01:00"], + "deprecated": false, + "supportedBy": [] + }, + "uint8": { + "description": "Unsigned 8-bit integer", + "definingBody": "OpenAPI", + "definition": "https://spec.openapis.org/oas/latest.html#data-types", + "types": ["number"], + "examples": [0, 1, 255], + "deprecated": false, + "supportedBy": [] + }, + "uri": { + "description": "A Uniform Resource Identifier as defined in RFC3986", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-resource-identifiers", + "types": ["string"], + "examples": ["https://example.com"], + "deprecated": false, + "supportedBy": [] + }, + "uri-reference": { + "description": "A URI reference as defined in RFC3986", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-resource-identifiers", + "types": ["string"], + "examples": ["../resource.json"], + "deprecated": false, + "supportedBy": [] + }, + "uri-template": { + "description": "A URI Template as defined in RFC6570", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-uri-template", + "types": ["string"], + "examples": ["https://example.com/{id}"], + "deprecated": false, + "supportedBy": [] + }, + "uuid": { + "description": "A Universally Unique IDentifier as defined in RFC4122", + "definingBody": "JSON Schema", + "definition": "https://json-schema.org/draft/2020-12/json-schema-validation.html#name-resource-identifiers", + "types": ["string"], + "examples": ["f81d4fae-7dec-11d0-a765-00a0c91e6bf6"], + "deprecated": false, + "supportedBy": [] + } +} \ No newline at end of file diff --git a/relative-json-pointer.xml b/specs/relative-json-pointer.xml similarity index 77% rename from relative-json-pointer.xml rename to specs/relative-json-pointer.xml index eb8b7f38..f00cb1ee 100644 --- a/relative-json-pointer.xml +++ b/specs/relative-json-pointer.xml @@ -1,5 +1,5 @@ - @@ -12,7 +12,7 @@ - + Relative JSON Pointers @@ -27,19 +27,20 @@ - +
- - - San Francisco - CA - USA - andrews_henry@yahoo.com
- + +
+ ben@jsonschema.dev + https://jsonschema.dev +
+
+ + Internet Engineering Task Force JSON JavaScript @@ -82,34 +83,30 @@ A Relative JSON Pointer is a Unicode string in UTF-8 encoding (see RFC 8259, Section 8), comprising a non-negative integer, - followed by either a '#' (%x23) character or a JSON Pointer - (RFC 6901). + an optional index adjustment consisting of '+' (%x2B) or '-' (%x2D) followed + by a positive integer, followed by either a '#' (%x23) character or + a JSON Pointer (RFC 6901). - The separation between the integer prefix and the JSON Pointer will + The separation between the integer prefix (with optional adjustment) + and the JSON Pointer will always be unambiguous, because a JSON Pointer must be either zero- length or start with a '/' (%x2F). Similarly, a JSON Pointer will never be ambiguous with the '#'. -
- - The ABNF syntax of a Relative JSON Pointer is: - - - - - - where <json-pointer> follows the production defined in - RFC 6901, Section 3 ("Syntax"). - -
+ The ABNF syntax of a Relative JSON Pointer is: +
@@ -123,8 +120,9 @@ Evaluation begins by processing the non-negative-integer prefix. This can be found by taking the longest continuous sequence of decimal digits available, starting from the beginning of the string, taking - the decimal numerical value. If this value is more than zero, then - the following steps are repeated that number of times: + the decimal numerical value. If the value is zero, the following steps + are skipped. If this value is more than zero, then the following steps + are repeated that number of times: If the current referenced value is the root of the document, then @@ -139,9 +137,30 @@ the new referenced value is that object. + + + If the next character is a plus ("+") or minus ("-"), followed by another + continuous sequence of decimal digits, the following steps + are taken using the decimal numeric value of that plus or minus sign + and decimal sequence: + + + If the current referenced value is not an item of an array, + then evaluation fails (see below). + + + If the referenced value is an item of an array, then the + new referenced value is the item of the array indexed by + adding the decimal value (which may be negative), to the + index of the current referenced value. + + + + If the remainder of the Relative JSON Pointer is a JSON Pointer, then - evaluation proceeds as per RFC 6901, Section 4 - ("Evaluation"), with the modification that the initial reference + evaluation proceeds as per + RFC 6901, Section 5 + with the modification that the initial reference being used is the reference currently being held (which may not be root of the document). @@ -179,7 +198,7 @@ @@ -284,6 +305,12 @@ programming languages that use NUL to mark the end of a string.
+ +
+ + This document has no IANA actions. + +
@@ -303,6 +330,17 @@ + + + Fix ABNF omission for using # with index manipulation + Clarify handling of leading "0" + + + + + Add array forward and backward index manipulation + + Update to the latest JSON RFC diff --git a/specs/schema.json b/specs/schema.json new file mode 100644 index 00000000..58da4e70 --- /dev/null +++ b/specs/schema.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://json-schema.org/draft/next/schema", + "$vocabulary": { + "https://json-schema.org/draft/next/vocab/core": true, + "https://json-schema.org/draft/next/vocab/applicator": true, + "https://json-schema.org/draft/next/vocab/unevaluated": true, + "https://json-schema.org/draft/next/vocab/validation": true, + "https://json-schema.org/draft/next/vocab/meta-data": true, + "https://json-schema.org/draft/next/vocab/format-annotation": true, + "https://json-schema.org/draft/next/vocab/content": true + }, + "$dynamicAnchor": "meta", + + "title": "Core and Validation specifications meta-schema", + "allOf": [ + {"$ref": "meta/core"}, + {"$ref": "meta/applicator"}, + {"$ref": "meta/unevaluated"}, + {"$ref": "meta/validation"}, + {"$ref": "meta/meta-data"}, + {"$ref": "meta/format-annotation"}, + {"$ref": "meta/content"} + ], + "type": ["object", "boolean"], + "$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.", + "properties": { + "definitions": { + "$comment": "\"definitions\" has been replaced by \"$defs\".", + "type": "object", + "additionalProperties": { "$dynamicRef": "#meta" }, + "deprecated": true, + "default": {} + }, + "dependencies": { + "$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.", + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$dynamicRef": "#meta" }, + { "$ref": "meta/validation#/$defs/stringArray" } + ] + }, + "deprecated": true, + "default": {} + }, + "$recursiveAnchor": { + "$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".", + "type": "boolean", + "deprecated": true + }, + "$recursiveRef": { + "$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".", + "type": "string", + "format": "uri-reference", + "deprecated": true + } + } +} diff --git a/specs/spec.css b/specs/spec.css new file mode 100644 index 00000000..6a32bdc6 --- /dev/null +++ b/specs/spec.css @@ -0,0 +1,121 @@ +svg { + fill: currentColor; +} + +/* Torchlight */ +pre { + border-radius: 0.5rem; + overflow-x: auto; + margin: 0; +} + +pre.torchlight code { + display: block; + min-width: -webkit-max-content; + min-width: -moz-max-content; + min-width: max-content; + border-radius: 0.5rem; +} + +pre.torchlight code .line { + padding-left: 1rem; + padding-right: 1rem; +} + +pre.torchlight code .line-number, +pre.torchlight code .summary-caret { + margin-right: 1rem; +} + +/* Flexible Code Titles */ +.remark-code-container{ + border-radius: 0.5rem; + margin-top: 1rem; + margin-bottom: 1rem; +} + +.remark-code-title { + height: 1.25rem; + border-radius: 0.5rem 0.5rem 0 0; + position: relative; + top: 0.5rem; + background-color: var(--background-alt); + padding: 0.5rem 0.5rem 0.5rem 2.5rem; + background-repeat: no-repeat; + background-size: 1.25rem; + background-position-y: center; + background-position-x: 0.75rem; +} + +.code-title-unknown { + padding-left: 1rem; +} + +.code-title-jsonschema { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 70.423268 70.42326'%3E%3Cg transform='translate(-104.22785,-45.507923)' id='layer1' fill='%23ffffff'%3E%3Cpath id='path4544' d='m 122.99401,114.18985 c -4.32897,-0.9404 -7.58044,-3.47848 -8.71251,-6.80095 -0.78921,-2.31618 -0.67682,-6.07238 0.33363,-11.150598 0.48507,-2.437836 0.88169,-5.347843 0.88139,-6.466688 -9.8e-4,-3.718098 -1.71106,-5.735418 -5.1001,-6.016462 l -1.9549,-0.162116 v -2.392655 -2.392657 l 1.85208,-0.250855 c 2.70243,-0.366031 3.74441,-1.02838 4.57629,-2.908984 0.61121,-1.381726 0.68884,-2.068648 0.50552,-4.472869 -0.11913,-1.562244 -0.53527,-4.348568 -0.92477,-6.191832 -0.98954,-4.682868 -0.94822,-8.485471 0.11707,-10.773163 1.56862,-3.368589 5.43705,-5.854553 9.93248,-6.382903 l 1.93299,-0.227185 v 2.518015 2.518015 h -1.29973 c -1.77186,0 -4.2497,1.262413 -4.8835,2.488054 -0.60797,1.175674 -0.65405,2.864146 -0.15834,5.802223 0.78343,4.643508 1.04707,9.098344 0.67592,11.421636 -0.42464,2.658142 -1.97477,5.796328 -3.6791,7.448236 l -1.18012,1.143813 1.61497,1.982752 c 1.99051,2.443801 2.76458,4.148744 3.24284,7.142561 0.37835,2.368341 0.0844,7.282673 -0.67072,11.213982 -1.05359,5.48514 0.1623,7.65141 4.66209,8.30613 l 1.67569,0.24382 v 2.44782 c 0,2.79211 0.17086,2.69708 -3.43917,1.91286 z' style='fill:stroke-width:0.35277775'/%3E%3Cpath id='path4546' d='m 152.2304,112.24932 v -2.42987 l 2.04969,-0.42336 c 2.26276,-0.46736 4.054,-1.8634 4.45842,-3.47475 0.1274,-0.50758 -0.11267,-3.16398 -0.53347,-5.90311 -1.37183,-8.929552 -0.6114,-13.537042 2.85482,-17.297452 l 1.48237,-1.60818 -1.1108,-1.26512 c -3.97855,-4.53132 -4.66885,-8.552208 -3.15364,-18.369547 0.76342,-4.946305 0.76409,-4.994322 0.087,-6.173611 -0.79713,-1.388278 -3.28385,-2.776033 -4.97438,-2.776033 h -1.15997 v -2.469445 c 0,-2.811057 -0.0583,-2.773846 3.24583,-2.072788 3.9645,0.841179 6.80448,2.853272 8.27787,5.864775 0.84544,1.728026 0.97275,2.400136 0.94911,5.010889 -0.015,1.658349 -0.35758,4.682054 -0.76125,6.719346 -1.49867,7.563594 -1.3651,9.576204 0.7654,11.532814 0.98915,0.90842 1.64012,1.17274 3.37032,1.36849 l 2.14439,0.24261 v 2.42387 2.42388 l -1.6757,7.1e-4 c -2.1517,7e-4 -3.9323,0.90924 -4.83869,2.46889 -0.95194,1.63803 -0.89239,5.20675 0.17364,10.40695 0.90648,4.421902 1.05253,8.458452 0.3882,10.728752 -0.70059,2.39406 -3.81995,5.29609 -6.74745,6.27718 -1.26118,0.42266 -2.96775,0.87096 -3.79236,0.99623 l -1.49931,0.22775 z' style='stroke-width:0.35277778'/%3E%3Cpath id='path4548' d='m 131.74239,108.26592 c -1.02163,-1.2988 -0.87294,-3.53652 0.38087,-5.73185 0.92776,-1.62446 4.80862,-6.948549 7.61066,-10.440949 l 1.13094,-1.40958 -1.80213,-5.22523 c -2.02147,-5.86123 -2.0098,-5.97467 0.65581,-6.37225 l 1.46834,-0.219 1.64076,3.3506 c 0.90242,1.84283 1.76982,3.35061 1.92755,3.35061 0.15774,0 1.77489,-1.75542 3.59368,-3.90092 3.15918,-3.72667 3.35688,-3.89165 4.42591,-3.69334 0.64552,0.11974 1.21858,0.0465 1.35432,-0.17316 0.31818,-0.51481 1.23083,0.24704 1.23083,1.02746 0,0.32009 -0.45438,1.13409 -1.00972,1.80888 -2.26771,2.75549 -7.10417,9.27155 -7.10417,9.5713 0,0.17685 0.97502,2.45302 2.16671,5.05816 l 2.1667,4.736609 -0.65823,0.98459 c -0.36203,0.54152 -0.66236,1.12603 -0.6674,1.29891 -0.005,0.17288 -0.27769,0.48371 -0.60588,0.69073 -0.83174,0.52464 -1.44656,-0.11541 -3.9894,-4.153119 -1.16417,-1.84856 -2.23163,-3.36491 -2.37215,-3.36967 -0.31309,-0.0106 -3.7911,5.131969 -6.47955,9.580639 -2.37093,3.92324 -1.93885,3.4204 -3.26614,3.80106 -0.95533,0.27398 -1.19348,0.19843 -1.79831,-0.57048 z' style='stroke-width:0.35277775'/%3E%3Cpath id='path4550' d='m 131.98567,83.677091 c -2.15148,-3.8472 -6.0183,-9.42829 -7.57842,-10.93815 -0.79252,-0.76698 -1.44094,-1.57494 -1.44094,-1.79546 0,-0.6016 1.61695,-1.21975 3.19058,-1.21975 1.69822,0 3.49597,1.47777 5.0997,4.19203 0.58208,0.98515 1.15641,1.79434 1.27629,1.79819 0.11988,0.004 0.80873,-1.65116 1.53078,-3.67779 1.5464,-4.34039 5.62351,-12.777999 7.22453,-14.951229 1.3726,-1.86316 3.42936,-2.865165 5.90274,-2.875676 3.23375,-0.01374 3.24268,0.130067 0.20474,3.296663 -4.63599,4.832327 -6.76321,8.809632 -11.25155,21.037252 -1.24637,3.39549 -2.39032,6.47895 -2.54212,6.85214 -0.23022,0.56597 -0.49833,0.28096 -1.61633,-1.71822 z' style='stroke-width:0.35277775'/%3E%3C/g%3E%3C/svg%3E"); +} + +.code-title-json { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 70.423268 70.42326'%3E%3Cg transform='translate(-104.22785,-45.507923)' id='layer1' fill='%23ffffff'%3E%3Cpath id='path4544' d='m 122.99401,114.18985 c -4.32897,-0.9404 -7.58044,-3.47848 -8.71251,-6.80095 -0.78921,-2.31618 -0.67682,-6.07238 0.33363,-11.150598 0.48507,-2.437836 0.88169,-5.347843 0.88139,-6.466688 -9.8e-4,-3.718098 -1.71106,-5.735418 -5.1001,-6.016462 l -1.9549,-0.162116 v -2.392655 -2.392657 l 1.85208,-0.250855 c 2.70243,-0.366031 3.74441,-1.02838 4.57629,-2.908984 0.61121,-1.381726 0.68884,-2.068648 0.50552,-4.472869 -0.11913,-1.562244 -0.53527,-4.348568 -0.92477,-6.191832 -0.98954,-4.682868 -0.94822,-8.485471 0.11707,-10.773163 1.56862,-3.368589 5.43705,-5.854553 9.93248,-6.382903 l 1.93299,-0.227185 v 2.518015 2.518015 h -1.29973 c -1.77186,0 -4.2497,1.262413 -4.8835,2.488054 -0.60797,1.175674 -0.65405,2.864146 -0.15834,5.802223 0.78343,4.643508 1.04707,9.098344 0.67592,11.421636 -0.42464,2.658142 -1.97477,5.796328 -3.6791,7.448236 l -1.18012,1.143813 1.61497,1.982752 c 1.99051,2.443801 2.76458,4.148744 3.24284,7.142561 0.37835,2.368341 0.0844,7.282673 -0.67072,11.213982 -1.05359,5.48514 0.1623,7.65141 4.66209,8.30613 l 1.67569,0.24382 v 2.44782 c 0,2.79211 0.17086,2.69708 -3.43917,1.91286 z' style='fill:stroke-width:0.35277775'/%3E%3Cpath id='path4546' d='m 152.2304,112.24932 v -2.42987 l 2.04969,-0.42336 c 2.26276,-0.46736 4.054,-1.8634 4.45842,-3.47475 0.1274,-0.50758 -0.11267,-3.16398 -0.53347,-5.90311 -1.37183,-8.929552 -0.6114,-13.537042 2.85482,-17.297452 l 1.48237,-1.60818 -1.1108,-1.26512 c -3.97855,-4.53132 -4.66885,-8.552208 -3.15364,-18.369547 0.76342,-4.946305 0.76409,-4.994322 0.087,-6.173611 -0.79713,-1.388278 -3.28385,-2.776033 -4.97438,-2.776033 h -1.15997 v -2.469445 c 0,-2.811057 -0.0583,-2.773846 3.24583,-2.072788 3.9645,0.841179 6.80448,2.853272 8.27787,5.864775 0.84544,1.728026 0.97275,2.400136 0.94911,5.010889 -0.015,1.658349 -0.35758,4.682054 -0.76125,6.719346 -1.49867,7.563594 -1.3651,9.576204 0.7654,11.532814 0.98915,0.90842 1.64012,1.17274 3.37032,1.36849 l 2.14439,0.24261 v 2.42387 2.42388 l -1.6757,7.1e-4 c -2.1517,7e-4 -3.9323,0.90924 -4.83869,2.46889 -0.95194,1.63803 -0.89239,5.20675 0.17364,10.40695 0.90648,4.421902 1.05253,8.458452 0.3882,10.728752 -0.70059,2.39406 -3.81995,5.29609 -6.74745,6.27718 -1.26118,0.42266 -2.96775,0.87096 -3.79236,0.99623 l -1.49931,0.22775 z' style='stroke-width:0.35277778'/%3E%3C/g%3E%3C/svg%3E"); +} + +/* Flexible Containers */ +.remark-container { + border: thin solid black; + border-radius: 1rem; + margin-bottom: 1rem; +} + +.remark-container-title { + border-radius: 1rem 1rem 0 0; + position: relative; + padding: .5rem 0 .5rem 2.5rem; + background-color: var(--background); + background-repeat: no-repeat; + background-size: 1.75rem; + background-position-y: center; + background-position-x: .25rem; +} + +.remark-container > :not(.remark-container-title) { + padding: 0 1rem 0 1rem; +} + +.remark-container-title.warning { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Ccircle cx='12' cy='17' r='1' fill='%23ffffff'%3E%3C/circle%3E%3Cpath d='M12 10L12 14' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3C/path%3E%3Cpath d='M3.44722 18.1056L10.2111 4.57771C10.9482 3.10361 13.0518 3.10362 13.7889 4.57771L20.5528 18.1056C21.2177 19.4354 20.2507 21 18.7639 21H5.23607C3.7493 21 2.78231 19.4354 3.44722 18.1056Z' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3C/path%3E%3C/g%3E%3C/svg%3E"); +} + +.remark-container-title.note { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 32 32' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:sketch='http://www.bohemiancoding.com/sketch/ns' fill='%23ffffff'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Ctitle%3Enote-text%3C/title%3E%3Cdesc%3ECreated with Sketch Beta.%3C/desc%3E%3Cdefs%3E%3C/defs%3E%3Cg id='Page-1' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' sketch:type='MSPage'%3E%3Cg id='Icon-Set' sketch:type='MSLayerGroup' transform='translate(-308.000000, -99.000000)' fill='%23ffffff'%3E%3Cpath d='M332,107 L316,107 C315.447,107 315,107.448 315,108 C315,108.553 315.447,109 316,109 L332,109 C332.553,109 333,108.553 333,108 C333,107.448 332.553,107 332,107 L332,107 Z M338,127 C338,128.099 336.914,129.012 335.817,129.012 L311.974,129.012 C310.877,129.012 309.987,128.122 309.987,127.023 L309.987,103.165 C309.987,102.066 310.902,101 312,101 L336,101 C337.098,101 338,101.902 338,103 L338,127 L338,127 Z M336,99 L312,99 C309.806,99 308,100.969 308,103.165 L308,127.023 C308,129.22 309.779,131 311.974,131 L335.817,131 C338.012,131 340,129.196 340,127 L340,103 C340,100.804 338.194,99 336,99 L336,99 Z M332,119 L316,119 C315.447,119 315,119.448 315,120 C315,120.553 315.447,121 316,121 L332,121 C332.553,121 333,120.553 333,120 C333,119.448 332.553,119 332,119 L332,119 Z M332,113 L316,113 C315.447,113 315,113.448 315,114 C315,114.553 315.447,115 316,115 L332,115 C332.553,115 333,114.553 333,114 C333,113.448 332.553,113 332,113 L332,113 Z' id='note-text' sketch:type='MSShapeGroup'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); +} + +.remark-container-title.experimental { + background-image: url("data:image/svg+xml,%3Csvg version='1.1' id='designs' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 32 32' xml:space='preserve' fill='%23ffffff'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Cstyle type='text/css'%3E .sketchy_een%7Bfill:%23ffffff;%7D %3C/style%3E%3Cpath class='sketchy_een' d='M27.958,26.693c-0.023-0.207-0.066-0.377-0.22-0.531c-0.006-0.006-0.015-0.008-0.021-0.014 c0.06-0.187,0.051-0.395-0.057-0.573c-0.326-0.538-0.64-1.08-0.942-1.631c-0.345-0.629-0.716-1.241-1.059-1.87 c-0.351-0.642-0.676-1.296-1.016-1.942c-0.352-0.675-0.773-1.309-1.142-1.974c-0.506-0.907-0.961-1.842-1.47-2.749 c-0.494-0.88-0.958-1.772-1.422-2.667c0.008-0.161-0.007-0.328-0.012-0.488c-0.004-0.168-0.009-0.337-0.017-0.506 c-0.015-0.364-0.042-0.726-0.064-1.087c-0.045-0.722-0.102-1.444-0.133-2.167c-0.062-1.561-0.036-3.121,0.043-4.68 c0.159,0.001,0.318,0.002,0.478,0.001c0.26-0.004,0.519-0.023,0.779-0.011c0.485,0.023,0.89-0.422,0.89-0.89 c0-0.235-0.095-0.462-0.261-0.629c-0.176-0.178-0.386-0.242-0.629-0.261C21.443,2.005,21.202,2,20.96,2 c-0.264,0-0.528,0.006-0.789,0.008C20.05,2.01,19.929,2.01,19.808,2.01c-0.201,0-0.402,0-0.602,0.002 c-0.347,0.004-0.695,0.026-1.042,0.034c-0.39,0.006-0.782,0.002-1.173,0.01c-0.402,0.01-0.803,0.028-1.203,0.042 c-0.769,0.025-1.536,0.068-2.308,0.068c-0.441,0-0.883,0.004-1.322,0c-0.5-0.004-0.998-0.045-1.499-0.066 c-0.445-0.021-0.818,0.386-0.818,0.818c0,0.458,0.373,0.805,0.818,0.82c0.12,0.004,0.24,0.003,0.36,0.006 c0.038,0.704,0.098,1.408,0.133,2.114c0.036,0.722,0.028,1.444,0.049,2.165c0.021,0.68,0.04,1.362,0.061,2.042 c0.019,0.608,0.055,1.214,0.07,1.822c-0.354,0.653-0.68,1.32-1.049,1.964c-0.195,0.341-0.385,0.682-0.563,1.031 c-0.172,0.333-0.316,0.68-0.468,1.023c-0.15,0.337-0.296,0.676-0.46,1.006c-0.165,0.328-0.333,0.656-0.489,0.987 c-0.165,0.352-0.324,0.708-0.493,1.061c-0.155,0.33-0.328,0.652-0.489,0.979c-0.263,0.534-0.496,1.082-0.746,1.622 c-0.267,0.58-0.525,1.165-0.777,1.752c-0.241,0.561-0.519,1.104-0.758,1.665c-0.225,0.529-0.428,1.068-0.647,1.6 c-0.039,0.093-0.079,0.184-0.118,0.278c-0.052,0.117-0.081,0.229-0.091,0.344c-0.087,0.136-0.152,0.288-0.159,0.459 c-0.019,0.46-0.019,0.911,0.218,1.324c0.159,0.281,0.358,0.478,0.618,0.663c0.135,0.095,0.305,0.14,0.457,0.199 c0.241,0.095,0.519,0.097,0.777,0.114c0.368,0.023,0.733,0.002,1.101-0.009c0.402-0.013,0.801-0.034,1.203-0.062 c0.405-0.03,0.813-0.036,1.218-0.047c0.801-0.025,1.605-0.019,2.406-0.004c0.762,0.013,1.519,0.038,2.279,0.1 c0.765,0.064,1.525,0.066,2.292,0.064c0.159,0,0.32,0,0.479,0c0.64,0.002,1.281,0.002,1.923-0.032 c0.756-0.042,1.514-0.053,2.271-0.085c0.392-0.017,0.781-0.055,1.169-0.093c0.377-0.036,0.756-0.047,1.133-0.062 c0.686-0.027,1.37-0.023,2.05-0.117c0.138-0.019,0.277-0.042,0.415-0.07c0.195-0.042,0.369-0.116,0.551-0.195 c0.282-0.121,0.527-0.314,0.748-0.525c0.275-0.261,0.421-0.599,0.53-0.957c0.097-0.314,0.138-0.656,0.114-0.983 C27.973,26.817,27.965,26.756,27.958,26.693z M15.375,3.768c0.449-0.004,0.9-0.002,1.351,0.002c0.322,0.002,0.644,0.006,0.966,0.004 c0.385-0.001,0.77,0.01,1.154,0.021c-0.028,0.789-0.017,1.581-0.015,2.372c0,0.754-0.009,1.51,0.01,2.264 c0.019,0.716,0.047,1.434,0.1,2.15c0.019,0.259,0.042,0.521,0.062,0.782c-0.342,0.013-0.685,0.025-1.027,0.039 c-0.572,0.021-1.146,0.025-1.718,0.068c-1.152,0.088-2.305,0.091-3.46,0.077c-0.036-0.807-0.057-1.615-0.065-2.424 c0.384-0.011,0.768-0.021,1.152-0.032c0.424-0.013,0.781-0.345,0.781-0.781c0-0.42-0.352-0.781-0.774-0.781 c-0.002,0-0.004,0-0.007,0c-0.389,0.004-0.779,0.008-1.168,0.011c-0.002-0.539,0.001-1.077-0.023-1.615 c-0.032-0.719-0.05-1.437-0.076-2.154C13.537,3.779,14.456,3.778,15.375,3.768z M26.457,27.054c-0.021,0.106-0.049,0.21-0.085,0.312 c-0.036,0.076-0.077,0.15-0.122,0.221c-0.054,0.056-0.112,0.108-0.172,0.159c-0.078,0.053-0.159,0.1-0.243,0.141 c-0.225,0.079-0.462,0.123-0.698,0.158c-0.307,0.032-0.615,0.033-0.922,0.049c-0.311,0.015-0.62,0.043-0.928,0.059 c-0.771,0.034-1.535,0.121-2.306,0.154c-0.758,0.032-1.519,0.034-2.279,0.061c-0.803,0.028-1.608,0.028-2.412,0.019 c-0.377-0.004-0.754-0.002-1.131-0.011c-0.366-0.008-0.729-0.034-1.095-0.059c-0.779-0.049-1.557-0.042-2.338-0.03 c-0.799,0.011-1.599,0.04-2.398,0.057c-0.798,0.017-1.591,0.055-2.389,0.055c-0.263,0.002-0.525-0.011-0.786-0.034 c-0.09-0.015-0.179-0.033-0.266-0.059c-0.03-0.015-0.059-0.032-0.087-0.049c-0.01-0.01-0.021-0.02-0.031-0.03 c-0.011-0.018-0.022-0.036-0.032-0.054c-0.005-0.17,0.01-0.342,0.017-0.511c0.005-0.097-0.021-0.188-0.051-0.275 c0.126-0.329,0.26-0.655,0.383-0.984c0.13-0.346,0.26-0.691,0.401-1.033c0.134-0.304,0.277-0.606,0.412-0.91 c0.007-0.015,0.013-0.031,0.02-0.046c0.333,0.005,0.668,0.002,1-0.004c0.582-0.008,1.165-0.017,1.749,0.021 c0.404,0.027,0.741-0.356,0.741-0.741c0-0.411-0.337-0.731-0.741-0.741c-0.692-0.016-1.384-0.045-2.076-0.07 c0.233-0.516,0.471-1.031,0.707-1.547c0.116-0.252,0.241-0.499,0.365-0.746c0.093,0.037,0.192,0.061,0.296,0.058 c0.36-0.008,0.722-0.021,1.082-0.04c0.258-0.013,0.523-0.049,0.782-0.032c0.436,0.03,0.801-0.386,0.801-0.801 c0-0.458-0.366-0.777-0.801-0.803c-0.023-0.002-0.045-0.002-0.068-0.002c-0.083,0-0.165,0.009-0.249,0.014 c-0.15,0.006-0.301,0.006-0.451,0.008c-0.209,0.002-0.419,0.003-0.628,0.004c0.099-0.22,0.198-0.441,0.301-0.66 c0.157-0.33,0.32-0.654,0.468-0.987c0.078-0.177,0.155-0.354,0.232-0.532c0.057,0.012,0.111,0.034,0.171,0.031 c0.754-0.044,1.506-0.097,2.262-0.14c0.419-0.023,0.771-0.333,0.771-0.771c0-0.426-0.35-0.765-0.771-0.773 c-0.067-0.001-0.133-0.001-0.2-0.001c-0.495,0-0.991,0.026-1.486,0.054c0.052-0.101,0.095-0.206,0.15-0.305 c0.34-0.613,0.68-1.226,1.023-1.838c0.055,0.013,0.107,0.034,0.166,0.034c1.25,0.002,2.497-0.082,3.745-0.146 c0.572-0.028,1.146-0.036,1.718-0.049c0.246-0.006,0.494-0.002,0.741,0c0.059,0.002,0.119,0.002,0.18,0.002 c0.034,0,0.069,0.003,0.103,0.003c0,0.14,0.021,0.28,0.091,0.41c0.383,0.71,0.799,1.404,1.203,2.101 c0.385,0.669,0.763,1.338,1.122,2.021c0.356,0.676,0.709,1.355,1.097,2.012c0.189,0.318,0.4,0.623,0.584,0.945 c0.188,0.324,0.358,0.657,0.53,0.991c0.466,0.89,0.949,1.77,1.47,2.631c0.241,0.398,0.468,0.803,0.703,1.205 c0.21,0.356,0.441,0.705,0.629,1.072c0.021,0.042,0.058,0.068,0.088,0.103c-0.04,0.091-0.062,0.19-0.059,0.295 C26.462,26.814,26.465,26.934,26.457,27.054z M24.139,25.03c0.191,0.358,0.093,0.807-0.267,1.017 c-0.172,0.1-0.381,0.129-0.572,0.076c-0.172-0.047-0.368-0.174-0.445-0.341c-0.481-1.029-1.029-2.027-1.555-3.031 c-0.286-0.546-0.557-1.099-0.852-1.641c-0.313-0.576-0.61-1.157-0.894-1.747c-0.093-0.193-0.136-0.383-0.078-0.593 c0.053-0.193,0.182-0.36,0.354-0.46c0.117-0.069,0.253-0.105,0.389-0.105c0.069,0,0.137,0.009,0.204,0.027 c0.178,0.049,0.379,0.182,0.458,0.354c0.28,0.593,0.557,1.186,0.851,1.771c0.277,0.551,0.54,1.11,0.832,1.654 c0.28,0.521,0.57,1.038,0.839,1.565c0.131,0.26,0.26,0.519,0.396,0.773C23.917,24.575,24.02,24.807,24.139,25.03z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E"); +} + +/* remark-highlight-code-lines */ + +.code-line.inserted { + background-color: var(--color-inserted-line); /* inserted code-line (+) */ +} + +.code-line.deleted { + background-color: var(--color-deleted-line); /* deleted code-line (-) */ +} + +.highlighted-code-line { + background-color: var(--color-highlighted-line); + border-left: 4px solid var(--color-highlighted-line-indicator); +} + +.numbered-code-line::before { + content: attr(data-line-number); + + margin-left: -8px; + margin-right: 16px; + width: 1rem; + color: var(--color-text-weak); + text-align: right; + + display: inline-block; +} diff --git a/standardized-output-verbose.json b/standardized-output-verbose.json deleted file mode 100644 index ef50444f..00000000 --- a/standardized-output-verbose.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "valid": false, - "keywordLocation": "#", - "instanceLocation": "#", - "errors": [ - { - "valid": true, - "keywordLocation": "#/definitions", - "instanceLocation": "#" - }, - { - "valid": true, - "keywordLocation": "#/type", - "instanceLocation": "#" - }, - { - "valid": false, - "keywordLocation": "#/items", - "instanceLocation": "#", - "errors": [ - { - "valid": true, - "keywordLocation": "#/items/$ref", - "absoluteKeywordLocation": - "http://example.com/polygon#/items/$ref", - "instanceLocation": "#/0", - "annotations": [ - { - "valid": true, - "keywordLocation": "#/items/$ref", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point", - "instanceLocation": "#/0", - "annotations": [ - { - "valid": true, - "keywordLocation": "#/items/$ref/type", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/type", - "instanceLocation": "#/0" - }, - { - "valid": true, - "keywordLocation": "#/items/$ref/properties", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/properties", - "instanceLocation": "#/0" - }, - { - "valid": true, - "keywordLocation": "#/items/$ref/required", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/required", - "instanceLocation": "#/0" - }, - { - "valid": true, - "keywordLocation": "#/items/$ref/additionalProperties", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/additionalProperties", - "instanceLocation": "#/0" - } - ] - } - ] - }, - { - "valid": false, - "keywordLocation": "#/items/$ref", - "absoluteKeywordLocation": - "http://example.com/polygon#/items/$ref", - "instanceLocation": "#/1", - "errors": [ - { - "valid": false, - "keywordLocation": "#/items/$ref", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point", - "instanceLocation": "#/1", - "errors": [ - { - "valid": true, - "keywordLocation": "#/items/$ref/type", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/type", - "instanceLocation": "#/1" - }, - { - "valid": true, - "keywordLocation": "#/items/$ref/properties", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/properties", - "instanceLocation": "#/1" - }, - { - "valid": false, - "keywordLocation": "#/items/$ref/required", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/required", - "instanceLocation": "#/1" - }, - { - "valid": false, - "keywordLocation": "#/items/$ref/additionalProperties", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/additionalProperties", - "instanceLocation": "#/1", - "errors": [ - { - "valid": false, - "keywordLocation": "#/items/$ref/additionalProperties", - "absoluteKeywordLocation": - "http://example.com/polygon#/definitions/point/additionalProperties", - "instanceLocation": "#/1/z" - } - ] - } - ] - } - ] - } - ] - }, - { - "valid": false, - "keywordLocation": "#/minItems", - "instanceLocation": "#" - } - ] -} diff --git a/web/.gitkeep b/web/.gitkeep new file mode 100644 index 00000000..e69de29b