├── .adr-dir ├── .envrc.dist ├── .github └── workflows │ ├── development.yaml │ ├── prerelease.yaml │ └── release.yaml ├── .gitignore ├── .goreleaser.yaml ├── .rules ├── .golangci.yml ├── .markdownlint.yaml ├── checkmake.ini └── yamllint.yaml ├── .tool-versions ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── codecov.yml ├── docs └── arch │ ├── 0001-record-architecture-decisions.md │ ├── 0002-add-quality-assurance-tooling.md │ ├── 0003-handling-libraries-extensions.md │ └── 0004-dependency-alert-tool.md ├── go.mod ├── go.sum ├── go.work ├── go.work.dist ├── go.work.sum ├── internal └── x │ └── text │ ├── cases.go │ └── cases_test.go ├── main.go ├── pkg ├── cmputil │ └── opts.go ├── codegen │ ├── emitter.go │ ├── model.go │ └── utils.go ├── generator │ ├── config.go │ ├── formatter.go │ ├── generate.go │ ├── json_formatter.go │ ├── name_scope.go │ ├── output.go │ ├── schema_generator.go │ ├── utils.go │ ├── validator.go │ └── yaml_formatter.go ├── mathutils │ ├── utils.go │ └── utils_test.go ├── schemas │ ├── loaders.go │ ├── model.go │ ├── parse.go │ ├── reference.go │ └── types.go ├── types │ ├── date.go │ └── time.go └── yamlutils │ └── yaml.go ├── renovate.json ├── scripts ├── asdf-add-plugins.sh ├── asdf-update-tools.sh ├── build.sh ├── docker-build.sh ├── docker-tools.sh ├── format-file.sh ├── format-golang.sh ├── format-json.sh ├── format-markdown.sh ├── format-shell.sh ├── format-yaml.sh ├── golang-install-tools.sh ├── golang-upgrade-deps-check.sh ├── golang-upgrade-deps.sh ├── lint-dockerfile.sh ├── lint-file.sh ├── lint-golang.sh ├── lint-json.sh ├── lint-makefile.sh ├── lint-markdown.sh ├── lint-shell.sh ├── lint-yaml.sh ├── release.sh ├── show-coverage-golang.sh └── test.sh └── tests ├── data ├── core │ ├── additionalProperties │ │ ├── arrayAdditionalProperties.go │ │ ├── arrayAdditionalProperties.json │ │ ├── autoinstallSchema.go │ │ ├── autoinstallSchema.json │ │ ├── boolAdditionalProperties.go │ │ ├── boolAdditionalProperties.json │ │ ├── intAdditionalProperties.go │ │ ├── intAdditionalProperties.json │ │ ├── numberAdditionalProperties.go │ │ ├── numberAdditionalProperties.json │ │ ├── objectAdditionalProperties.go │ │ ├── objectAdditionalProperties.json │ │ ├── objectWithPropsAdditionalProperties.go │ │ ├── objectWithPropsAdditionalProperties.json │ │ ├── stringAdditionalProperties.go │ │ └── stringAdditionalProperties.json │ ├── allOf │ │ ├── allOf.1.go │ │ ├── allOf.1.json │ │ ├── allOf.2.go │ │ ├── allOf.2.json │ │ ├── allOf.3.go │ │ ├── allOf.3.json │ │ ├── allOf.4.go │ │ ├── allOf.4.json │ │ ├── allOf.ref.go │ │ ├── allOf.ref.json │ │ ├── embeddedlinkend │ │ ├── embeddedlinkpath │ │ ├── embeddedlinkrelation │ │ ├── issue6.go │ │ └── issue6.json │ ├── anyOf │ │ ├── anyOf.1.go │ │ ├── anyOf.1.json │ │ ├── anyOf.2.go │ │ ├── anyOf.2.json │ │ ├── anyOf.3.go │ │ ├── anyOf.3.json │ │ ├── anyOf.4.go │ │ ├── anyOf.4.json │ │ ├── anyOf.5.go │ │ ├── anyOf.5.json │ │ ├── anyOf.6.go │ │ ├── anyOf.6.json │ │ ├── embeddedlinkend │ │ ├── embeddedlinkpath │ │ └── embeddedlinkrelation │ ├── array │ │ ├── array.go │ │ └── array.json │ ├── date │ │ ├── date.go │ │ └── date.json │ ├── dateTime │ │ ├── dateTime.go │ │ └── dateTime.json │ ├── duration │ │ ├── duration.go │ │ └── duration.json │ ├── ip │ │ ├── ip.go │ │ └── ip.json │ ├── nativeMap │ │ ├── map.go │ │ └── map.json │ ├── nullableType │ │ ├── nullableType.go │ │ └── nullableType.json │ ├── object │ │ ├── object.go │ │ └── object.json │ ├── objectAdditionalProperties │ │ ├── objectAdditionalProperties.go │ │ └── objectAdditionalProperties.json │ ├── objectEmpty │ │ ├── objectEmpty.go │ │ └── objectEmpty.json │ ├── objectNested │ │ ├── objectNested.go │ │ └── objectNested.json │ ├── objectPropertiesDefault │ │ ├── objectPropertiesDefault.go │ │ └── objectPropertiesDefault.json │ ├── primitives │ │ ├── primitives.go │ │ └── primitives.json │ ├── ref │ │ ├── ref.go │ │ └── ref.json │ ├── refExternalFile │ │ ├── refExternalFile.go │ │ └── refExternalFile.json │ ├── refExternalFileWithDupe │ │ ├── refExternalFileWithDupe.go │ │ └── refExternalFileWithDupe.json │ ├── refExternalFileWithScheme │ │ ├── refExternalFileWithScheme.go │ │ └── refExternalFileWithScheme.json │ ├── refExternalFileYaml │ │ ├── refExternalFile.go │ │ └── refExternalFile.json │ ├── refOld │ │ ├── refOld.go │ │ └── refOld.json │ ├── refToEnum │ │ ├── refToEnum.go │ │ └── refToEnum.json │ ├── refToMap │ │ ├── refToMap.go │ │ └── refToMap.json │ ├── refToPrimitiveString │ │ ├── refToPrimitiveString.go │ │ └── refToPrimitiveString.json │ └── time │ │ ├── time.go │ │ └── time.json ├── crossPackage │ ├── other │ │ ├── other.go │ │ └── other.json │ └── schema │ │ ├── schema.go │ │ └── schema.json ├── crossPackageNoOutput │ ├── other │ │ └── other.json │ └── schema │ │ ├── schema.go │ │ └── schema.json ├── deeplyNested │ ├── Makefile │ └── standalone │ │ ├── RolloutSpecification.go │ │ └── RolloutSpecification.json ├── disableCustomTypesForMaps │ ├── map.go │ ├── map.json │ ├── refToMap.go │ └── refToMap.json ├── disableOmitempty │ ├── omitempty.go │ └── omitempty.json ├── extraImports │ ├── gopkgYAMLv3 │ │ ├── gopkgYAMLv3.go │ │ ├── gopkgYAMLv3.json │ │ └── gopkgYAMLv3.yaml │ ├── gopkgYAMLv3AdditionalProperties │ │ ├── gopkgYAMLv3AdditionalProperties.go │ │ ├── gopkgYAMLv3AdditionalProperties.json │ │ └── gopkgYAMLv3AdditionalProperties.yaml │ └── gopkgYAMLv3invalidEnum │ │ └── gopkgYAMLv3invalidEnum.yaml ├── minSizedInts │ ├── arrays │ │ ├── exact.go │ │ └── exact.json │ ├── exactReferences │ │ ├── exact.go │ │ └── exact.json │ ├── exactSizes │ │ ├── exact.go │ │ └── exact.json │ ├── exactSizesExclusiveBool │ │ ├── exact.go │ │ └── exact.json │ ├── exactSizesExclusiveNum │ │ ├── exact.go │ │ └── exact.json │ ├── largerSizes │ │ ├── larger.go │ │ └── larger.json │ ├── restrictedSizes │ │ ├── restricted.go │ │ └── restricted.json │ └── restrictedSizesReferences │ │ ├── restricted.go │ │ └── restricted.json ├── misc │ ├── booleanAsSchema │ │ ├── booleanAsSchema.go │ │ └── booleanAsSchema.json │ ├── capitalization │ │ ├── capitalization.go │ │ └── capitalization.json │ ├── onlyModels │ │ ├── onlyModels.go │ │ └── onlyModels.json │ ├── specialCharacters │ │ ├── specialCharacters.go │ │ └── specialCharacters.json │ └── tags │ │ ├── tags.go │ │ └── tags.json ├── miscWithDefaults │ ├── case │ │ ├── case.go │ │ └── case.json │ ├── caseDupes │ │ ├── caseDupes.go │ │ └── caseDupes.json │ ├── cyclic │ │ ├── cyclic.go │ │ └── cyclic.json │ ├── cyclicAndRequired1 │ │ ├── cyclicAndRequired1.go │ │ └── cyclicAndRequired1.json │ ├── rootEmptyJustDefinitions │ │ ├── rootEmptyJustDefinitions.go │ │ └── rootEmptyJustDefinitions.json │ └── rootIsArrayOfString │ │ ├── rootIsArrayOfString.go │ │ └── rootIsArrayOfString.json ├── nameFromTitle │ ├── properties │ │ ├── properties.go │ │ └── properties.json │ ├── ref │ │ ├── ref.go │ │ └── ref.json │ └── refExternalFile │ │ ├── refExternalFile.go │ │ └── refExternalFile.json ├── regressions │ ├── issue32 │ │ ├── issue32.go │ │ └── issue32.json │ ├── issue378 │ │ ├── issue378.go │ │ └── issue378.json │ └── issue51 │ │ ├── issue51.go │ │ └── issue51.json ├── schemaExtensions │ ├── nillable │ │ ├── nillability.go │ │ └── nillability.json │ └── nonNillable │ │ ├── nillability.go │ │ └── nillability.json ├── validation │ ├── description │ │ ├── description.go │ │ └── description.json │ ├── enum │ │ ├── enum.go │ │ └── enum.json │ ├── exclusiveMaximum │ │ ├── exclusiveMaximum.go │ │ ├── exclusiveMaximum.json │ │ ├── exclusiveMaximumOld.go │ │ └── exclusiveMaximumOld.json │ ├── exclusiveMinimum │ │ ├── exclusiveMinimum.go │ │ ├── exclusiveMinimum.json │ │ ├── exclusiveMinimumOld.go │ │ └── exclusiveMinimumOld.json │ ├── maxItems │ │ ├── maxItems.go │ │ └── maxItems.json │ ├── maxLength │ │ ├── maxLength.go │ │ └── maxLength.json │ ├── maximum │ │ ├── maximum.go │ │ └── maximum.json │ ├── minItems │ │ ├── minItems.go │ │ └── minItems.json │ ├── minLength │ │ ├── minLength.go │ │ └── minLength.json │ ├── minMaxItems │ │ ├── minMaxItems.go │ │ └── minMaxItems.json │ ├── minimum │ │ ├── minimum.go │ │ └── minimum.json │ ├── multipleOf │ │ ├── multipleOf.go │ │ └── multipleOf.json │ ├── pattern │ │ ├── pattern.go │ │ └── pattern.json │ ├── primitive_defs │ │ ├── primitive_defs.go │ │ └── primitive_defs.json │ ├── readOnly │ │ ├── readOnly.go │ │ └── readOnly.json │ ├── readOnlyAndRequired │ │ ├── readOnlyAndRequired.go │ │ └── readOnlyAndRequired.json │ ├── requiredFields │ │ ├── requiredFields.go │ │ ├── requiredFields.json │ │ ├── requiredNullable.go │ │ └── requiredNullable.json │ ├── typeMultiple │ │ ├── typeMultiple.go │ │ └── typeMultiple.json │ ├── typedDefault │ │ ├── typedDefault.go │ │ └── typedDefault.json │ ├── typedDefaultEmpty │ │ ├── typedDefaultEmpty.go │ │ └── typedDefaultEmpty.json │ └── typedDefaultEnums │ │ ├── typedDefaultEnums.go │ │ └── typedDefaultEnums.json ├── validationDisabled │ └── readOnly │ │ ├── readOnlyNoValidation.go │ │ └── readOnlyNoValidation.json └── yaml │ ├── yamlMultilineDescriptions │ ├── yamlMultilineDescriptions.go │ └── yamlMultilineDescriptions.yaml │ └── yamlStructNameFromFile │ ├── yamlStructNameFromFile.go │ └── yamlStructNameFromFile.yaml ├── generation_test.go ├── go.mod ├── go.sum ├── helpers ├── checks.go └── other │ ├── go.mod │ └── main.go ├── serializable_date_test.go ├── serializable_time_test.go ├── unmarshal_json_test.go ├── unmarshal_yaml_test.go └── validation_test.go /.adr-dir: -------------------------------------------------------------------------------- 1 | docs/arch 2 | -------------------------------------------------------------------------------- /.envrc.dist: -------------------------------------------------------------------------------- 1 | use asdf 2 | -------------------------------------------------------------------------------- /.github/workflows/development.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: development 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | permissions: 9 | contents: read 10 | pull-requests: read 11 | concurrency: 12 | group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }} 13 | cancel-in-progress: true 14 | jobs: 15 | qa: 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 20 | - name: Setup Golang 21 | uses: actions/setup-go@v5 22 | with: 23 | go-version: ^1.23.8 24 | - name: Setup workspace 25 | run: cp go.work.dist go.work 26 | - name: Download golangci-lint installer 27 | run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh -o /tmp/install-golangci-lint.sh 28 | - name: Install golangci-lint 29 | run: sh /tmp/install-golangci-lint.sh -b /usr/local/bin v2.1.6 30 | - name: Lint Go files 31 | run: ./scripts/lint-golang.sh 32 | - name: Run tests 33 | run: ./scripts/test.sh 34 | - name: Upload coverage to Codecov 35 | uses: codecov/codecov-action@v5 36 | - name: Build binaries 37 | uses: goreleaser/goreleaser-action@v6 38 | with: 39 | distribution: goreleaser 40 | version: 2.9.0 41 | args: release --verbose --snapshot --clean 42 | env: 43 | GO_VERSION: 1.23.8 44 | -------------------------------------------------------------------------------- /.github/workflows/prerelease.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: prerelease 3 | on: 4 | push: 5 | tags: 6 | - v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+ 7 | - v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+ 8 | - v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+ 9 | permissions: 10 | contents: write 11 | concurrency: 12 | group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }} 13 | cancel-in-progress: true 14 | jobs: 15 | prerelease: 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 20 | - name: Fetch all tags 21 | run: git fetch --force --tags 22 | - name: Setup Golang 23 | uses: actions/setup-go@v5 24 | with: 25 | go-version: ^1.23.8 26 | - name: Setup workspace 27 | run: cp go.work.dist go.work 28 | - name: Run GoReleaser for release 29 | uses: goreleaser/goreleaser-action@v6 30 | with: 31 | distribution: goreleaser 32 | version: 2.9.0 33 | args: release --verbose --clean 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 36 | GO_VERSION: 1.23.8 37 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release 3 | on: 4 | push: 5 | tags: 6 | - v[0-9]+.[0-9]+.[0-9]+ 7 | permissions: 8 | contents: write 9 | concurrency: 10 | group: ${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }} 11 | cancel-in-progress: true 12 | jobs: 13 | release: 14 | runs-on: ubuntu-24.04 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 18 | - name: Fetch all tags 19 | run: git fetch --force --tags 20 | - name: Cleanup pre-release tags 21 | run: git tag -l | grep -E "v[0-9]+.[0-9]+.[0-9]+-(alpha|beta|rc).[0-9]+" | xargs git tag -d 22 | - name: Setup Golang 23 | uses: actions/setup-go@v5 24 | with: 25 | go-version: ^1.23.8 26 | - name: Setup workspace 27 | run: cp go.work.dist go.work 28 | - name: Log in to Docker Hub 29 | if: ${{ !contains(github.ref_name, '-') }} 30 | uses: docker/login-action@v3 31 | with: 32 | username: ${{ secrets.DOCKER_USERNAME }} 33 | password: ${{ secrets.DOCKER_PASSWORD }} 34 | - name: Run GoReleaser for release 35 | uses: goreleaser/goreleaser-action@v6 36 | with: 37 | distribution: goreleaser 38 | version: 2.9.0 39 | args: release --verbose --clean 40 | env: 41 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 42 | GO_VERSION: 1.23.8 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .envrc 3 | .idea 4 | coverage.out 5 | coverage/ 6 | bin/ 7 | dist/ 8 | vendor/ 9 | output/ 10 | go.work 11 | -------------------------------------------------------------------------------- /.rules/.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ########################### 3 | ########################### 4 | ## Markdown Linter rules ## 5 | ########################### 6 | ########################### 7 | 8 | # Linter rules doc 9 | # - 10 | # 11 | # Note 12 | # To comment out a single error 13 | # 14 | # any violations you want 15 | # 16 | # 17 | 18 | ############### 19 | # Rules by id # 20 | ############### 21 | MD004: false # Unordered list style 22 | MD007: 23 | indent: 2 # Unordered list indentation 24 | MD013: 25 | line_length: 120 # Line length 26 | MD014: false # Dollar signs used before commands without showing output 27 | MD026: 28 | punctuation: '.,;:!。,;:' # List of not allowed 29 | MD029: false # Ordered list item prefix 30 | MD033: false # Allow inline HTML 31 | MD036: false # Emphasis used instead of a heading 32 | MD041: false 33 | ################# 34 | # Rules by tags # 35 | ################# 36 | blank_lines: false # Error on blank lines 37 | -------------------------------------------------------------------------------- /.rules/checkmake.ini: -------------------------------------------------------------------------------- 1 | [maxbodylength] 2 | maxBodyLength = 10 3 | 4 | [minphony] 5 | disabled = true 6 | -------------------------------------------------------------------------------- /.rules/yamllint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | rules: 4 | line-length: 5 | max: 120 6 | level: warning 7 | comments-indentation: disable 8 | comments: 9 | min-spaces-from-content: 1 10 | ignore: | 11 | **/dist/** 12 | **/node_modules/** 13 | **/helm_chart/** 14 | **/.github/** 15 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | adr-tools 3.0.0 2 | golang 1.23.8 3 | golangci-lint 2.1.6 4 | goreleaser 2.9.0 5 | hadolint 2.12.0 6 | markdownlint-cli2 0.18.1 7 | shellcheck 0.10.0 8 | shfmt 3.11.0 9 | yamllint 1.37.1 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.8-alpine3.21 AS tools 2 | 3 | COPY scripts/tools-golang.sh /tmp/tools-golang.sh 4 | 5 | RUN /tmp/tools-golang.sh && rm /tmp/tools-golang.sh 6 | 7 | RUN apk add --no-cache jq~=1.7 yq~=4.33 && \ 8 | rm -rf /var/cache/apk/* /tmp/* 9 | 10 | FROM scratch AS go-jsonschema 11 | 12 | ENTRYPOINT ["/go-jsonschema"] 13 | 14 | COPY go-jsonschema / 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Alexander Staubo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "**/*.json" 3 | - "**/*.md" 4 | - "**/*.mod" 5 | - "**/*.sum" 6 | - "**/*.yaml" 7 | - "**/*.yml" 8 | - "**/*_test.go" 9 | - "**/Dockerfile" 10 | - "**/LICENSE" 11 | - "**/Makefile" 12 | - ".github/" 13 | - ".rules/" 14 | - ".vscode/" 15 | - "coverage/" 16 | - "dist/" 17 | - "docs/" 18 | - "output/" 19 | - "scripts/" 20 | 21 | codecov: 22 | require_ci_to_pass: true 23 | branch: main 24 | 25 | coverage: 26 | status: 27 | project: 28 | app: 29 | target: auto 30 | paths: "!tests/" 31 | tests: 32 | target: auto 33 | paths: "tests/" 34 | patch: 35 | enabled: true 36 | target: auto 37 | threshold: 0.25% 38 | only_pulls: true 39 | changes: 40 | enabled: true 41 | target: auto 42 | threshold: 0.25% 43 | only_pulls: true 44 | -------------------------------------------------------------------------------- /docs/arch/0001-record-architecture-decisions.md: -------------------------------------------------------------------------------- 1 | # 1. Record architecture decisions 2 | 3 | Date: 2023-04-09 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | We need to record the architectural decisions made on this project. 12 | 13 | ## Decision 14 | 15 | We will use Architecture Decision Records, as [described by Michael Nygard][documenting-architecture-decisions]. 16 | There is a good summary of available resources at [https://adr.github.io][github-adr]. 17 | 18 | ## Consequences 19 | 20 | See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [adr-tools][adr-tools]. 21 | 22 | [adr-tools]: https://github.com/npryce/adr-tools 23 | [documenting-architecture-decisions]: http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions 24 | [github-adr]: https://adr.github.io 25 | -------------------------------------------------------------------------------- /docs/arch/0002-add-quality-assurance-tooling.md: -------------------------------------------------------------------------------- 1 | # 2. Add Quality Assurance tooling 2 | 3 | Date: 2023-04-09 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | We want to increase the internal quality of the project. 12 | 13 | ## Decision 14 | 15 | We are going to introduce a number of tools and practices to help with most aspects of development, including: 16 | 17 | - Writing down Architectural Decision Records 18 | - Ensuring all required tooling is installable with a few commands 19 | - Running static code analysis wherever possible on all files 20 | - Developing automated tests to cover most of the codebase 21 | - Setting up CI pipelines to ensure all checks are run all the time 22 | - Keeping a consistent format when redacting commit messages and release notes 23 | 24 | In general, we want to automate all aspect of the project development lifecycle and leverage tools to the maximum extent 25 | to ensure we can focus our attention on delivering value. 26 | 27 | ## Consequences 28 | 29 | The project should reach a high level of automation and quality, guaranteed by practices and tools, 30 | while keeping maintenance costs at a reasonable level. 31 | -------------------------------------------------------------------------------- /docs/arch/0003-handling-libraries-extensions.md: -------------------------------------------------------------------------------- 1 | # 3. Handling libraries extensions 2 | 3 | Date: 2023-04-09 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | We sometimes find ourselves in a situation where we need to extend a library that we use. 12 | This can be for a number of reasons, but the most common ones are that we need to add a feature that the library 13 | doesn't support, or to add one or more helper functions that we need to make our life easier, or to reduce duplication, 14 | or to refactor away some non-business logic from our codebase to the library. 15 | 16 | ## Decision 17 | 18 | We will store all extensions and helpers to third-party and golang own's libraries with the `x/` folder. 19 | For example, helper functions for the `net/http` package will be stored in `x/net/http`. 20 | 21 | ## Consequences 22 | 23 | This will allow us to keep our codebase clean and easier to read, and it will keep the folders containing 24 | the business logic more focused on the tasks to solve. 25 | -------------------------------------------------------------------------------- /docs/arch/0004-dependency-alert-tool.md: -------------------------------------------------------------------------------- 1 | # 4. Dependency alert tool 2 | 3 | Date: 2023-04-09 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | We need a tool that helps us update the project dependencies automatically, keeping it as secure as possible. 12 | 13 | ## Decision 14 | 15 | We are going to use [Renovate][renovate] as the dependency maintainer: 16 | it is a third-party software installable as Github App that simplifies the update process, 17 | opening a PR when a new dependency update is available. 18 | I prefer this over Dependabot because of its flexibility and more advanced features. 19 | See [this article][article] for a more detailed comparison. 20 | 21 | ## Consequences 22 | 23 | We will have to spend less time updating dependencies manually, and the project will be more secure. 24 | 25 | [renovate]: https://github.com/renovatebot/renovate 26 | [article]: https://javascript.plainenglish.io/automate-dependency-updates-by-renovate-not-by-dependabot-6efddd549a3e 27 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/atombender/go-jsonschema 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.8 6 | 7 | require ( 8 | dario.cat/mergo v1.0.2 9 | github.com/davecgh/go-spew v1.1.1 // indirect 10 | github.com/goccy/go-yaml v1.18.0 11 | github.com/google/go-cmp v0.7.0 12 | github.com/mitchellh/go-wordwrap v1.0.1 13 | github.com/pkg/errors v0.9.1 14 | github.com/sanity-io/litter v1.5.8 15 | github.com/spf13/cobra v1.9.1 16 | github.com/stretchr/testify v1.10.0 17 | ) 18 | 19 | require gopkg.in/yaml.v3 v3.0.1 // indirect 20 | 21 | require github.com/sosodev/duration v1.3.1 22 | 23 | require ( 24 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 25 | github.com/pmezard/go-difflib v1.0.0 // indirect 26 | github.com/spf13/pflag v1.0.6 // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /go.work: -------------------------------------------------------------------------------- 1 | go 1.23.0 2 | 3 | use ( 4 | . 5 | ./tests 6 | ) 7 | -------------------------------------------------------------------------------- /go.work.dist: -------------------------------------------------------------------------------- 1 | go 1.23.0 2 | 3 | use ( 4 | . 5 | ./tests 6 | ) 7 | -------------------------------------------------------------------------------- /internal/x/text/cases_test.go: -------------------------------------------------------------------------------- 1 | package text_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | 8 | "github.com/atombender/go-jsonschema/internal/x/text" 9 | ) 10 | 11 | func TestNewCaser(t *testing.T) { 12 | t.Parallel() 13 | 14 | capitalizations := []string{"ID", "URL"} 15 | resolveExtensions := []string{".go", ".txt"} 16 | 17 | caser := text.NewCaser(capitalizations, resolveExtensions) 18 | 19 | assert.NotNil(t, caser) 20 | } 21 | 22 | func TestIdentifierFromFileName(t *testing.T) { 23 | t.Parallel() 24 | 25 | caser := text.NewCaser(nil, []string{".go", ".txt"}) 26 | 27 | tests := []struct { 28 | fileName string 29 | expected string 30 | }{ 31 | {"example.go", "Example"}, 32 | {"example.txt", "Example"}, 33 | {"example.md", "ExampleMd"}, 34 | {"example", "Example"}, 35 | } 36 | 37 | for _, test := range tests { 38 | result := caser.IdentifierFromFileName(test.fileName) 39 | assert.Equal(t, test.expected, result) 40 | } 41 | } 42 | 43 | func TestIdentifierize(t *testing.T) { 44 | t.Parallel() 45 | 46 | caser := text.NewCaser(nil, nil) 47 | 48 | tests := []struct { 49 | input string 50 | expected string 51 | }{ 52 | {"", "Blank"}, 53 | {"*", "Wildcard"}, 54 | {"example", "Example"}, 55 | {"example_test", "ExampleTest"}, 56 | {"exampleTest", "ExampleTest"}, 57 | {"ExampleTest", "ExampleTest"}, 58 | {"123example", "A123Example"}, 59 | {"example123Test", "Example123Test"}, 60 | } 61 | 62 | for _, test := range tests { 63 | result := caser.Identifierize(test.input) 64 | assert.Equal(t, test.expected, result) 65 | } 66 | } 67 | 68 | func TestCapitalize(t *testing.T) { 69 | t.Parallel() 70 | 71 | caser := text.NewCaser([]string{"ID", "URL"}, nil) 72 | 73 | tests := []struct { 74 | input string 75 | expected string 76 | }{ 77 | {"", ""}, 78 | {"id", "ID"}, 79 | {"url", "URL"}, 80 | {"example", "Example"}, 81 | } 82 | 83 | for _, test := range tests { 84 | result := caser.Capitalize(test.input) 85 | assert.Equal(t, test.expected, result) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /pkg/cmputil/opts.go: -------------------------------------------------------------------------------- 1 | package cmputil 2 | 3 | import ( 4 | "github.com/google/go-cmp/cmp" 5 | "github.com/google/go-cmp/cmp/cmpopts" 6 | ) 7 | 8 | func Opts(t ...any) []cmp.Option { 9 | opts := make([]cmp.Option, 0) 10 | 11 | for _, v := range t { 12 | opts = append(opts, cmpopts.IgnoreUnexported(v), cmpopts.IgnoreFields(v, "Ref"), cmpopts.IgnoreFields(v, "AnyOf")) 13 | } 14 | 15 | return opts 16 | } 17 | -------------------------------------------------------------------------------- /pkg/codegen/emitter.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/mitchellh/go-wordwrap" 8 | ) 9 | 10 | type Emitter struct { 11 | sb strings.Builder 12 | maxLineLength int32 13 | start bool 14 | indent int32 15 | } 16 | 17 | func NewEmitter(maxLineLength int32) *Emitter { 18 | return &Emitter{ 19 | maxLineLength: maxLineLength, 20 | start: true, 21 | } 22 | } 23 | 24 | func (e *Emitter) String() string { 25 | return e.sb.String() 26 | } 27 | 28 | func (e *Emitter) Bytes() []byte { 29 | return []byte(e.sb.String()) 30 | } 31 | 32 | func (e *Emitter) Indent(n int32) { 33 | if e.indent+n < 0 { 34 | panic("unexpected unbalanced indentation") 35 | } 36 | 37 | e.indent += n 38 | } 39 | 40 | func (e *Emitter) Comment(s string) { 41 | if s != "" { 42 | limit := e.maxLineLength - e.indent 43 | if limit < 0 { 44 | limit = 0 45 | } 46 | 47 | //nolint:gosec // limit is guarded against negative values 48 | lines := strings.Split(wordwrap.WrapString(s, uint(limit)), "\n") 49 | 50 | for _, line := range lines { 51 | e.Printlnf("// %s", line) 52 | } 53 | } 54 | } 55 | 56 | func (e *Emitter) Commentf(s string, args ...interface{}) { 57 | s = fmt.Sprintf(s, args...) 58 | if s != "" { 59 | limit := e.maxLineLength - e.indent 60 | if limit < 0 { 61 | limit = 0 62 | } 63 | 64 | //nolint:gosec // limit is guarded against negative values 65 | lines := strings.Split(wordwrap.WrapString(s, uint(limit)), "\n") 66 | 67 | for _, line := range lines { 68 | e.Printlnf("// %s", line) 69 | } 70 | } 71 | } 72 | 73 | func (e *Emitter) Printf(format string, args ...interface{}) { 74 | e.checkIndent() 75 | fmt.Fprintf(&e.sb, format, args...) 76 | e.start = false 77 | } 78 | 79 | func (e *Emitter) Printlnf(format string, args ...interface{}) { 80 | e.Printf(format, args...) 81 | e.Newline() 82 | } 83 | 84 | func (e *Emitter) Newline() { 85 | e.sb.WriteRune('\n') 86 | e.start = true 87 | } 88 | 89 | func (e *Emitter) checkIndent() { 90 | if e.start { 91 | for range e.indent { 92 | e.sb.WriteRune('\t') 93 | } 94 | 95 | e.start = false 96 | } 97 | } 98 | 99 | func (e *Emitter) MaxLineLength() int32 { 100 | return e.maxLineLength 101 | } 102 | -------------------------------------------------------------------------------- /pkg/generator/config.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import "github.com/atombender/go-jsonschema/pkg/schemas" 4 | 5 | type Config struct { 6 | SchemaMappings []SchemaMapping 7 | // ExtraImports allows the generator to pull imports from outside the standard library. 8 | ExtraImports bool 9 | // Capitalizations configures capitalized forms for identifiers which take precedence over the default algorithm. 10 | Capitalizations []string 11 | // ResolveExtensions configures file extensions to use when resolving schema names. 12 | ResolveExtensions []string 13 | // YAMLExtensions configures the file extensions that are recognized as YAML files. 14 | YAMLExtensions []string 15 | // DefaultPackageName configures the package to declare files under. 16 | DefaultPackageName string 17 | // DefaultOutputName configures the file to write. 18 | DefaultOutputName string 19 | // StructNameFromTitle configures the generator to use the schema title as the generated struct name. 20 | StructNameFromTitle bool 21 | // Warner provides a handler for warning messages. 22 | Warner func(string) 23 | // Tags specifies which struct tags should be generated. 24 | Tags []string 25 | // OnlyModels configures the generator to omit unmarshal methods, validations, anything but models. 26 | OnlyModels bool 27 | // MinSizedInts configures the generator to use the smallest int and uint types based on schema maximum values. 28 | MinSizedInts bool 29 | // MinimalNames configures the generator to use the shortest identifier names possible. 30 | MinimalNames bool 31 | // Loader provides a schema loader for the generator. 32 | Loader schemas.Loader 33 | // When DisableOmitempty is set to true, 34 | // an "omitempty" tag will never be present in generated struct fields. 35 | // When DisableOmitempty is set to false, 36 | // an "omitempty" tag will be present for all fields that are not required. 37 | DisableOmitempty bool 38 | // DisableReadOnlyValidation configures the generator to omit validation for read-only fields. 39 | DisableReadOnlyValidation bool 40 | // DisableCustomTypesForMaps configures the generator to avoid creating a custom type for maps, 41 | // and to use the map type directly. 42 | DisableCustomTypesForMaps bool 43 | } 44 | 45 | type SchemaMapping struct { 46 | SchemaID string 47 | PackageName string 48 | RootType string 49 | OutputName string 50 | } 51 | -------------------------------------------------------------------------------- /pkg/generator/formatter.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "github.com/atombender/go-jsonschema/pkg/codegen" 5 | ) 6 | 7 | type formatter interface { 8 | addImport(out *codegen.File, declType codegen.TypeDecl) 9 | 10 | generate(output *output, declType codegen.TypeDecl, validators []validator) func(*codegen.Emitter) error 11 | enumMarshal(declType codegen.TypeDecl) func(*codegen.Emitter) error 12 | enumUnmarshal( 13 | declType codegen.TypeDecl, 14 | enumType codegen.Type, 15 | valueConstant *codegen.Var, 16 | wrapInStruct bool, 17 | ) func(*codegen.Emitter) error 18 | } 19 | -------------------------------------------------------------------------------- /pkg/generator/name_scope.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type nameScope struct { 8 | stack []string 9 | } 10 | 11 | func newNameScope(s string) nameScope { 12 | return nameScope{stack: []string{s}} 13 | } 14 | 15 | func (ns nameScope) string() string { 16 | return strings.Join(ns.stack, "") 17 | } 18 | 19 | func (ns nameScope) stringFrom(start int) string { 20 | if start >= len(ns.stack) { 21 | return "" 22 | } 23 | 24 | return strings.Join(ns.stack[start:], "") 25 | } 26 | 27 | func (ns nameScope) add(s string) nameScope { 28 | result := make([]string, len(ns.stack)+1) 29 | copy(result, ns.stack) 30 | result[len(result)-1] = s 31 | 32 | ns.stack = result 33 | 34 | return ns 35 | } 36 | 37 | func (ns nameScope) last() (string, bool) { 38 | if len(ns.stack) == 0 { 39 | return "", false 40 | } 41 | 42 | return ns.stack[len(ns.stack)-1], true 43 | } 44 | 45 | func (ns nameScope) len() int { 46 | return len(ns.stack) 47 | } 48 | -------------------------------------------------------------------------------- /pkg/generator/utils.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "sort" 5 | 6 | "github.com/atombender/go-jsonschema/pkg/codegen" 7 | "github.com/atombender/go-jsonschema/pkg/schemas" 8 | ) 9 | 10 | const additionalProperties = "AdditionalProperties" 11 | 12 | func sortedKeys[T any](props map[string]T) []string { 13 | names := make([]string, 0, len(props)) 14 | for name := range props { 15 | names = append(names, name) 16 | } 17 | 18 | sort.Strings(names) 19 | 20 | return names 21 | } 22 | 23 | func sortDefinitionsByName(defs schemas.Definitions) []string { 24 | names := make([]string, 0, len(defs)) 25 | 26 | for name := range defs { 27 | names = append(names, name) 28 | } 29 | 30 | sort.Strings(names) 31 | 32 | return names 33 | } 34 | 35 | func isNamedType(t codegen.Type) bool { 36 | switch x := t.(type) { 37 | case *codegen.NamedType: 38 | return true 39 | 40 | case *codegen.PointerType: 41 | if _, ok := x.Type.(*codegen.NamedType); ok { 42 | return true 43 | } 44 | } 45 | 46 | return false 47 | } 48 | 49 | func isMapType(t codegen.Type) bool { 50 | _, isMapType := t.(*codegen.MapType) 51 | 52 | return isMapType 53 | } 54 | -------------------------------------------------------------------------------- /pkg/mathutils/utils.go: -------------------------------------------------------------------------------- 1 | package mathutils 2 | 3 | // NormalizeBounds is a public function that normalizes the given bounds and exclusivity flags. 4 | func NormalizeBounds( 5 | minimum, maximum *float64, exclusiveMinimum, exclusiveMaximum *any, 6 | ) (*float64, *float64, bool, bool) { 7 | var minBound, maxBound *float64 8 | 9 | var minExclusive, maxExclusive bool 10 | 11 | if exclusiveMinimum != nil { 12 | switch v := (*exclusiveMinimum).(type) { 13 | case bool: 14 | minExclusive = v 15 | minBound = minimum 16 | 17 | case float64: 18 | if minimum == nil || v > *minimum { 19 | minBound = &v 20 | minExclusive = true 21 | } else { 22 | minBound = minimum 23 | minExclusive = false 24 | } 25 | } 26 | } else { 27 | minBound = minimum 28 | minExclusive = false 29 | } 30 | 31 | if minimum != nil && minBound == nil { 32 | minBound = minimum 33 | minExclusive = false 34 | } 35 | 36 | if exclusiveMaximum != nil { 37 | switch v := (*exclusiveMaximum).(type) { 38 | case bool: 39 | maxExclusive = v 40 | maxBound = maximum 41 | 42 | case float64: 43 | if maximum == nil || v < *maximum { 44 | maxBound = &v 45 | maxExclusive = true 46 | } else { 47 | maxBound = maximum 48 | maxExclusive = false 49 | } 50 | } 51 | } else { 52 | maxBound = maximum 53 | maxExclusive = false 54 | } 55 | 56 | if maximum != nil && maxBound == nil { 57 | maxBound = maximum 58 | maxExclusive = false 59 | } 60 | 61 | return minBound, maxBound, minExclusive, maxExclusive 62 | } 63 | -------------------------------------------------------------------------------- /pkg/schemas/parse.go: -------------------------------------------------------------------------------- 1 | package schemas 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "os" 8 | 9 | "github.com/goccy/go-yaml" 10 | 11 | "github.com/atombender/go-jsonschema/pkg/yamlutils" 12 | ) 13 | 14 | func FromJSONFile(fileName string) (*Schema, error) { 15 | f, err := os.Open(fileName) 16 | if err != nil { 17 | return nil, fmt.Errorf("failed to open file: %w", err) 18 | } 19 | 20 | defer func() { 21 | _ = f.Close() 22 | }() 23 | 24 | return FromJSONReader(f) 25 | } 26 | 27 | func FromJSONReader(r io.Reader) (*Schema, error) { 28 | var schema Schema 29 | if err := json.NewDecoder(r).Decode(&schema); err != nil { 30 | return nil, fmt.Errorf("failed to unmarshal JSON: %w", err) 31 | } 32 | 33 | return &schema, nil 34 | } 35 | 36 | func FromYAMLFile(fileName string) (*Schema, error) { 37 | f, err := os.Open(fileName) 38 | if err != nil { 39 | return nil, fmt.Errorf("failed to open file: %w", err) 40 | } 41 | 42 | defer func() { 43 | _ = f.Close() 44 | }() 45 | 46 | return FromYAMLReader(f) 47 | } 48 | 49 | func FromYAMLReader(r io.Reader) (*Schema, error) { 50 | // Marshal to JSON first because YAML decoder doesn't understand JSON tags. 51 | var m map[string]interface{} 52 | 53 | if err := yaml.NewDecoder(r).Decode(&m); err != nil { 54 | return nil, fmt.Errorf("failed to unmarshal YAML: %w", err) 55 | } 56 | 57 | yamlutils.FixMapKeys(m) 58 | 59 | value, err := json.Marshal(m) 60 | if err != nil { 61 | return nil, fmt.Errorf("failed to marshal JSON: %w", err) 62 | } 63 | 64 | var schema Schema 65 | 66 | if err = json.Unmarshal(value, &schema); err != nil { 67 | return nil, fmt.Errorf("failed to unmarshal JSON: %w", err) 68 | } 69 | 70 | return &schema, nil 71 | } 72 | -------------------------------------------------------------------------------- /pkg/schemas/reference.go: -------------------------------------------------------------------------------- 1 | package schemas 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net/url" 7 | ) 8 | 9 | var ( 10 | ErrEmptyReference = errors.New("reference is empty") 11 | ErrUnsupportedRefFormat = errors.New("unsupported $ref format") 12 | ErrCannotParseRef = errors.New("cannot parse $ref") 13 | ErrUnsupportedRefSchema = errors.New("unsupported $ref schema") 14 | ErrGetRefType = errors.New("cannot get $ref type") 15 | ) 16 | 17 | type RefType string 18 | 19 | const ( 20 | RefTypeFile RefType = "file" 21 | RefTypeHTTP RefType = "http" 22 | RefTypeHTTPS RefType = "https" 23 | RefTypeUnknown RefType = "unknown" 24 | ) 25 | 26 | func GetRefType(ref string) (RefType, error) { 27 | urlRef, err := url.Parse(ref) 28 | if err != nil { 29 | return RefTypeUnknown, fmt.Errorf("%w: %w", ErrGetRefType, err) 30 | } 31 | 32 | switch urlRef.Scheme { 33 | case "http": 34 | return RefTypeHTTP, nil 35 | 36 | case "https": 37 | return RefTypeHTTPS, nil 38 | 39 | case "file", "": 40 | return RefTypeFile, nil 41 | 42 | default: 43 | return RefTypeUnknown, fmt.Errorf("%w: %w", ErrGetRefType, ErrUnsupportedRefSchema) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pkg/schemas/types.go: -------------------------------------------------------------------------------- 1 | package schemas 2 | 3 | import "strings" 4 | 5 | const ( 6 | TypeNameString = "string" 7 | TypeNameArray = "array" 8 | TypeNameNumber = "number" 9 | TypeNameInteger = "integer" 10 | TypeNameObject = "object" 11 | TypeNameBoolean = "boolean" 12 | TypeNameNull = "null" 13 | PrefixEnumValue = "enumValues_" 14 | ) 15 | 16 | func IsPrimitiveType(t string) bool { 17 | switch t { 18 | case TypeNameString, TypeNameNumber, TypeNameInteger, TypeNameBoolean, TypeNameNull: 19 | return true 20 | 21 | default: 22 | return false 23 | } 24 | } 25 | 26 | func CleanNameForSorting(name string) string { 27 | if strings.HasPrefix(name, PrefixEnumValue) { 28 | return strings.TrimPrefix(name, PrefixEnumValue) + "_enumValues" // Append a string for sorting properly. 29 | } 30 | 31 | return name 32 | } 33 | 34 | func isPrimitiveTypeList(types []*Type) bool { 35 | for _, typ := range types { 36 | if len(typ.Type) == 0 { 37 | continue 38 | } 39 | 40 | if !IsPrimitiveType(typ.Type[0]) { 41 | return false 42 | } 43 | } 44 | 45 | return true 46 | } 47 | -------------------------------------------------------------------------------- /pkg/types/date.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "strings" 7 | "time" 8 | ) 9 | 10 | var ErrDateNotJSONString = errors.New("cannot parse non-string value as a date") 11 | 12 | type SerializableDate struct { 13 | time.Time 14 | } 15 | 16 | func (date SerializableDate) MarshalJSON() ([]byte, error) { 17 | return []byte("\"" + date.Format(time.DateOnly) + "\""), nil 18 | } 19 | 20 | func (date *SerializableDate) UnmarshalJSON(data []byte) error { 21 | stringifiedData := string(data) 22 | if stringifiedData == "null" { 23 | return nil 24 | } 25 | 26 | if !strings.HasPrefix(stringifiedData, "\"") || !strings.HasSuffix(stringifiedData, "\"") { 27 | return ErrDateNotJSONString 28 | } 29 | 30 | dataWithoutQuotes := stringifiedData[1 : len(stringifiedData)-1] 31 | 32 | parsedDate, err := time.Parse(time.DateOnly, dataWithoutQuotes) 33 | if err != nil { 34 | return fmt.Errorf("unable to parse date from JSON: %w", err) 35 | } 36 | 37 | date.Time = parsedDate 38 | 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /pkg/types/time.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "strings" 7 | "time" 8 | ) 9 | 10 | var ErrTimeNotJSONString = errors.New("cannot parse non-string value as a time") 11 | 12 | type SerializableTime struct { 13 | time.Time 14 | } 15 | 16 | func (t SerializableTime) MarshalJSON() ([]byte, error) { 17 | return []byte("\"" + t.Format(time.TimeOnly) + "\""), nil 18 | } 19 | 20 | func (t *SerializableTime) UnmarshalJSON(data []byte) error { 21 | stringifiedData := string(data) 22 | if stringifiedData == "null" { 23 | return nil 24 | } 25 | 26 | if !strings.HasPrefix(stringifiedData, "\"") || !strings.HasSuffix(stringifiedData, "\"") { 27 | return ErrTimeNotJSONString 28 | } 29 | 30 | timeWithoutQuotes := stringifiedData[1 : len(stringifiedData)-1] 31 | 32 | // RFC 3339 full-time layouts. 33 | layouts := []string{ 34 | "15:04:05", // Time without offset. 35 | "15:04:05Z07:00", // Time with offset. Works with ..Z, ..+09:00 ... 36 | } 37 | 38 | var parsedTime time.Time 39 | 40 | var err error 41 | 42 | for _, layout := range layouts { 43 | parsedTime, err = time.Parse(layout, timeWithoutQuotes) 44 | if err == nil { 45 | t.Time = parsedTime 46 | 47 | return nil 48 | } 49 | } 50 | 51 | if err != nil { 52 | return fmt.Errorf("unable to parse time from JSON: %w", err) 53 | } 54 | 55 | return nil 56 | } 57 | -------------------------------------------------------------------------------- /pkg/yamlutils/yaml.go: -------------------------------------------------------------------------------- 1 | package yamlutils 2 | 3 | import "fmt" 4 | 5 | // FixMapKeys fixes non-string keys that occur in nested YAML unmarshalling results. 6 | func FixMapKeys(m map[string]interface{}) { 7 | for k, v := range m { 8 | m[k] = fixMapKeysIn(v) 9 | } 10 | } 11 | 12 | // Fix non-string keys that occur in nested YAML unmarshalling results. 13 | func fixMapKeysIn(value interface{}) interface{} { 14 | switch t := value.(type) { 15 | case []interface{}: 16 | for i, elem := range t { 17 | t[i] = fixMapKeysIn(elem) 18 | } 19 | 20 | return t 21 | 22 | case map[interface{}]interface{}: 23 | m := map[string]interface{}{} 24 | 25 | for k, v := range t { 26 | ks, ok := k.(string) 27 | if !ok { 28 | ks = fmt.Sprintf("%v", k) 29 | } 30 | 31 | m[ks] = fixMapKeysIn(v) 32 | } 33 | 34 | return m 35 | 36 | default: 37 | return value 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ], 6 | "constraints": { 7 | "go": "1.23" 8 | }, 9 | "packageRules": [ 10 | { 11 | "description": "Update all dependencies up to the minor release level", 12 | "matchUpdateTypes": [ 13 | "patch", 14 | "pin", 15 | "digest" 16 | ], 17 | "automerge": true 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /scripts/asdf-add-plugins.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | cut -d ' ' -f 1 < .tool-versions | xargs -n 1 asdf plugin add 7 | -------------------------------------------------------------------------------- /scripts/asdf-update-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # shellcheck disable=SC2016 4 | 5 | set -e 6 | set -o errexit -o nounset 7 | 8 | cut -d ' ' -f 1 < .tool-versions | \ 9 | xargs -I {} -n 1 sh -c 'echo {} $(asdf latest {} 2>/dev/null)' > \ 10 | .tool-versions.tmp 11 | 12 | mv .tool-versions.tmp .tool-versions 13 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | GO_VERSION=$(go version | cut -d ' ' -f 3) 7 | 8 | export GO_VERSION 9 | 10 | goreleaser check 11 | goreleaser release --verbose --snapshot --clean 12 | 13 | unset GO_VERSION 14 | -------------------------------------------------------------------------------- /scripts/docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | docker build --tag omissis/go-jsonschema:latest --file Dockerfile --target go-jsonschema . 7 | -------------------------------------------------------------------------------- /scripts/docker-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | docker build --tag omissis/go-jsonschema:tools-latest --file Dockerfile --target tools . 7 | -------------------------------------------------------------------------------- /scripts/format-file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | IGNORE_PATHS='.git/,.github/,.vscode/,.idea/' 7 | 8 | file-cr --text --ignore "${IGNORE_PATHS}" --fix --path . 9 | file-crlf --text --ignore "${IGNORE_PATHS}" --fix --path . 10 | file-nullbyte --text --ignore "${IGNORE_PATHS}" --fix --path . 11 | file-trailing-newline --text --ignore "${IGNORE_PATHS}" --fix --path . 12 | file-trailing-single-newline --text --ignore "${IGNORE_PATHS}" --fix --path . 13 | file-trailing-space --text --ignore "${IGNORE_PATHS}" --fix --path . 14 | file-utf8 --text --ignore "${IGNORE_PATHS}" --fix --path . 15 | file-utf8-bom --text --ignore "${IGNORE_PATHS}" --fix --path . 16 | -------------------------------------------------------------------------------- /scripts/format-golang.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | GOFILES=$(find . -name "*.go" -type f -not -path './vendor/*' -not -path './tests/data/*' | sed 's/^\.\///g') 7 | 8 | echo "formatting with gofmt.." 9 | echo "${GOFILES}" | xargs -I {} sh -c 'gofmt -w -s {}' 10 | 11 | echo "formatting with gofumpt.." 12 | echo "${GOFILES}" | xargs -I {} sh -c 'gofumpt -w -extra {}' 13 | 14 | echo "formatting with goimports.." 15 | echo "${GOFILES}" | xargs -I {} sh -c 'goimports -v -w -e -local github.com/atombender {}' 16 | 17 | echo "formatting with gci.." 18 | echo "${GOFILES}" | 19 | xargs -I {} sh -c 'gci write --skip-generated -s standard -s default -s "Prefix(github.com/atombender)" {}' 20 | -------------------------------------------------------------------------------- /scripts/format-json.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | find . -name "*.json" -type f -exec sh -c 'jq -M . "$1" > "$1".tmp' shell {} \; -exec mv {}.tmp {} \; 7 | -------------------------------------------------------------------------------- /scripts/format-markdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | markdownlint-cli2 "**/*.md" --config ".rules/.markdownlint.yaml" --fix 7 | -------------------------------------------------------------------------------- /scripts/format-shell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | shfmt -i 2 -ci -sr -w . 7 | -------------------------------------------------------------------------------- /scripts/format-yaml.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | find . \( -name '*.yaml' -o -name '*.yml' \) -type f -exec yq eval -P -I 2 -M -i {} \; 7 | -------------------------------------------------------------------------------- /scripts/golang-install-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | CHECKMAKE_VERSION="0.2.2" 7 | GCI_VERSION="v0.13.4" 8 | GINKGO_VERSION="v2.17.1" 9 | GO_COVER_TREEMAP_VERSION="v1.4.2" 10 | GOFUMPT_VERSION="v0.6.0" 11 | GOIMPORTS_VERSION="v0.20.0" 12 | GOLANGCI_LINT_VERSION="v2.1.6" 13 | 14 | go install "github.com/daixiang0/gci@${GCI_VERSION}" 15 | go install "github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}" 16 | go install "github.com/mrtazz/checkmake/cmd/checkmake@${CHECKMAKE_VERSION}" 17 | go install "github.com/nikolaydubina/go-cover-treemap@${GO_COVER_TREEMAP_VERSION}" 18 | go install "github.com/onsi/ginkgo/v2/ginkgo@${GINKGO_VERSION}" 19 | go install "golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION}" 20 | go install "mvdan.cc/gofumpt@${GOFUMPT_VERSION}" 21 | -------------------------------------------------------------------------------- /scripts/golang-upgrade-deps-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | go list -mod=readonly -u \ 7 | -f "{{if (and (not (or .Main .Indirect)) .Update)}}{{.Path}}: {{.Version}} -> {{.Update.Version}}{{end}}" \ 8 | -m all 9 | -------------------------------------------------------------------------------- /scripts/golang-upgrade-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | go get -u ./... && go mod tidy 7 | -------------------------------------------------------------------------------- /scripts/lint-dockerfile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | find . \ 7 | -type f \ 8 | -name '*Dockerfile*' \ 9 | -not -path './.git/*' \ 10 | -exec hadolint {} \; 11 | -------------------------------------------------------------------------------- /scripts/lint-file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | IGNORE_PATHS='.git/,.github/,.vscode/,.idea/' 7 | 8 | file-cr --text --ignore "${IGNORE_PATHS}" --path . 9 | file-crlf --text --ignore "${IGNORE_PATHS}" --path . 10 | file-trailing-single-newline --text --ignore "${IGNORE_PATHS}" --path . 11 | file-trailing-space --text --ignore "${IGNORE_PATHS}" --path . 12 | file-utf8 --text --ignore "${IGNORE_PATHS}" --path . 13 | file-utf8-bom --text --ignore "${IGNORE_PATHS}" --path . 14 | -------------------------------------------------------------------------------- /scripts/lint-golang.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | golangci-lint -v run --color=always --config=.rules/.golangci.yml ./... 7 | golangci-lint -v run --color=always --config=.rules/.golangci.yml tests/*.go 8 | golangci-lint -v run --color=always --config=.rules/.golangci.yml tests/helpers/*.go 9 | -------------------------------------------------------------------------------- /scripts/lint-json.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | find . \ 7 | -type f \ 8 | -not -path ".git" \ 9 | -not -path ".github" \ 10 | -not -path ".vscode" \ 11 | -not -path ".idea" \ 12 | -name "*.json" \ 13 | -exec jsonlint -c -q -t ' ' {} \; 14 | -------------------------------------------------------------------------------- /scripts/lint-makefile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | checkmake --config .rules/checkmake.ini Makefile 7 | -------------------------------------------------------------------------------- /scripts/lint-markdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | markdownlint-cli2 "**/*.md" --config ".rules/.markdownlint.yaml" 7 | -------------------------------------------------------------------------------- /scripts/lint-shell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | shellcheck -a -o all -s bash -- **/*.sh 7 | -------------------------------------------------------------------------------- /scripts/lint-yaml.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | yamllint -c .rules/yamllint.yaml . 7 | -------------------------------------------------------------------------------- /scripts/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | GO_VERSION=$(go version | cut -d ' ' -f 3) 7 | 8 | export GO_VERSION 9 | 10 | goreleaser check 11 | goreleaser --debug release --clean 12 | 13 | unset GO_VERSION 14 | -------------------------------------------------------------------------------- /scripts/show-coverage-golang.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | OS="$(uname -s)" 7 | 8 | export _BIN_OPEN="open" 9 | if [[ "${OS}" = "Linux" ]]; then 10 | _BIN_OPEN="xdg-open" 11 | fi 12 | 13 | go tool cover -html=coverage.out -o coverage.html 14 | 15 | go-cover-treemap -coverprofile coverage.out > coverage.svg && ${_BIN_OPEN} coverage.svg 16 | 17 | unset _BIN_OPEN 18 | -------------------------------------------------------------------------------- /scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o errexit -o nounset 5 | 6 | mkdir -p "${PWD}/coverage/pkg" 7 | mkdir -p "${PWD}/coverage/tests" 8 | 9 | go test -v -race -mod=readonly -covermode=atomic -coverpkg=./... -cover ./... -args -test.gocoverdir="${PWD}/coverage/pkg" 10 | go test -v -race -mod=readonly -covermode=atomic -coverpkg=./... -cover ./tests -args -test.gocoverdir="${PWD}/coverage/tests" 11 | 12 | go tool covdata textfmt -i=./coverage/tests,./coverage/pkg -o coverage.out 13 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/arrayAdditionalProperties.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "github.com/go-viper/mapstructure/v2" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "reflect" 9 | import "strings" 10 | 11 | type ArrayAdditionalProperties struct { 12 | // Name corresponds to the JSON schema field "name". 13 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 14 | 15 | AdditionalProperties map[string][]interface{} `mapstructure:",remain"` 16 | } 17 | 18 | // UnmarshalJSON implements json.Unmarshaler. 19 | func (j *ArrayAdditionalProperties) UnmarshalJSON(value []byte) error { 20 | var raw map[string]interface{} 21 | if err := json.Unmarshal(value, &raw); err != nil { 22 | return err 23 | } 24 | type Plain ArrayAdditionalProperties 25 | var plain Plain 26 | if err := json.Unmarshal(value, &plain); err != nil { 27 | return err 28 | } 29 | if v, ok := raw[""]; !ok || v == nil { 30 | plain.AdditionalProperties = map[string][]interface{}{} 31 | } 32 | st := reflect.TypeOf(Plain{}) 33 | for i := range st.NumField() { 34 | delete(raw, st.Field(i).Name) 35 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 36 | } 37 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 38 | return err 39 | } 40 | *j = ArrayAdditionalProperties(plain) 41 | return nil 42 | } 43 | 44 | // UnmarshalYAML implements yaml.Unmarshaler. 45 | func (j *ArrayAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { 46 | var raw map[string]interface{} 47 | if err := value.Decode(&raw); err != nil { 48 | return err 49 | } 50 | type Plain ArrayAdditionalProperties 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if v, ok := raw[""]; !ok || v == nil { 56 | plain.AdditionalProperties = map[string][]interface{}{} 57 | } 58 | st := reflect.TypeOf(Plain{}) 59 | for i := range st.NumField() { 60 | delete(raw, st.Field(i).Name) 61 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 62 | } 63 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 64 | return err 65 | } 66 | *j = ArrayAdditionalProperties(plain) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/arrayAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | } 8 | }, 9 | "additionalProperties": {"type": "array"} 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/boolAdditionalProperties.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "github.com/go-viper/mapstructure/v2" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "reflect" 9 | import "strings" 10 | 11 | type BoolAdditionalProperties struct { 12 | // Name corresponds to the JSON schema field "name". 13 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 14 | 15 | AdditionalProperties map[string]bool `mapstructure:",remain"` 16 | } 17 | 18 | // UnmarshalJSON implements json.Unmarshaler. 19 | func (j *BoolAdditionalProperties) UnmarshalJSON(value []byte) error { 20 | var raw map[string]interface{} 21 | if err := json.Unmarshal(value, &raw); err != nil { 22 | return err 23 | } 24 | type Plain BoolAdditionalProperties 25 | var plain Plain 26 | if err := json.Unmarshal(value, &plain); err != nil { 27 | return err 28 | } 29 | if v, ok := raw[""]; !ok || v == nil { 30 | plain.AdditionalProperties = map[string]bool{} 31 | } 32 | st := reflect.TypeOf(Plain{}) 33 | for i := range st.NumField() { 34 | delete(raw, st.Field(i).Name) 35 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 36 | } 37 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 38 | return err 39 | } 40 | *j = BoolAdditionalProperties(plain) 41 | return nil 42 | } 43 | 44 | // UnmarshalYAML implements yaml.Unmarshaler. 45 | func (j *BoolAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { 46 | var raw map[string]interface{} 47 | if err := value.Decode(&raw); err != nil { 48 | return err 49 | } 50 | type Plain BoolAdditionalProperties 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if v, ok := raw[""]; !ok || v == nil { 56 | plain.AdditionalProperties = map[string]bool{} 57 | } 58 | st := reflect.TypeOf(Plain{}) 59 | for i := range st.NumField() { 60 | delete(raw, st.Field(i).Name) 61 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 62 | } 63 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 64 | return err 65 | } 66 | *j = BoolAdditionalProperties(plain) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/boolAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | } 8 | }, 9 | "additionalProperties": {"type": "boolean"} 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/intAdditionalProperties.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "github.com/go-viper/mapstructure/v2" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "reflect" 9 | import "strings" 10 | 11 | type IntAdditionalProperties struct { 12 | // Name corresponds to the JSON schema field "name". 13 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 14 | 15 | AdditionalProperties map[string]int `mapstructure:",remain"` 16 | } 17 | 18 | // UnmarshalJSON implements json.Unmarshaler. 19 | func (j *IntAdditionalProperties) UnmarshalJSON(value []byte) error { 20 | var raw map[string]interface{} 21 | if err := json.Unmarshal(value, &raw); err != nil { 22 | return err 23 | } 24 | type Plain IntAdditionalProperties 25 | var plain Plain 26 | if err := json.Unmarshal(value, &plain); err != nil { 27 | return err 28 | } 29 | if v, ok := raw[""]; !ok || v == nil { 30 | plain.AdditionalProperties = map[string]int{} 31 | } 32 | st := reflect.TypeOf(Plain{}) 33 | for i := range st.NumField() { 34 | delete(raw, st.Field(i).Name) 35 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 36 | } 37 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 38 | return err 39 | } 40 | *j = IntAdditionalProperties(plain) 41 | return nil 42 | } 43 | 44 | // UnmarshalYAML implements yaml.Unmarshaler. 45 | func (j *IntAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { 46 | var raw map[string]interface{} 47 | if err := value.Decode(&raw); err != nil { 48 | return err 49 | } 50 | type Plain IntAdditionalProperties 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if v, ok := raw[""]; !ok || v == nil { 56 | plain.AdditionalProperties = map[string]int{} 57 | } 58 | st := reflect.TypeOf(Plain{}) 59 | for i := range st.NumField() { 60 | delete(raw, st.Field(i).Name) 61 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 62 | } 63 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 64 | return err 65 | } 66 | *j = IntAdditionalProperties(plain) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/intAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | } 8 | }, 9 | "additionalProperties": {"type": "integer"} 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/numberAdditionalProperties.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "github.com/go-viper/mapstructure/v2" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "reflect" 9 | import "strings" 10 | 11 | type NumberAdditionalProperties struct { 12 | // Name corresponds to the JSON schema field "name". 13 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 14 | 15 | AdditionalProperties map[string]float64 `mapstructure:",remain"` 16 | } 17 | 18 | // UnmarshalJSON implements json.Unmarshaler. 19 | func (j *NumberAdditionalProperties) UnmarshalJSON(value []byte) error { 20 | var raw map[string]interface{} 21 | if err := json.Unmarshal(value, &raw); err != nil { 22 | return err 23 | } 24 | type Plain NumberAdditionalProperties 25 | var plain Plain 26 | if err := json.Unmarshal(value, &plain); err != nil { 27 | return err 28 | } 29 | if v, ok := raw[""]; !ok || v == nil { 30 | plain.AdditionalProperties = map[string]float64{} 31 | } 32 | st := reflect.TypeOf(Plain{}) 33 | for i := range st.NumField() { 34 | delete(raw, st.Field(i).Name) 35 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 36 | } 37 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 38 | return err 39 | } 40 | *j = NumberAdditionalProperties(plain) 41 | return nil 42 | } 43 | 44 | // UnmarshalYAML implements yaml.Unmarshaler. 45 | func (j *NumberAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { 46 | var raw map[string]interface{} 47 | if err := value.Decode(&raw); err != nil { 48 | return err 49 | } 50 | type Plain NumberAdditionalProperties 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if v, ok := raw[""]; !ok || v == nil { 56 | plain.AdditionalProperties = map[string]float64{} 57 | } 58 | st := reflect.TypeOf(Plain{}) 59 | for i := range st.NumField() { 60 | delete(raw, st.Field(i).Name) 61 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 62 | } 63 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 64 | return err 65 | } 66 | *j = NumberAdditionalProperties(plain) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/numberAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | } 8 | }, 9 | "additionalProperties": {"type": "number"} 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/objectAdditionalProperties.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "github.com/go-viper/mapstructure/v2" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "reflect" 9 | import "strings" 10 | 11 | type ObjectAdditionalProperties struct { 12 | // Name corresponds to the JSON schema field "name". 13 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 14 | 15 | AdditionalProperties map[string]interface{} `mapstructure:",remain"` 16 | } 17 | 18 | // UnmarshalJSON implements json.Unmarshaler. 19 | func (j *ObjectAdditionalProperties) UnmarshalJSON(value []byte) error { 20 | var raw map[string]interface{} 21 | if err := json.Unmarshal(value, &raw); err != nil { 22 | return err 23 | } 24 | type Plain ObjectAdditionalProperties 25 | var plain Plain 26 | if err := json.Unmarshal(value, &plain); err != nil { 27 | return err 28 | } 29 | if v, ok := raw[""]; !ok || v == nil { 30 | plain.AdditionalProperties = map[string]interface{}{} 31 | } 32 | st := reflect.TypeOf(Plain{}) 33 | for i := range st.NumField() { 34 | delete(raw, st.Field(i).Name) 35 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 36 | } 37 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 38 | return err 39 | } 40 | *j = ObjectAdditionalProperties(plain) 41 | return nil 42 | } 43 | 44 | // UnmarshalYAML implements yaml.Unmarshaler. 45 | func (j *ObjectAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { 46 | var raw map[string]interface{} 47 | if err := value.Decode(&raw); err != nil { 48 | return err 49 | } 50 | type Plain ObjectAdditionalProperties 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if v, ok := raw[""]; !ok || v == nil { 56 | plain.AdditionalProperties = map[string]interface{}{} 57 | } 58 | st := reflect.TypeOf(Plain{}) 59 | for i := range st.NumField() { 60 | delete(raw, st.Field(i).Name) 61 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 62 | } 63 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 64 | return err 65 | } 66 | *j = ObjectAdditionalProperties(plain) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/objectAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | } 8 | }, 9 | "additionalProperties": {"type": "object"} 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/objectWithPropsAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/empty_object_properties", 4 | "type": "object", 5 | "additionalProperties": { 6 | "type": "object", 7 | "properties": { 8 | "property1": { 9 | "type": "string" 10 | }, 11 | "property2": { 12 | "type": "number" 13 | } 14 | } 15 | }, 16 | "properties": { 17 | "foo": { 18 | "type": "string" 19 | }, 20 | "bar": { 21 | "type": "string" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/stringAdditionalProperties.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "github.com/go-viper/mapstructure/v2" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "reflect" 9 | import "strings" 10 | 11 | type StringAdditionalProperties struct { 12 | // Name corresponds to the JSON schema field "name". 13 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 14 | 15 | AdditionalProperties map[string]string `mapstructure:",remain"` 16 | } 17 | 18 | // UnmarshalJSON implements json.Unmarshaler. 19 | func (j *StringAdditionalProperties) UnmarshalJSON(value []byte) error { 20 | var raw map[string]interface{} 21 | if err := json.Unmarshal(value, &raw); err != nil { 22 | return err 23 | } 24 | type Plain StringAdditionalProperties 25 | var plain Plain 26 | if err := json.Unmarshal(value, &plain); err != nil { 27 | return err 28 | } 29 | if v, ok := raw[""]; !ok || v == nil { 30 | plain.AdditionalProperties = map[string]string{} 31 | } 32 | st := reflect.TypeOf(Plain{}) 33 | for i := range st.NumField() { 34 | delete(raw, st.Field(i).Name) 35 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 36 | } 37 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 38 | return err 39 | } 40 | *j = StringAdditionalProperties(plain) 41 | return nil 42 | } 43 | 44 | // UnmarshalYAML implements yaml.Unmarshaler. 45 | func (j *StringAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { 46 | var raw map[string]interface{} 47 | if err := value.Decode(&raw); err != nil { 48 | return err 49 | } 50 | type Plain StringAdditionalProperties 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if v, ok := raw[""]; !ok || v == nil { 56 | plain.AdditionalProperties = map[string]string{} 57 | } 58 | st := reflect.TypeOf(Plain{}) 59 | for i := range st.NumField() { 60 | delete(raw, st.Field(i).Name) 61 | delete(raw, strings.Split(st.Field(i).Tag.Get("json"), ",")[0]) 62 | } 63 | if err := mapstructure.Decode(raw, &plain.AdditionalProperties); err != nil { 64 | return err 65 | } 66 | *j = StringAdditionalProperties(plain) 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /tests/data/core/additionalProperties/stringAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | } 8 | }, 9 | "additionalProperties": {"type": "string"} 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/core/allOf/allOf.1.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type AllOf1 struct { 10 | // Configurations corresponds to the JSON schema field "configurations". 11 | Configurations []AllOf1ConfigurationsElem `json:"configurations,omitempty" yaml:"configurations,omitempty" mapstructure:"configurations,omitempty"` 12 | } 13 | 14 | type AllOf1ConfigurationsElem struct { 15 | // Bar corresponds to the JSON schema field "bar". 16 | Bar float64 `json:"bar" yaml:"bar" mapstructure:"bar"` 17 | 18 | // Foo corresponds to the JSON schema field "foo". 19 | Foo string `json:"foo" yaml:"foo" mapstructure:"foo"` 20 | } 21 | 22 | // UnmarshalJSON implements json.Unmarshaler. 23 | func (j *AllOf1ConfigurationsElem) UnmarshalJSON(value []byte) error { 24 | var raw map[string]interface{} 25 | if err := json.Unmarshal(value, &raw); err != nil { 26 | return err 27 | } 28 | if _, ok := raw["bar"]; raw != nil && !ok { 29 | return fmt.Errorf("field bar in AllOf1ConfigurationsElem: required") 30 | } 31 | if _, ok := raw["foo"]; raw != nil && !ok { 32 | return fmt.Errorf("field foo in AllOf1ConfigurationsElem: required") 33 | } 34 | type Plain AllOf1ConfigurationsElem 35 | var plain Plain 36 | if err := json.Unmarshal(value, &plain); err != nil { 37 | return err 38 | } 39 | *j = AllOf1ConfigurationsElem(plain) 40 | return nil 41 | } 42 | 43 | // UnmarshalYAML implements yaml.Unmarshaler. 44 | func (j *AllOf1ConfigurationsElem) UnmarshalYAML(value *yaml.Node) error { 45 | var raw map[string]interface{} 46 | if err := value.Decode(&raw); err != nil { 47 | return err 48 | } 49 | if _, ok := raw["bar"]; raw != nil && !ok { 50 | return fmt.Errorf("field bar in AllOf1ConfigurationsElem: required") 51 | } 52 | if _, ok := raw["foo"]; raw != nil && !ok { 53 | return fmt.Errorf("field foo in AllOf1ConfigurationsElem: required") 54 | } 55 | type Plain AllOf1ConfigurationsElem 56 | var plain Plain 57 | if err := value.Decode(&plain); err != nil { 58 | return err 59 | } 60 | *j = AllOf1ConfigurationsElem(plain) 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /tests/data/core/allOf/allOf.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/objectAllOf", 4 | "type": "object", 5 | "properties": { 6 | "configurations": { 7 | "type": "array", 8 | "items": { 9 | "allOf": [ 10 | { 11 | "type": "object", 12 | "properties": { 13 | "foo": { 14 | "type": "string" 15 | } 16 | }, 17 | "required": [ 18 | "foo" 19 | ] 20 | }, 21 | { 22 | "type": "object", 23 | "properties": { 24 | "bar": { 25 | "type": "number" 26 | } 27 | }, 28 | "required": [ 29 | "bar" 30 | ] 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/data/core/allOf/allOf.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$defs": { 4 | "foo": { 5 | "type": "object", 6 | "properties": { 7 | "foo": { 8 | "type": "string" 9 | } 10 | }, 11 | "required": [ 12 | "foo" 13 | ] 14 | }, 15 | "bar": { 16 | "type": "object", 17 | "properties": { 18 | "bar": { 19 | "type": "number" 20 | } 21 | }, 22 | "required": [ 23 | "bar" 24 | ] 25 | }, 26 | "baz": { 27 | "type": "object", 28 | "properties": { 29 | "baz": { 30 | "type": "boolean" 31 | } 32 | } 33 | } 34 | }, 35 | "id": "https://example.com/objectAllOf", 36 | "type": "object", 37 | "properties": { 38 | "configurations": { 39 | "type": "array", 40 | "items": { 41 | "allOf": [ 42 | { 43 | "$ref": "#/$defs/foo" 44 | }, 45 | { 46 | "$ref": "#/$defs/bar" 47 | }, 48 | { 49 | "$ref": "#/$defs/baz" 50 | } 51 | ] 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/data/core/allOf/allOf.3.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type AllOf3 struct { 10 | // Bar corresponds to the JSON schema field "bar". 11 | Bar float64 `json:"bar" yaml:"bar" mapstructure:"bar"` 12 | 13 | // Configurations corresponds to the JSON schema field "configurations". 14 | Configurations []interface{} `json:"configurations,omitempty" yaml:"configurations,omitempty" mapstructure:"configurations,omitempty"` 15 | 16 | // Foo corresponds to the JSON schema field "foo". 17 | Foo string `json:"foo" yaml:"foo" mapstructure:"foo"` 18 | } 19 | 20 | // UnmarshalJSON implements json.Unmarshaler. 21 | func (j *AllOf3) UnmarshalJSON(value []byte) error { 22 | var raw map[string]interface{} 23 | if err := json.Unmarshal(value, &raw); err != nil { 24 | return err 25 | } 26 | if _, ok := raw["bar"]; raw != nil && !ok { 27 | return fmt.Errorf("field bar in AllOf3: required") 28 | } 29 | if _, ok := raw["foo"]; raw != nil && !ok { 30 | return fmt.Errorf("field foo in AllOf3: required") 31 | } 32 | type Plain AllOf3 33 | var plain Plain 34 | if err := json.Unmarshal(value, &plain); err != nil { 35 | return err 36 | } 37 | *j = AllOf3(plain) 38 | return nil 39 | } 40 | 41 | // UnmarshalYAML implements yaml.Unmarshaler. 42 | func (j *AllOf3) UnmarshalYAML(value *yaml.Node) error { 43 | var raw map[string]interface{} 44 | if err := value.Decode(&raw); err != nil { 45 | return err 46 | } 47 | if _, ok := raw["bar"]; raw != nil && !ok { 48 | return fmt.Errorf("field bar in AllOf3: required") 49 | } 50 | if _, ok := raw["foo"]; raw != nil && !ok { 51 | return fmt.Errorf("field foo in AllOf3: required") 52 | } 53 | type Plain AllOf3 54 | var plain Plain 55 | if err := value.Decode(&plain); err != nil { 56 | return err 57 | } 58 | *j = AllOf3(plain) 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /tests/data/core/allOf/allOf.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/objectAllOf", 4 | "type": "object", 5 | "allOf": [ 6 | { 7 | "type": "object", 8 | "properties": { 9 | "foo": { 10 | "type": "string" 11 | } 12 | }, 13 | "required": ["foo"] 14 | }, 15 | { 16 | "type": "object", 17 | "properties": { 18 | "bar": { 19 | "type": "number" 20 | } 21 | }, 22 | "required": ["bar"] 23 | }, 24 | { 25 | "type": "object", 26 | "properties": { 27 | "configurations": { 28 | "type": "array", 29 | "items": {} 30 | } 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /tests/data/core/allOf/allOf.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinksarray", 4 | "type": "array", 5 | "items": { 6 | "allOf": [ 7 | { 8 | "type": "object", 9 | "$ref": "embeddedlinkend" 10 | }, 11 | { 12 | "type": "object", 13 | "$ref": "embeddedlinkpath" 14 | }, 15 | { 16 | "type": "object", 17 | "$ref": "embeddedlinkrelation" 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/data/core/allOf/allOf.ref.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "definitions": { 4 | "TextContent": { 5 | "description": "Text provided to or from an LLM.", 6 | "properties": { 7 | "text": { 8 | "description": "The text content of the message.", 9 | "type": "string" 10 | } 11 | }, 12 | "required": [ 13 | "text" 14 | ], 15 | "type": "object" 16 | }, 17 | "CallToolResult": { 18 | "description": "The server's response to a tool call", 19 | "properties": { 20 | "content": { 21 | "items": { 22 | "allOf": [ 23 | { 24 | "$ref": "#/definitions/TextContent" 25 | } 26 | ] 27 | }, 28 | "type": "array" 29 | } 30 | }, 31 | "type": "object" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/data/core/allOf/embeddedlinkend: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinkend", 4 | "properties": { 5 | "linkType": { 6 | "type": "string", 7 | "enum": [ 8 | "END" 9 | ] 10 | }, 11 | "from": { 12 | "description": "When consuming a CDEvent, you are consuming a parent event. So, when looking at the 'from' key, this is the parent's parent.", 13 | "type": "object", 14 | "properties": { 15 | "contextId": { 16 | "type": "string", 17 | "minLength": 1 18 | } 19 | }, 20 | "required": [ 21 | "contextId" 22 | ] 23 | }, 24 | "tags": { 25 | "type": "object", 26 | "additionalProperties": true 27 | } 28 | }, 29 | "additionalProperties": false, 30 | "type": "object", 31 | "required": [ 32 | "linkType" 33 | ] 34 | } 35 | 36 | -------------------------------------------------------------------------------- /tests/data/core/allOf/embeddedlinkpath: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinkpath", 4 | "properties": { 5 | "linkType": { 6 | "type": "string", 7 | "enum": [ 8 | "PATH" 9 | ] 10 | }, 11 | "from": { 12 | "description": "When consuming a CDEvent, you are consuming a parent event. So, when looking at the 'from' key, this is the parent's parent.", 13 | "type": "object", 14 | "properties": { 15 | "contextId": { 16 | "type": "string", 17 | "minLength": 1 18 | } 19 | }, 20 | "required": [ 21 | "contextId" 22 | ] 23 | }, 24 | "tags": { 25 | "type": "object", 26 | "additionalProperties": true 27 | } 28 | }, 29 | "additionalProperties": false, 30 | "type": "object", 31 | "required": [ 32 | "linkType", 33 | "from" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/data/core/allOf/embeddedlinkrelation: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinkrelation", 4 | "properties": { 5 | "linkType": { 6 | "type": "string", 7 | "enum": [ 8 | "RELATION" 9 | ] 10 | }, 11 | "linkKind": { 12 | "type": "string", 13 | "minLength": 1 14 | }, 15 | "target": { 16 | "description": "", 17 | "type": "object", 18 | "properties": { 19 | "contextId": { 20 | "type": "string", 21 | "minLength": 1 22 | } 23 | } 24 | }, 25 | "tags": { 26 | "type": "object", 27 | "additionalProperties": true 28 | } 29 | }, 30 | "additionalProperties": false, 31 | "type": "object", 32 | "required": [ 33 | "linkType", 34 | "linkKind", 35 | "target" 36 | ] 37 | } 38 | 39 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/anyOf.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/objectAllOf", 4 | "description": "object with anyOf properties", 5 | "type": "object", 6 | "properties": { 7 | "flags": { 8 | "anyOf": [ 9 | { 10 | "type": "string" 11 | }, 12 | { 13 | "type": "boolean" 14 | } 15 | ] 16 | }, 17 | "configurations": { 18 | "type": "array", 19 | "items": { 20 | "anyOf": [ 21 | { 22 | "type": "object", 23 | "properties": { 24 | "foo": { 25 | "type": "string" 26 | } 27 | }, 28 | "required": [ 29 | "foo" 30 | ] 31 | }, 32 | { 33 | "type": "object", 34 | "properties": { 35 | "bar": { 36 | "type": "number" 37 | } 38 | }, 39 | "required": [ 40 | "bar" 41 | ] 42 | }, 43 | { 44 | "type": "object", 45 | "properties": { 46 | "baz": { 47 | "type": "boolean" 48 | } 49 | } 50 | } 51 | ] 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/anyOf.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/objectAllOf", 4 | "description": "object with anyOf properties, some with $defs", 5 | "type": "object", 6 | "$defs": { 7 | "foo": { 8 | "type": "object", 9 | "properties": { 10 | "foo": { 11 | "type": "string" 12 | } 13 | }, 14 | "required": [ 15 | "foo" 16 | ] 17 | } 18 | }, 19 | "properties": { 20 | "configurations": { 21 | "type": "array", 22 | "items": { 23 | "anyOf": [ 24 | { 25 | "$ref": "#/$defs/foo" 26 | }, 27 | { 28 | "type": "object", 29 | "properties": { 30 | "bar": { 31 | "type": "number" 32 | } 33 | }, 34 | "required": [ 35 | "bar" 36 | ] 37 | }, 38 | { 39 | "type": "object", 40 | "properties": { 41 | "baz": { 42 | "type": "boolean" 43 | } 44 | } 45 | } 46 | ] 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/anyOf.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/objectAnyOf", 4 | "description": "object with anyOf properties as root", 5 | "type": "object", 6 | "anyOf": [ 7 | { 8 | "type": "object", 9 | "properties": { 10 | "foo": { 11 | "type": "string" 12 | } 13 | }, 14 | "required": ["foo"] 15 | }, 16 | { 17 | "type": "object", 18 | "properties": { 19 | "bar": { 20 | "type": "number" 21 | } 22 | }, 23 | "required": ["bar"] 24 | }, 25 | { 26 | "type": "object", 27 | "properties": { 28 | "configurations": { 29 | "type": "array", 30 | "items": {} 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/anyOf.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinksarray", 4 | "type": "array", 5 | "items": { 6 | "anyOf": [ 7 | { 8 | "type": "object", 9 | "$ref": "embeddedlinkend" 10 | }, 11 | { 12 | "type": "object", 13 | "$ref": "embeddedlinkpath" 14 | }, 15 | { 16 | "type": "object", 17 | "$ref": "embeddedlinkrelation" 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/anyOf.5.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "definitions": { 4 | "TextContent": { 5 | "description": "Text provided to or from an LLM.", 6 | "properties": { 7 | "text": { 8 | "description": "The text content of the message.", 9 | "type": "string" 10 | } 11 | }, 12 | "required": [ 13 | "text" 14 | ], 15 | "type": "object" 16 | }, 17 | "CallToolResult": { 18 | "description": "The server's response to a tool call", 19 | "properties": { 20 | "content": { 21 | "items": { 22 | "anyOf": [ 23 | { 24 | "$ref": "#/definitions/TextContent" 25 | } 26 | ] 27 | }, 28 | "type": "array" 29 | } 30 | }, 31 | "type": "object" 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/embeddedlinkend: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinkend", 4 | "properties": { 5 | "linkType": { 6 | "type": "string", 7 | "enum": [ 8 | "END" 9 | ] 10 | }, 11 | "from": { 12 | "description": "When consuming a CDEvent, you are consuming a parent event. So, when looking at the 'from' key, this is the parent's parent.", 13 | "type": "object", 14 | "properties": { 15 | "contextId": { 16 | "type": "string", 17 | "minLength": 1 18 | } 19 | }, 20 | "required": [ 21 | "contextId" 22 | ] 23 | }, 24 | "tags": { 25 | "type": "object", 26 | "additionalProperties": true 27 | } 28 | }, 29 | "additionalProperties": false, 30 | "type": "object", 31 | "required": [ 32 | "linkType" 33 | ] 34 | } 35 | 36 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/embeddedlinkpath: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinkpath", 4 | "properties": { 5 | "linkType": { 6 | "type": "string", 7 | "enum": [ 8 | "PATH" 9 | ] 10 | }, 11 | "from": { 12 | "description": "When consuming a CDEvent, you are consuming a parent event. So, when looking at the 'from' key, this is the parent's parent.", 13 | "type": "object", 14 | "properties": { 15 | "contextId": { 16 | "type": "string", 17 | "minLength": 1 18 | } 19 | }, 20 | "required": [ 21 | "contextId" 22 | ] 23 | }, 24 | "tags": { 25 | "type": "object", 26 | "additionalProperties": true 27 | } 28 | }, 29 | "additionalProperties": false, 30 | "type": "object", 31 | "required": [ 32 | "linkType", 33 | "from" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/data/core/anyOf/embeddedlinkrelation: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://cdevents.dev/0.5.0-draft/schema/links/embeddedlinkrelation", 4 | "properties": { 5 | "linkType": { 6 | "type": "string", 7 | "enum": [ 8 | "RELATION" 9 | ] 10 | }, 11 | "linkKind": { 12 | "type": "string", 13 | "minLength": 1 14 | }, 15 | "target": { 16 | "description": "", 17 | "type": "object", 18 | "properties": { 19 | "contextId": { 20 | "type": "string", 21 | "minLength": 1 22 | } 23 | } 24 | }, 25 | "tags": { 26 | "type": "object", 27 | "additionalProperties": true 28 | } 29 | }, 30 | "additionalProperties": false, 31 | "type": "object", 32 | "required": [ 33 | "linkType", 34 | "linkKind", 35 | "target" 36 | ] 37 | } 38 | 39 | -------------------------------------------------------------------------------- /tests/data/core/array/array.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myStringArray": { 7 | "type": "array", 8 | "items": { 9 | "type": "string" 10 | } 11 | }, 12 | "myNumberArray": { 13 | "type": "array", 14 | "items": { 15 | "type": "number" 16 | } 17 | }, 18 | "myIntegerArray": { 19 | "type": "array", 20 | "items": { 21 | "type": "integer" 22 | } 23 | }, 24 | "myBooleanArray": { 25 | "type": "array", 26 | "items": { 27 | "type": "boolean" 28 | } 29 | }, 30 | "myNullArray": { 31 | "type": "array", 32 | "items": { 33 | "type": "null" 34 | } 35 | }, 36 | "myObjectArray": { 37 | "type": "array", 38 | "items": { 39 | "type": "object" 40 | } 41 | }, 42 | "myArray": { 43 | "type": "array" 44 | }, 45 | "myNestedNullArray": { 46 | "type": "array", 47 | "items": { 48 | "type": "array", 49 | "items": { 50 | "type": "null" 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/data/core/date/date.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import "github.com/atombender/go-jsonschema/pkg/types" 8 | import yaml "gopkg.in/yaml.v3" 9 | 10 | type Date struct { 11 | // MyObject corresponds to the JSON schema field "myObject". 12 | MyObject *DateMyObject `json:"myObject,omitempty" yaml:"myObject,omitempty" mapstructure:"myObject,omitempty"` 13 | } 14 | 15 | type DateMyObject struct { 16 | // MyDate corresponds to the JSON schema field "myDate". 17 | MyDate types.SerializableDate `json:"myDate" yaml:"myDate" mapstructure:"myDate"` 18 | } 19 | 20 | // UnmarshalJSON implements json.Unmarshaler. 21 | func (j *DateMyObject) UnmarshalJSON(value []byte) error { 22 | var raw map[string]interface{} 23 | if err := json.Unmarshal(value, &raw); err != nil { 24 | return err 25 | } 26 | if _, ok := raw["myDate"]; raw != nil && !ok { 27 | return fmt.Errorf("field myDate in DateMyObject: required") 28 | } 29 | type Plain DateMyObject 30 | var plain Plain 31 | if err := json.Unmarshal(value, &plain); err != nil { 32 | return err 33 | } 34 | *j = DateMyObject(plain) 35 | return nil 36 | } 37 | 38 | // UnmarshalYAML implements yaml.Unmarshaler. 39 | func (j *DateMyObject) UnmarshalYAML(value *yaml.Node) error { 40 | var raw map[string]interface{} 41 | if err := value.Decode(&raw); err != nil { 42 | return err 43 | } 44 | if _, ok := raw["myDate"]; raw != nil && !ok { 45 | return fmt.Errorf("field myDate in DateMyObject: required") 46 | } 47 | type Plain DateMyObject 48 | var plain Plain 49 | if err := value.Decode(&plain); err != nil { 50 | return err 51 | } 52 | *j = DateMyObject(plain) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /tests/data/core/date/date.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "http://example.com/object", 4 | "type": "object", 5 | "title": "object", 6 | "properties": { 7 | "myObject": { 8 | "type": "object", 9 | "required": [ 10 | "myDate" 11 | ], 12 | "properties": { 13 | "myDate": { 14 | "type": "string", 15 | "format": "date" 16 | } 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/data/core/dateTime/dateTime.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "time" 9 | 10 | type DateTime struct { 11 | // MyObject corresponds to the JSON schema field "myObject". 12 | MyObject *DateTimeMyObject `json:"myObject,omitempty" yaml:"myObject,omitempty" mapstructure:"myObject,omitempty"` 13 | } 14 | 15 | type DateTimeMyObject struct { 16 | // MyDateTime corresponds to the JSON schema field "myDateTime". 17 | MyDateTime time.Time `json:"myDateTime" yaml:"myDateTime" mapstructure:"myDateTime"` 18 | } 19 | 20 | // UnmarshalJSON implements json.Unmarshaler. 21 | func (j *DateTimeMyObject) UnmarshalJSON(value []byte) error { 22 | var raw map[string]interface{} 23 | if err := json.Unmarshal(value, &raw); err != nil { 24 | return err 25 | } 26 | if _, ok := raw["myDateTime"]; raw != nil && !ok { 27 | return fmt.Errorf("field myDateTime in DateTimeMyObject: required") 28 | } 29 | type Plain DateTimeMyObject 30 | var plain Plain 31 | if err := json.Unmarshal(value, &plain); err != nil { 32 | return err 33 | } 34 | *j = DateTimeMyObject(plain) 35 | return nil 36 | } 37 | 38 | // UnmarshalYAML implements yaml.Unmarshaler. 39 | func (j *DateTimeMyObject) UnmarshalYAML(value *yaml.Node) error { 40 | var raw map[string]interface{} 41 | if err := value.Decode(&raw); err != nil { 42 | return err 43 | } 44 | if _, ok := raw["myDateTime"]; raw != nil && !ok { 45 | return fmt.Errorf("field myDateTime in DateTimeMyObject: required") 46 | } 47 | type Plain DateTimeMyObject 48 | var plain Plain 49 | if err := value.Decode(&plain); err != nil { 50 | return err 51 | } 52 | *j = DateTimeMyObject(plain) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /tests/data/core/dateTime/dateTime.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "http://example.com/object", 4 | "type": "object", 5 | "title": "object", 6 | "properties": { 7 | "myObject": { 8 | "type": "object", 9 | "required": [ 10 | "myDateTime" 11 | ], 12 | "properties": { 13 | "myDateTime": { 14 | "type": "string", 15 | "format": "date-time" 16 | } 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/data/core/duration/duration.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "http://example.com/object", 4 | "type": "object", 5 | "title": "object", 6 | "properties": { 7 | "myObject": { 8 | "type": "object", 9 | "properties": { 10 | "withDefault": { 11 | "type": "string", 12 | "format": "duration", 13 | "default": "PT20S" 14 | }, 15 | "withoutDefault": { 16 | "type": "string", 17 | "format": "duration" 18 | } 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/core/ip/ip.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "net/netip" 9 | 10 | type Ip struct { 11 | // MyObject corresponds to the JSON schema field "myObject". 12 | MyObject *IpMyObject `json:"myObject,omitempty" yaml:"myObject,omitempty" mapstructure:"myObject,omitempty"` 13 | } 14 | 15 | type IpMyObject struct { 16 | // MyIp corresponds to the JSON schema field "myIp". 17 | MyIp netip.Addr `json:"myIp" yaml:"myIp" mapstructure:"myIp"` 18 | } 19 | 20 | // UnmarshalJSON implements json.Unmarshaler. 21 | func (j *IpMyObject) UnmarshalJSON(value []byte) error { 22 | var raw map[string]interface{} 23 | if err := json.Unmarshal(value, &raw); err != nil { 24 | return err 25 | } 26 | if _, ok := raw["myIp"]; raw != nil && !ok { 27 | return fmt.Errorf("field myIp in IpMyObject: required") 28 | } 29 | type Plain IpMyObject 30 | var plain Plain 31 | if err := json.Unmarshal(value, &plain); err != nil { 32 | return err 33 | } 34 | *j = IpMyObject(plain) 35 | return nil 36 | } 37 | 38 | // UnmarshalYAML implements yaml.Unmarshaler. 39 | func (j *IpMyObject) UnmarshalYAML(value *yaml.Node) error { 40 | var raw map[string]interface{} 41 | if err := value.Decode(&raw); err != nil { 42 | return err 43 | } 44 | if _, ok := raw["myIp"]; raw != nil && !ok { 45 | return fmt.Errorf("field myIp in IpMyObject: required") 46 | } 47 | type Plain IpMyObject 48 | var plain Plain 49 | if err := value.Decode(&plain); err != nil { 50 | return err 51 | } 52 | *j = IpMyObject(plain) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /tests/data/core/ip/ip.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/object", 4 | "type": "object", 5 | "title": "object", 6 | "properties": { 7 | "myObject": { 8 | "type": "object", 9 | "required": [ 10 | "myIp" 11 | ], 12 | "properties": { 13 | "myIp": { 14 | "type": "string", 15 | "format": "ipv4" 16 | } 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/data/core/nativeMap/map.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Map struct { 6 | // MyMap corresponds to the JSON schema field "myMap". 7 | MyMap MapMyMap `json:"myMap,omitempty" yaml:"myMap,omitempty" mapstructure:"myMap,omitempty"` 8 | } 9 | 10 | type MapMyMap map[string]float64 11 | -------------------------------------------------------------------------------- /tests/data/core/nativeMap/map.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "http://example.com/object", 4 | "type": "object", 5 | "properties": { 6 | "myMap": { 7 | "type": "object", 8 | "additionalProperties": { 9 | "type": "number" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /tests/data/core/nullableType/nullableType.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type BoolThing *bool 6 | 7 | type FloatThing *float64 8 | 9 | type IntegerThing *int 10 | 11 | type NullableType struct { 12 | // MyInlineStringValue corresponds to the JSON schema field "MyInlineStringValue". 13 | MyInlineStringValue *string `json:"MyInlineStringValue,omitempty" yaml:"MyInlineStringValue,omitempty" mapstructure:"MyInlineStringValue,omitempty"` 14 | 15 | // MyStringValue corresponds to the JSON schema field "MyStringValue". 16 | MyStringValue StringThing `json:"MyStringValue,omitempty" yaml:"MyStringValue,omitempty" mapstructure:"MyStringValue,omitempty"` 17 | } 18 | 19 | type StringThing *string 20 | -------------------------------------------------------------------------------- /tests/data/core/nullableType/nullableType.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/nullableType", 4 | "type": "object", 5 | "$defs": { 6 | "StringThing": { 7 | "type": [ 8 | "null", 9 | "string" 10 | ] 11 | }, 12 | "FloatThing": { 13 | "type": [ 14 | "number", 15 | "null" 16 | ] 17 | }, 18 | "IntegerThing": { 19 | "type": [ 20 | "integer", 21 | "null" 22 | ] 23 | }, 24 | "BoolThing": { 25 | "type": [ 26 | "boolean", 27 | "null" 28 | ] 29 | } 30 | }, 31 | "properties": { 32 | "MyStringValue": { 33 | "$ref": "#/$defs/StringThing" 34 | }, 35 | "MyInlineStringValue": { 36 | "type": [ 37 | "null", 38 | "string" 39 | ] 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/data/core/object/object.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type Object struct { 10 | // MyObject corresponds to the JSON schema field "myObject". 11 | MyObject *ObjectMyObject `json:"myObject,omitempty" yaml:"myObject,omitempty" mapstructure:"myObject,omitempty"` 12 | } 13 | 14 | type ObjectMyObject struct { 15 | // MyString corresponds to the JSON schema field "myString". 16 | MyString string `json:"myString" yaml:"myString" mapstructure:"myString"` 17 | } 18 | 19 | // UnmarshalJSON implements json.Unmarshaler. 20 | func (j *ObjectMyObject) UnmarshalJSON(value []byte) error { 21 | var raw map[string]interface{} 22 | if err := json.Unmarshal(value, &raw); err != nil { 23 | return err 24 | } 25 | if _, ok := raw["myString"]; raw != nil && !ok { 26 | return fmt.Errorf("field myString in ObjectMyObject: required") 27 | } 28 | type Plain ObjectMyObject 29 | var plain Plain 30 | if err := json.Unmarshal(value, &plain); err != nil { 31 | return err 32 | } 33 | *j = ObjectMyObject(plain) 34 | return nil 35 | } 36 | 37 | // UnmarshalYAML implements yaml.Unmarshaler. 38 | func (j *ObjectMyObject) UnmarshalYAML(value *yaml.Node) error { 39 | var raw map[string]interface{} 40 | if err := value.Decode(&raw); err != nil { 41 | return err 42 | } 43 | if _, ok := raw["myString"]; raw != nil && !ok { 44 | return fmt.Errorf("field myString in ObjectMyObject: required") 45 | } 46 | type Plain ObjectMyObject 47 | var plain Plain 48 | if err := value.Decode(&plain); err != nil { 49 | return err 50 | } 51 | *j = ObjectMyObject(plain) 52 | return nil 53 | } 54 | -------------------------------------------------------------------------------- /tests/data/core/object/object.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/object", 4 | "type": "object", 5 | "properties": { 6 | "myObject": { 7 | "type": "object", 8 | "required": [ 9 | "myString" 10 | ], 11 | "properties": { 12 | "myString": { 13 | "type": "string" 14 | } 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/data/core/objectAdditionalProperties/objectAdditionalProperties.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import yaml "gopkg.in/yaml.v3" 7 | 8 | type ObjectAdditionalProperties struct { 9 | // Foo corresponds to the JSON schema field "foo". 10 | Foo ObjectAdditionalPropertiesFoo `json:"foo,omitempty" yaml:"foo,omitempty" mapstructure:"foo,omitempty"` 11 | } 12 | 13 | type ObjectAdditionalPropertiesFoo map[string]string 14 | 15 | // UnmarshalJSON implements json.Unmarshaler. 16 | func (j *ObjectAdditionalProperties) UnmarshalJSON(value []byte) error { 17 | var raw map[string]interface{} 18 | if err := json.Unmarshal(value, &raw); err != nil { 19 | return err 20 | } 21 | type Plain ObjectAdditionalProperties 22 | var plain Plain 23 | if err := json.Unmarshal(value, &plain); err != nil { 24 | return err 25 | } 26 | if v, ok := raw["foo"]; !ok || v == nil { 27 | plain.Foo = map[string]string{} 28 | } 29 | *j = ObjectAdditionalProperties(plain) 30 | return nil 31 | } 32 | 33 | // UnmarshalYAML implements yaml.Unmarshaler. 34 | func (j *ObjectAdditionalProperties) UnmarshalYAML(value *yaml.Node) error { 35 | var raw map[string]interface{} 36 | if err := value.Decode(&raw); err != nil { 37 | return err 38 | } 39 | type Plain ObjectAdditionalProperties 40 | var plain Plain 41 | if err := value.Decode(&plain); err != nil { 42 | return err 43 | } 44 | if v, ok := raw["foo"]; !ok || v == nil { 45 | plain.Foo = map[string]string{} 46 | } 47 | *j = ObjectAdditionalProperties(plain) 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /tests/data/core/objectAdditionalProperties/objectAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "foo": { 6 | "type": "object", 7 | "additionalProperties": { 8 | "type": "string" 9 | }, 10 | "default": {} 11 | } 12 | }, 13 | "additionalProperties": false 14 | } 15 | -------------------------------------------------------------------------------- /tests/data/core/objectEmpty/objectEmpty.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type ObjectEmpty struct { 6 | // Foo corresponds to the JSON schema field "foo". 7 | Foo ObjectEmptyFoo `json:"foo,omitempty" yaml:"foo,omitempty" mapstructure:"foo,omitempty"` 8 | } 9 | 10 | type ObjectEmptyFoo map[string]interface{} 11 | -------------------------------------------------------------------------------- /tests/data/core/objectEmpty/objectEmpty.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/empty_object_properties", 4 | "type": "object", 5 | "properties": { 6 | "foo": { 7 | "type": "object" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/core/objectNested/objectNested.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type ObjectNested struct { 6 | // MyObject corresponds to the JSON schema field "myObject". 7 | MyObject *ObjectNestedMyObject `json:"myObject,omitempty" yaml:"myObject,omitempty" mapstructure:"myObject,omitempty"` 8 | } 9 | 10 | type ObjectNestedMyObject struct { 11 | // MyObject corresponds to the JSON schema field "myObject". 12 | MyObject *ObjectNestedMyObjectMyObject `json:"myObject,omitempty" yaml:"myObject,omitempty" mapstructure:"myObject,omitempty"` 13 | } 14 | 15 | type ObjectNestedMyObjectMyObject struct { 16 | // MyString corresponds to the JSON schema field "myString". 17 | MyString *string `json:"myString,omitempty" yaml:"myString,omitempty" mapstructure:"myString,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /tests/data/core/objectNested/objectNested.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/objectNested", 4 | "type": "object", 5 | "properties": { 6 | "myObject": { 7 | "type": "object", 8 | "properties": { 9 | "myObject": { 10 | "type": "object", 11 | "properties": { 12 | "myString": { 13 | "type": "string" 14 | } 15 | } 16 | } 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/data/core/primitives/primitives.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type Primitives struct { 10 | // MyBoolean corresponds to the JSON schema field "myBoolean". 11 | MyBoolean *bool `json:"myBoolean,omitempty" yaml:"myBoolean,omitempty" mapstructure:"myBoolean,omitempty"` 12 | 13 | // MyInteger corresponds to the JSON schema field "myInteger". 14 | MyInteger *int `json:"myInteger,omitempty" yaml:"myInteger,omitempty" mapstructure:"myInteger,omitempty"` 15 | 16 | // MyNull corresponds to the JSON schema field "myNull". 17 | MyNull interface{} `json:"myNull,omitempty" yaml:"myNull,omitempty" mapstructure:"myNull,omitempty"` 18 | 19 | // MyNumber corresponds to the JSON schema field "myNumber". 20 | MyNumber *float64 `json:"myNumber,omitempty" yaml:"myNumber,omitempty" mapstructure:"myNumber,omitempty"` 21 | 22 | // MyString corresponds to the JSON schema field "myString". 23 | MyString *string `json:"myString,omitempty" yaml:"myString,omitempty" mapstructure:"myString,omitempty"` 24 | } 25 | 26 | // UnmarshalJSON implements json.Unmarshaler. 27 | func (j *Primitives) UnmarshalJSON(value []byte) error { 28 | var raw map[string]interface{} 29 | if err := json.Unmarshal(value, &raw); err != nil { 30 | return err 31 | } 32 | type Plain Primitives 33 | var plain Plain 34 | if err := json.Unmarshal(value, &plain); err != nil { 35 | return err 36 | } 37 | if plain.MyNull != nil { 38 | return fmt.Errorf("field %s: must be null", "myNull") 39 | } 40 | *j = Primitives(plain) 41 | return nil 42 | } 43 | 44 | // UnmarshalYAML implements yaml.Unmarshaler. 45 | func (j *Primitives) UnmarshalYAML(value *yaml.Node) error { 46 | var raw map[string]interface{} 47 | if err := value.Decode(&raw); err != nil { 48 | return err 49 | } 50 | type Plain Primitives 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if plain.MyNull != nil { 56 | return fmt.Errorf("field %s: must be null", "myNull") 57 | } 58 | *j = Primitives(plain) 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /tests/data/core/primitives/primitives.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/primitives", 4 | "type": "object", 5 | "properties": { 6 | "myString": { 7 | "type": "string" 8 | }, 9 | "myNumber": { 10 | "type": "number" 11 | }, 12 | "myInteger": { 13 | "type": "integer" 14 | }, 15 | "myBoolean": { 16 | "type": "boolean" 17 | }, 18 | "myNull": { 19 | "type": "null" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/core/ref/ref.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Ref struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | 9 | // MyThing2 corresponds to the JSON schema field "myThing2". 10 | MyThing2 *Thing `json:"myThing2,omitempty" yaml:"myThing2,omitempty" mapstructure:"myThing2,omitempty"` 11 | } 12 | 13 | type Thing struct { 14 | // Name corresponds to the JSON schema field "name". 15 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /tests/data/core/ref/ref.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/ref", 4 | "type": "object", 5 | "properties": { 6 | "myThing": { 7 | "$ref": "#/$defs/Thing" 8 | }, 9 | "myThing2": { 10 | "$ref": "#/$defs/Thing" 11 | } 12 | }, 13 | "$defs": { 14 | "Thing": { 15 | "type": "object", 16 | "properties": { 17 | "name": { 18 | "type": "string" 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFile/refExternalFile.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Ref struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | 9 | // MyThing2 corresponds to the JSON schema field "myThing2". 10 | MyThing2 *Thing `json:"myThing2,omitempty" yaml:"myThing2,omitempty" mapstructure:"myThing2,omitempty"` 11 | } 12 | 13 | type RefExternalFile struct { 14 | // MyExternalThing corresponds to the JSON schema field "myExternalThing". 15 | MyExternalThing *Thing `json:"myExternalThing,omitempty" yaml:"myExternalThing,omitempty" mapstructure:"myExternalThing,omitempty"` 16 | 17 | // SomeOtherExternalThing corresponds to the JSON schema field 18 | // "someOtherExternalThing". 19 | SomeOtherExternalThing *Thing `json:"someOtherExternalThing,omitempty" yaml:"someOtherExternalThing,omitempty" mapstructure:"someOtherExternalThing,omitempty"` 20 | } 21 | 22 | type Thing struct { 23 | // Name corresponds to the JSON schema field "name". 24 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 25 | } 26 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFile/refExternalFile.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refExternalFile", 4 | "type": "object", 5 | "properties": { 6 | "myExternalThing": { 7 | "$ref": "../ref/ref.json#/$defs/Thing" 8 | }, 9 | "someOtherExternalThing": { 10 | "$ref": "../ref/ref.json#/$defs/Thing" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFileWithDupe/refExternalFileWithDupe.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Ref struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing_1 `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | 9 | // MyThing2 corresponds to the JSON schema field "myThing2". 10 | MyThing2 *Thing_1 `json:"myThing2,omitempty" yaml:"myThing2,omitempty" mapstructure:"myThing2,omitempty"` 11 | } 12 | 13 | type RefExternalFileWithDupe struct { 14 | // MyExternalThing corresponds to the JSON schema field "myExternalThing". 15 | MyExternalThing *Thing_1 `json:"myExternalThing,omitempty" yaml:"myExternalThing,omitempty" mapstructure:"myExternalThing,omitempty"` 16 | 17 | // MyThing corresponds to the JSON schema field "myThing". 18 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 19 | } 20 | 21 | type Thing struct { 22 | // Something corresponds to the JSON schema field "something". 23 | Something *string `json:"something,omitempty" yaml:"something,omitempty" mapstructure:"something,omitempty"` 24 | } 25 | 26 | type Thing_1 struct { 27 | // Name corresponds to the JSON schema field "name". 28 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 29 | } 30 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFileWithDupe/refExternalFileWithDupe.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refExternalFileWithDupe", 4 | "type": "object", 5 | "properties": { 6 | "myExternalThing": { 7 | "$ref": "../ref/ref.json#/$defs/Thing" 8 | }, 9 | "myThing": { 10 | "$ref": "#/$defs/Thing" 11 | } 12 | }, 13 | "$defs": { 14 | "Thing": { 15 | "type": "object", 16 | "properties": { 17 | "something": { 18 | "type": "string" 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFileWithScheme/refExternalFileWithScheme.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Ref struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | 9 | // MyThing2 corresponds to the JSON schema field "myThing2". 10 | MyThing2 *Thing `json:"myThing2,omitempty" yaml:"myThing2,omitempty" mapstructure:"myThing2,omitempty"` 11 | } 12 | 13 | type RefExternalFileWithScheme struct { 14 | // MyExternalThing corresponds to the JSON schema field "myExternalThing". 15 | MyExternalThing *Thing `json:"myExternalThing,omitempty" yaml:"myExternalThing,omitempty" mapstructure:"myExternalThing,omitempty"` 16 | 17 | // SomeOtherExternalThing corresponds to the JSON schema field 18 | // "someOtherExternalThing". 19 | SomeOtherExternalThing *Thing `json:"someOtherExternalThing,omitempty" yaml:"someOtherExternalThing,omitempty" mapstructure:"someOtherExternalThing,omitempty"` 20 | } 21 | 22 | type Thing struct { 23 | // Name corresponds to the JSON schema field "name". 24 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 25 | } 26 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFileWithScheme/refExternalFileWithScheme.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refExternalFileWithScheme", 4 | "type": "object", 5 | "properties": { 6 | "myExternalThing": { 7 | "$ref": "file://../ref/ref.json#/$defs/Thing" 8 | }, 9 | "someOtherExternalThing": { 10 | "$ref": "file://../ref/ref.json#/$defs/Thing" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFileYaml/refExternalFile.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type RefExternalFile struct { 6 | // MyExternalThing corresponds to the JSON schema field "myExternalThing". 7 | MyExternalThing *YamlStructNameFromFile `json:"myExternalThing,omitempty" yaml:"myExternalThing,omitempty" mapstructure:"myExternalThing,omitempty"` 8 | 9 | // SomeOtherExternalThing corresponds to the JSON schema field 10 | // "someOtherExternalThing". 11 | SomeOtherExternalThing *YamlStructNameFromFile `json:"someOtherExternalThing,omitempty" yaml:"someOtherExternalThing,omitempty" mapstructure:"someOtherExternalThing,omitempty"` 12 | } 13 | 14 | type YamlStructNameFromFile struct { 15 | // Foo corresponds to the JSON schema field "foo". 16 | Foo *string `json:"foo,omitempty" yaml:"foo,omitempty" mapstructure:"foo,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /tests/data/core/refExternalFileYaml/refExternalFile.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refExternalFile", 4 | "type": "object", 5 | "properties": { 6 | "myExternalThing": { 7 | "$ref": "../../yaml/yamlStructNameFromFile/yamlStructNameFromFile.yaml" 8 | }, 9 | "someOtherExternalThing": { 10 | "$ref": "../../yaml/yamlStructNameFromFile/yamlStructNameFromFile.yaml" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/data/core/refOld/refOld.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type RefOld struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | 9 | // MyThing2 corresponds to the JSON schema field "myThing2". 10 | MyThing2 *Thing `json:"myThing2,omitempty" yaml:"myThing2,omitempty" mapstructure:"myThing2,omitempty"` 11 | } 12 | 13 | type Thing struct { 14 | // Name corresponds to the JSON schema field "name". 15 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /tests/data/core/refOld/refOld.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/ref", 4 | "type": "object", 5 | "properties": { 6 | "myThing": { 7 | "$ref": "#/definitions/Thing" 8 | }, 9 | "myThing2": { 10 | "$ref": "#/definitions/Thing" 11 | } 12 | }, 13 | "definitions": { 14 | "Thing": { 15 | "type": "object", 16 | "properties": { 17 | "name": { 18 | "type": "string" 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/data/core/refToEnum/refToEnum.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "reflect" 9 | 10 | type RefToEnum struct { 11 | // MyThing corresponds to the JSON schema field "myThing". 12 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 13 | } 14 | 15 | type Thing string 16 | 17 | const ThingX Thing = "x" 18 | const ThingY Thing = "y" 19 | 20 | var enumValues_Thing = []interface{}{ 21 | "x", 22 | "y", 23 | } 24 | 25 | // UnmarshalJSON implements json.Unmarshaler. 26 | func (j *Thing) UnmarshalJSON(value []byte) error { 27 | var v string 28 | if err := json.Unmarshal(value, &v); err != nil { 29 | return err 30 | } 31 | var ok bool 32 | for _, expected := range enumValues_Thing { 33 | if reflect.DeepEqual(v, expected) { 34 | ok = true 35 | break 36 | } 37 | } 38 | if !ok { 39 | return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_Thing, v) 40 | } 41 | *j = Thing(v) 42 | return nil 43 | } 44 | 45 | // UnmarshalYAML implements yaml.Unmarshaler. 46 | func (j *Thing) UnmarshalYAML(value *yaml.Node) error { 47 | var v string 48 | if err := value.Decode(&v); err != nil { 49 | return err 50 | } 51 | var ok bool 52 | for _, expected := range enumValues_Thing { 53 | if reflect.DeepEqual(v, expected) { 54 | ok = true 55 | break 56 | } 57 | } 58 | if !ok { 59 | return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_Thing, v) 60 | } 61 | *j = Thing(v) 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /tests/data/core/refToEnum/refToEnum.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refToPrimitive", 4 | "type": "object", 5 | "properties": { 6 | "myThing": { 7 | "$ref": "#/$defs/Thing" 8 | } 9 | }, 10 | "$defs": { 11 | "Thing": { 12 | "type": "string", 13 | "enum": [ 14 | "x", 15 | "y" 16 | ] 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/data/core/refToMap/refToMap.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type RefToMap struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | } 9 | 10 | type Thing map[string]float64 11 | -------------------------------------------------------------------------------- /tests/data/core/refToMap/refToMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refToPrimitive", 4 | "type": "object", 5 | "properties": { 6 | "myThing": { 7 | "$ref": "#/$defs/Thing" 8 | } 9 | }, 10 | "$defs": { 11 | "Thing": { 12 | "type": "object", 13 | "additionalProperties": { 14 | "type": "number" 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /tests/data/core/refToPrimitiveString/refToPrimitiveString.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type RefToPrimitiveString struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | } 9 | 10 | type Thing string 11 | -------------------------------------------------------------------------------- /tests/data/core/refToPrimitiveString/refToPrimitiveString.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refToPrimitive", 4 | "type": "object", 5 | "properties": { 6 | "myThing": { 7 | "$ref": "#/$defs/Thing" 8 | } 9 | }, 10 | "$defs": { 11 | "Thing": { 12 | "type": "string" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/data/core/time/time.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import "github.com/atombender/go-jsonschema/pkg/types" 8 | import yaml "gopkg.in/yaml.v3" 9 | 10 | type Time struct { 11 | // MyObject corresponds to the JSON schema field "myObject". 12 | MyObject *TimeMyObject `json:"myObject,omitempty" yaml:"myObject,omitempty" mapstructure:"myObject,omitempty"` 13 | } 14 | 15 | type TimeMyObject struct { 16 | // MyTime corresponds to the JSON schema field "myTime". 17 | MyTime types.SerializableTime `json:"myTime" yaml:"myTime" mapstructure:"myTime"` 18 | } 19 | 20 | // UnmarshalJSON implements json.Unmarshaler. 21 | func (j *TimeMyObject) UnmarshalJSON(value []byte) error { 22 | var raw map[string]interface{} 23 | if err := json.Unmarshal(value, &raw); err != nil { 24 | return err 25 | } 26 | if _, ok := raw["myTime"]; raw != nil && !ok { 27 | return fmt.Errorf("field myTime in TimeMyObject: required") 28 | } 29 | type Plain TimeMyObject 30 | var plain Plain 31 | if err := json.Unmarshal(value, &plain); err != nil { 32 | return err 33 | } 34 | *j = TimeMyObject(plain) 35 | return nil 36 | } 37 | 38 | // UnmarshalYAML implements yaml.Unmarshaler. 39 | func (j *TimeMyObject) UnmarshalYAML(value *yaml.Node) error { 40 | var raw map[string]interface{} 41 | if err := value.Decode(&raw); err != nil { 42 | return err 43 | } 44 | if _, ok := raw["myTime"]; raw != nil && !ok { 45 | return fmt.Errorf("field myTime in TimeMyObject: required") 46 | } 47 | type Plain TimeMyObject 48 | var plain Plain 49 | if err := value.Decode(&plain); err != nil { 50 | return err 51 | } 52 | *j = TimeMyObject(plain) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /tests/data/core/time/time.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "http://example.com/object", 4 | "type": "object", 5 | "title": "object", 6 | "properties": { 7 | "myObject": { 8 | "type": "object", 9 | "required": [ 10 | "myTime" 11 | ], 12 | "properties": { 13 | "myTime": { 14 | "type": "string", 15 | "format": "time" 16 | } 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/data/crossPackage/other/other.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package other 4 | 5 | type Thing struct { 6 | // S corresponds to the JSON schema field "s". 7 | S *string `json:"s,omitempty" yaml:"s,omitempty" mapstructure:"s,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/crossPackage/other/other.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/other", 4 | "$defs": { 5 | "Thing": { 6 | "type": "object", 7 | "properties": { 8 | "s": { 9 | "type": "string" 10 | } 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/data/crossPackage/schema/schema.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package schema 4 | 5 | import other "github.com/atombender/go-jsonschema/tests/data/crossPackage/other" 6 | 7 | type Schema struct { 8 | // DefInOtherSchema corresponds to the JSON schema field "defInOtherSchema". 9 | DefInOtherSchema *other.Thing `json:"defInOtherSchema,omitempty" yaml:"defInOtherSchema,omitempty" mapstructure:"defInOtherSchema,omitempty"` 10 | 11 | // DefInSameSchema corresponds to the JSON schema field "defInSameSchema". 12 | DefInSameSchema *Thing `json:"defInSameSchema,omitempty" yaml:"defInSameSchema,omitempty" mapstructure:"defInSameSchema,omitempty"` 13 | } 14 | 15 | type Thing struct { 16 | // S corresponds to the JSON schema field "s". 17 | S *string `json:"s,omitempty" yaml:"s,omitempty" mapstructure:"s,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /tests/data/crossPackage/schema/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/schema", 4 | "type": "object", 5 | "properties": { 6 | "defInSameSchema": { 7 | "$ref": "#/$defs/Thing" 8 | }, 9 | "defInOtherSchema": { 10 | "$ref": "../other/other.json#/$defs/Thing" 11 | } 12 | }, 13 | "$defs": { 14 | "Thing": { 15 | "type": "object", 16 | "properties": { 17 | "s": { 18 | "type": "string" 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/data/crossPackageNoOutput/other/other.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/other", 4 | "$defs": { 5 | "Thing": { 6 | "type": "object", 7 | "properties": { 8 | "s": { 9 | "type": "string" 10 | } 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/data/crossPackageNoOutput/schema/schema.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package schema 4 | 5 | import other "github.com/atombender/go-jsonschema/tests/helpers/other" 6 | 7 | type Schema struct { 8 | // DefInOtherSchema corresponds to the JSON schema field "defInOtherSchema". 9 | DefInOtherSchema *other.Thing `json:"defInOtherSchema,omitempty" yaml:"defInOtherSchema,omitempty" mapstructure:"defInOtherSchema,omitempty"` 10 | 11 | // DefInSameSchema corresponds to the JSON schema field "defInSameSchema". 12 | DefInSameSchema *Thing `json:"defInSameSchema,omitempty" yaml:"defInSameSchema,omitempty" mapstructure:"defInSameSchema,omitempty"` 13 | } 14 | 15 | type Thing struct { 16 | // S corresponds to the JSON schema field "s". 17 | S *string `json:"s,omitempty" yaml:"s,omitempty" mapstructure:"s,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /tests/data/crossPackageNoOutput/schema/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/schema", 4 | "type": "object", 5 | "properties": { 6 | "defInSameSchema": { 7 | "$ref": "#/$defs/Thing" 8 | }, 9 | "defInOtherSchema": { 10 | "$ref": "../other/other.json#/$defs/Thing" 11 | } 12 | }, 13 | "$defs": { 14 | "Thing": { 15 | "type": "object", 16 | "properties": { 17 | "s": { 18 | "type": "string" 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/data/deeplyNested/Makefile: -------------------------------------------------------------------------------- 1 | standalone/RolloutSpecification.json: 2 | wget --output-document=$@ --quiet https://ev2schema.azure.net/schemas/2020-01-01/$(notdir $@) -------------------------------------------------------------------------------- /tests/data/disableCustomTypesForMaps/map.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Map struct { 6 | // MyMap corresponds to the JSON schema field "myMap". 7 | MyMap map[string]float64 `json:"myMap,omitempty" yaml:"myMap,omitempty" mapstructure:"myMap,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/disableCustomTypesForMaps/map.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "http://example.com/object", 4 | "type": "object", 5 | "properties": { 6 | "myMap": { 7 | "type": "object", 8 | "additionalProperties": { 9 | "type": "number" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /tests/data/disableCustomTypesForMaps/refToMap.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type RefToMap struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing map[string]float64 `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/disableCustomTypesForMaps/refToMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refToPrimitive", 4 | "type": "object", 5 | "properties": { 6 | "myThing": { 7 | "$ref": "#/$defs/Thing" 8 | } 9 | }, 10 | "$defs": { 11 | "Thing": { 12 | "type": "object", 13 | "additionalProperties": { 14 | "type": "number" 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /tests/data/disableOmitempty/omitempty.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Omitempty struct { 6 | // ImportedString corresponds to the JSON schema field "importedString". 7 | ImportedString *string `json:"importedString" yaml:"importedString" mapstructure:"importedString"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/disableOmitempty/omitempty.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/imported", 4 | "type": "object", 5 | "properties": { 6 | "importedString": { 7 | "type": "string" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/primitives", 4 | "type": "object", 5 | "properties": { 6 | "myString": { 7 | "type": "string" 8 | }, 9 | "myNumber": { 10 | "type": "number" 11 | }, 12 | "myInteger": { 13 | "type": "integer" 14 | }, 15 | "myBoolean": { 16 | "type": "boolean" 17 | }, 18 | "myNull": { 19 | "type": "null" 20 | }, 21 | "myEnum": { 22 | "type": "string", 23 | "enum": [ 24 | "x", 25 | "y" 26 | ] 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/data/extraImports/gopkgYAMLv3/gopkgYAMLv3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | myString: example 3 | myNumber: 123.456 4 | myInteger: 123 5 | myBoolean: true 6 | myNull: null 7 | myEnum: x 8 | -------------------------------------------------------------------------------- /tests/data/extraImports/gopkgYAMLv3AdditionalProperties/gopkgYAMLv3AdditionalProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/empty_object_properties", 4 | "type": "object", 5 | "additionalProperties": { 6 | "type": "object", 7 | "properties": { 8 | "property1": { 9 | "type": "string" 10 | }, 11 | "property2": { 12 | "type": "number" 13 | } 14 | } 15 | }, 16 | "properties": { 17 | "foo": { 18 | "type": "string" 19 | }, 20 | "bar": { 21 | "type": "string" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/data/extraImports/gopkgYAMLv3AdditionalProperties/gopkgYAMLv3AdditionalProperties.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | foo: "example1" 3 | bar: "example2" 4 | baz: 5 | property1: "hello" 6 | property2: 123 7 | -------------------------------------------------------------------------------- /tests/data/extraImports/gopkgYAMLv3invalidEnum/gopkgYAMLv3invalidEnum.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | myString: example 3 | myNumber: 123.456 4 | myInteger: 123 5 | myBoolean: true 6 | myNull: null 7 | myEnum: z 8 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/arrays/exact.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/arrays", 4 | "type": "object", 5 | "properties": { 6 | "i8": { 7 | "type": "array", 8 | "items": { 9 | "type": "integer", 10 | "minimum": -128, 11 | "maximum": 127 12 | } 13 | }, 14 | "i16": { 15 | "type": "array", 16 | "items": { 17 | "type": "integer", 18 | "minimum": -32768, 19 | "maximum": 32767 20 | } 21 | }, 22 | "i32": { 23 | "type": "array", 24 | "items": { 25 | "type": "integer", 26 | "minimum": -2147483648, 27 | "maximum": 2147483647 28 | } 29 | }, 30 | "i64": { 31 | "type": "array", 32 | "items": { 33 | "type": "integer", 34 | "minimum": -9223372036854775808, 35 | "maximum": 9223372036854775807 36 | } 37 | }, 38 | "u8": { 39 | "type": "array", 40 | "items": { 41 | "type": "integer", 42 | "minimum": 0, 43 | "maximum": 255 44 | } 45 | }, 46 | "u16": { 47 | "type": "array", 48 | "items": { 49 | "type": "integer", 50 | "minimum": 0, 51 | "maximum": 65535 52 | } 53 | }, 54 | "u32": { 55 | "type": "array", 56 | "items": { 57 | "type": "integer", 58 | "minimum": 0, 59 | "maximum": 4294967295 60 | } 61 | }, 62 | "u64": { 63 | "type": "array", 64 | "items": { 65 | "type": "integer", 66 | "minimum": 0, 67 | "maximum": 18446744073709551615 68 | } 69 | } 70 | }, 71 | "required": [ 72 | "i8", 73 | "i16", 74 | "i32", 75 | "i64", 76 | "u8", 77 | "u16", 78 | "u32", 79 | "u64" 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/exactReferences/exact.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/reference", 4 | "type": "object", 5 | "definitions": { 6 | "bound8": { 7 | "type": "integer", 8 | "minimum": -128, 9 | "maximum": 127 10 | }, 11 | "bound16": { 12 | "type": "integer", 13 | "minimum": -32768, 14 | "maximum": 32767 15 | }, 16 | "bound32": { 17 | "type": "integer", 18 | "minimum": -2147483648, 19 | "maximum": 2147483647 20 | }, 21 | "bound64": { 22 | "type": "integer", 23 | "minimum": -9223372036854775808, 24 | "maximum": 9223372036854775807 25 | }, 26 | "uBound8": { 27 | "type": "integer", 28 | "minimum": 0, 29 | "maximum": 255 30 | }, 31 | "uBound16": { 32 | "type": "integer", 33 | "minimum": 0, 34 | "maximum": 65535 35 | }, 36 | "uBound32": { 37 | "type": "integer", 38 | "minimum": 0, 39 | "maximum": 4294967295 40 | }, 41 | "uBound64": { 42 | "type": "integer", 43 | "minimum": 0, 44 | "maximum": 18446744073709551615 45 | } 46 | }, 47 | "properties": { 48 | "i8": { 49 | "$ref": "#/definitions/bound8" 50 | }, 51 | "i16": { 52 | "$ref": "#/definitions/bound16" 53 | }, 54 | "i32": { 55 | "$ref": "#/definitions/bound32" 56 | }, 57 | "i64": { 58 | "$ref": "#/definitions/bound64" 59 | }, 60 | "u8": { 61 | "$ref": "#/definitions/uBound8" 62 | }, 63 | "u16": { 64 | "$ref": "#/definitions/uBound16" 65 | }, 66 | "u32": { 67 | "$ref": "#/definitions/uBound32" 68 | }, 69 | "u64": { 70 | "$ref": "#/definitions/uBound64" 71 | } 72 | }, 73 | "required": [ 74 | "i8", 75 | "i16", 76 | "i32", 77 | "i64", 78 | "u8", 79 | "u16", 80 | "u32", 81 | "u64" 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/exactSizes/exact.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/exact", 4 | "type": "object", 5 | "properties": { 6 | "i8": { 7 | "type": "integer", 8 | "minimum": -128, 9 | "maximum": 127 10 | }, 11 | "i16": { 12 | "type": "integer", 13 | "minimum": -32768, 14 | "maximum": 32767 15 | }, 16 | "i32": { 17 | "type": "integer", 18 | "minimum": -2147483648, 19 | "maximum": 2147483647 20 | }, 21 | "i64": { 22 | "type": "integer", 23 | "minimum": -9223372036854775808, 24 | "maximum": 9223372036854775807 25 | }, 26 | "u8": { 27 | "type": "integer", 28 | "minimum": 0, 29 | "maximum": 255 30 | }, 31 | "u16": { 32 | "type": "integer", 33 | "minimum": 0, 34 | "maximum": 65535 35 | }, 36 | "u32": { 37 | "type": "integer", 38 | "minimum": 0, 39 | "maximum": 4294967295 40 | }, 41 | "u64": { 42 | "type": "integer", 43 | "minimum": 0, 44 | "maximum": 18446744073709551615 45 | } 46 | }, 47 | "required": [ 48 | "i8", 49 | "i16", 50 | "i32", 51 | "i64", 52 | "u8", 53 | "u16", 54 | "u32", 55 | "u64" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/exactSizesExclusiveBool/exact.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/exact", 4 | "type": "object", 5 | "properties": { 6 | "i8": { 7 | "type": "integer", 8 | "minimum": -129, 9 | "maximum": 128, 10 | "exclusiveMinimum": true, 11 | "exclusiveMaximum": true 12 | }, 13 | "i16": { 14 | "type": "integer", 15 | "minimum": -32769, 16 | "maximum": 32768, 17 | "exclusiveMinimum": true, 18 | "exclusiveMaximum": true 19 | }, 20 | "i32": { 21 | "type": "integer", 22 | "minimum": -2147483649, 23 | "maximum": 2147483648, 24 | "exclusiveMinimum": true, 25 | "exclusiveMaximum": true 26 | }, 27 | "i64": { 28 | "type": "integer", 29 | "minimum": -9223372036854775809, 30 | "maximum": 9223372036854775808, 31 | "exclusiveMinimum": true, 32 | "exclusiveMaximum": true 33 | }, 34 | "u8": { 35 | "type": "integer", 36 | "minimum": -1, 37 | "maximum": 256, 38 | "exclusiveMinimum": true, 39 | "exclusiveMaximum": true 40 | }, 41 | "u16": { 42 | "type": "integer", 43 | "minimum": -1, 44 | "maximum": 65536, 45 | "exclusiveMinimum": true, 46 | "exclusiveMaximum": true 47 | }, 48 | "u32": { 49 | "type": "integer", 50 | "minimum": -1, 51 | "maximum": 4294967296, 52 | "exclusiveMinimum": true, 53 | "exclusiveMaximum": true 54 | }, 55 | "u64": { 56 | "type": "integer", 57 | "minimum": -1, 58 | "maximum": 18446744073709551616, 59 | "exclusiveMinimum": true, 60 | "exclusiveMaximum": true 61 | } 62 | }, 63 | "required": [ 64 | "i8", 65 | "i16", 66 | "i32", 67 | "i64", 68 | "u8", 69 | "u16", 70 | "u32", 71 | "u64" 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/exactSizesExclusiveNum/exact.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/exact", 4 | "type": "object", 5 | "properties": { 6 | "i8": { 7 | "type": "integer", 8 | "exclusiveMinimum": -129, 9 | "exclusiveMaximum": 128 10 | }, 11 | "i16": { 12 | "type": "integer", 13 | "exclusiveMinimum": -32769, 14 | "exclusiveMaximum": 32768 15 | }, 16 | "i32": { 17 | "type": "integer", 18 | "exclusiveMinimum": -2147483649, 19 | "exclusiveMaximum": 2147483648 20 | }, 21 | "i64": { 22 | "type": "integer", 23 | "exclusiveMinimum": -9223372036854775809, 24 | "exclusiveMaximum": 9223372036854775808 25 | }, 26 | "u8": { 27 | "type": "integer", 28 | "exclusiveMinimum": -1, 29 | "exclusiveMaximum": 256 30 | }, 31 | "u16": { 32 | "type": "integer", 33 | "exclusiveMinimum": -1, 34 | "exclusiveMaximum": 65536 35 | }, 36 | "u32": { 37 | "type": "integer", 38 | "exclusiveMinimum": -1, 39 | "exclusiveMaximum": 4294967296 40 | }, 41 | "u64": { 42 | "type": "integer", 43 | "exclusiveMinimum": -1, 44 | "exclusiveMaximum": 18446744073709551616 45 | } 46 | }, 47 | "required": [ 48 | "i8", 49 | "i16", 50 | "i32", 51 | "i64", 52 | "u8", 53 | "u16", 54 | "u32", 55 | "u64" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/largerSizes/larger.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/exact", 4 | "type": "object", 5 | "properties": { 6 | "i16l": { 7 | "type": "integer", 8 | "minimum": -129, 9 | "maximum": 127 10 | }, 11 | "i16u": { 12 | "type": "integer", 13 | "minimum": -128, 14 | "maximum": 128 15 | }, 16 | "i32l": { 17 | "type": "integer", 18 | "minimum": -32769, 19 | "maximum": 32767 20 | }, 21 | "i32u": { 22 | "type": "integer", 23 | "minimum": -32768, 24 | "maximum": 32768 25 | }, 26 | "i64l": { 27 | "type": "integer", 28 | "minimum": -2147483649, 29 | "maximum": 2147483647 30 | }, 31 | "i64u": { 32 | "type": "integer", 33 | "minimum": -2147483648, 34 | "maximum": 2147483648 35 | }, 36 | "u16" : { 37 | "type" : "integer", 38 | "minimum" : 0, 39 | "maximum" : 256 40 | }, 41 | "u32" : { 42 | "type" : "integer", 43 | "minimum" : 0, 44 | "maximum" : 65536 45 | }, 46 | "u64" : { 47 | "type" : "integer", 48 | "minimum" : 0, 49 | "maximum" : 4294967296 50 | } 51 | }, 52 | "required": [ 53 | "i8", 54 | "i16", 55 | "i32", 56 | "i64", 57 | "u8", 58 | "u16", 59 | "u32", 60 | "u64" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/restrictedSizes/restricted.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/restricted", 4 | "type": "object", 5 | "properties": { 6 | "i8": { 7 | "type": "integer", 8 | "minimum": -127, 9 | "maximum": 126 10 | }, 11 | "i16": { 12 | "type": "integer", 13 | "minimum": -32767, 14 | "maximum": 32766 15 | }, 16 | "i32": { 17 | "type": "integer", 18 | "minimum": -2147483647, 19 | "maximum": 2147483646 20 | }, 21 | "i64": { 22 | "type": "integer", 23 | "minimum": -9223372036854775807, 24 | "maximum": 9223372036854775806 25 | }, 26 | "u8": { 27 | "type": "integer", 28 | "minimum": 1, 29 | "maximum": 254 30 | }, 31 | "u16": { 32 | "type": "integer", 33 | "minimum": 1, 34 | "maximum": 65534 35 | }, 36 | "u32": { 37 | "type": "integer", 38 | "minimum": 1, 39 | "maximum": 4294967294 40 | }, 41 | "u64": { 42 | "type": "integer", 43 | "minimum": 1, 44 | "maximum": 18446744073709551614 45 | } 46 | }, 47 | "required": [ 48 | "i8", 49 | "i16", 50 | "i32", 51 | "i64", 52 | "u8", 53 | "u16", 54 | "u32", 55 | "u64" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /tests/data/minSizedInts/restrictedSizesReferences/restricted.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/restrictedReferences", 4 | "type": "object", 5 | "definitions": { 6 | "i16l": { 7 | "type": "integer", 8 | "minimum": -129, 9 | "maximum": 127 10 | }, 11 | "i16u": { 12 | "type": "integer", 13 | "minimum": -128, 14 | "maximum": 128 15 | }, 16 | "i32l": { 17 | "type": "integer", 18 | "minimum": -32769, 19 | "maximum": 32767 20 | }, 21 | "i32u": { 22 | "type": "integer", 23 | "minimum": -32768, 24 | "maximum": 32768 25 | }, 26 | "i64l": { 27 | "type": "integer", 28 | "minimum": -2147483649, 29 | "maximum": 2147483647 30 | }, 31 | "i64u": { 32 | "type": "integer", 33 | "minimum": -2147483648, 34 | "maximum": 2147483648 35 | }, 36 | "u16": { 37 | "type": "integer", 38 | "minimum": 0, 39 | "maximum": 256 40 | }, 41 | "u32": { 42 | "type": "integer", 43 | "minimum": 0, 44 | "maximum": 65536 45 | }, 46 | "u64": { 47 | "type": "integer", 48 | "minimum": 0, 49 | "maximum": 4294967296 50 | } 51 | }, 52 | "properties": { 53 | "i16l": { 54 | "$ref": "#/definitions/i16l" 55 | }, 56 | "i16u": { 57 | "$ref": "#/definitions/i16u" 58 | }, 59 | "i32l": { 60 | "$ref": "#/definitions/i32l" 61 | }, 62 | "i32u": { 63 | "$ref": "#/definitions/i32u" 64 | }, 65 | "i64l": { 66 | "$ref": "#/definitions/i64l" 67 | }, 68 | "i64u": { 69 | "$ref": "#/definitions/i64u" 70 | }, 71 | "u16": { 72 | "$ref": "#/definitions/u16" 73 | }, 74 | "u32": { 75 | "$ref": "#/definitions/u32" 76 | }, 77 | "u64": { 78 | "$ref": "#/definitions/u64" 79 | } 80 | }, 81 | "required": [ 82 | "i16l", 83 | "i16u", 84 | "i32l", 85 | "i32u", 86 | "i64l", 87 | "i64u", 88 | "u16", 89 | "u32", 90 | "u64" 91 | ] 92 | } 93 | -------------------------------------------------------------------------------- /tests/data/misc/booleanAsSchema/booleanAsSchema.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type BooleanAsSchema struct { 6 | // Id corresponds to the JSON schema field "id". 7 | Id *string `json:"id,omitempty" yaml:"id,omitempty" mapstructure:"id,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/misc/booleanAsSchema/booleanAsSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/case", 4 | "type": "object", 5 | "additionalProperties": false, 6 | "properties": { 7 | "id": { 8 | "type": "string" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/data/misc/capitalization/capitalization.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/case", 4 | "type": "object", 5 | "properties": { 6 | "url": { 7 | "type": "string" 8 | }, 9 | "id": { 10 | "type": "string" 11 | }, 12 | "html": { 13 | "type": "string" 14 | }, 15 | "url_something": { 16 | "type": "string" 17 | }, 18 | "id_something": { 19 | "type": "string" 20 | }, 21 | "html_something": { 22 | "type": "string" 23 | }, 24 | "urlSomethingElse": { 25 | "type": "string" 26 | }, 27 | "idSomethingElse": { 28 | "type": "string" 29 | }, 30 | "htmlSomethingElse": { 31 | "type": "string" 32 | }, 33 | "url__": { 34 | "type": "string" 35 | }, 36 | "id__": { 37 | "type": "string" 38 | }, 39 | "html__": { 40 | "type": "string" 41 | }, 42 | 43 | "속성": { 44 | "type": "string" 45 | }, 46 | "アトリビュート": { 47 | "type": "string" 48 | }, 49 | "属性": { 50 | "type": "string" 51 | }, 52 | "屬性": { 53 | "type": "string" 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/data/misc/onlyModels/onlyModels.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type OnlyModels struct { 6 | // MyBoolean corresponds to the JSON schema field "myBoolean". 7 | MyBoolean *bool `json:"myBoolean,omitempty" yaml:"myBoolean,omitempty" mapstructure:"myBoolean,omitempty"` 8 | 9 | // MyEnum corresponds to the JSON schema field "myEnum". 10 | MyEnum *OnlyModelsMyEnum `json:"myEnum,omitempty" yaml:"myEnum,omitempty" mapstructure:"myEnum,omitempty"` 11 | 12 | // MyInteger corresponds to the JSON schema field "myInteger". 13 | MyInteger *int `json:"myInteger,omitempty" yaml:"myInteger,omitempty" mapstructure:"myInteger,omitempty"` 14 | 15 | // MyNull corresponds to the JSON schema field "myNull". 16 | MyNull interface{} `json:"myNull,omitempty" yaml:"myNull,omitempty" mapstructure:"myNull,omitempty"` 17 | 18 | // MyNumber corresponds to the JSON schema field "myNumber". 19 | MyNumber *float64 `json:"myNumber,omitempty" yaml:"myNumber,omitempty" mapstructure:"myNumber,omitempty"` 20 | 21 | // MyString corresponds to the JSON schema field "myString". 22 | MyString *string `json:"myString,omitempty" yaml:"myString,omitempty" mapstructure:"myString,omitempty"` 23 | } 24 | 25 | type OnlyModelsMyEnum string 26 | 27 | const OnlyModelsMyEnumX OnlyModelsMyEnum = "x" 28 | const OnlyModelsMyEnumY OnlyModelsMyEnum = "y" 29 | -------------------------------------------------------------------------------- /tests/data/misc/onlyModels/onlyModels.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/primitives", 4 | "type": "object", 5 | "properties": { 6 | "myString": { 7 | "type": "string" 8 | }, 9 | "myNumber": { 10 | "type": "number" 11 | }, 12 | "myInteger": { 13 | "type": "integer" 14 | }, 15 | "myBoolean": { 16 | "type": "boolean" 17 | }, 18 | "myNull": { 19 | "type": "null" 20 | }, 21 | "myEnum": { 22 | "type": "string", 23 | "enum": [ 24 | "x", 25 | "y" 26 | ] 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/data/misc/specialCharacters/specialCharacters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/special-characters", 4 | "type": "object", 5 | "properties": { 6 | "plainLicenses": { 7 | "type": "string", 8 | "enum": [ 9 | "GPL-3.0", 10 | "MIT", 11 | "*" 12 | ] 13 | }, 14 | "plusLicenses": { 15 | "type": "string", 16 | "enum": [ 17 | "GPL-3.0+", 18 | "MIT+", 19 | "*" 20 | ] 21 | }, 22 | "plainLicensesRef": { 23 | "type": "array", 24 | "items": { 25 | "$ref": "#/definitions/license" 26 | } 27 | }, 28 | "plusLicensesRef": { 29 | "type": "array", 30 | "items": { 31 | "$ref": "#/definitions/license+" 32 | } 33 | } 34 | }, 35 | "definitions": { 36 | "license": { 37 | "type": "string", 38 | "enum": [ 39 | "GPL-3.0", 40 | "MIT", 41 | "*" 42 | ] 43 | }, 44 | "license+": { 45 | "type": "string", 46 | "enum": [ 47 | "GPL-3.0+", 48 | "MIT+", 49 | "*" 50 | ] 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/data/misc/tags/tags.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Tags struct { 6 | // Html corresponds to the JSON schema field "html". 7 | Html *string `yaml:"html,omitempty"` 8 | 9 | // Id corresponds to the JSON schema field "id". 10 | Id *string `yaml:"id,omitempty"` 11 | 12 | // Url corresponds to the JSON schema field "url". 13 | Url *string `yaml:"url,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /tests/data/misc/tags/tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/case", 4 | "type": "object", 5 | "properties": { 6 | "url": { 7 | "type": "string" 8 | }, 9 | "id": { 10 | "type": "string" 11 | }, 12 | "html": { 13 | "type": "string" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/case/case.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Case struct { 6 | // CapitalCamelField corresponds to the JSON schema field "CapitalCamelField". 7 | CapitalCamelField *string `json:"CapitalCamelField,omitempty" yaml:"CapitalCamelField,omitempty" mapstructure:"CapitalCamelField,omitempty"` 8 | 9 | // UPPERCASEFIELD corresponds to the JSON schema field "UPPERCASEFIELD". 10 | UPPERCASEFIELD *string `json:"UPPERCASEFIELD,omitempty" yaml:"UPPERCASEFIELD,omitempty" mapstructure:"UPPERCASEFIELD,omitempty"` 11 | 12 | // CamelCase corresponds to the JSON schema field "camelCase". 13 | CamelCase *string `json:"camelCase,omitempty" yaml:"camelCase,omitempty" mapstructure:"camelCase,omitempty"` 14 | 15 | // Lowercase corresponds to the JSON schema field "lowercase". 16 | Lowercase *string `json:"lowercase,omitempty" yaml:"lowercase,omitempty" mapstructure:"lowercase,omitempty"` 17 | 18 | // SnakeMixedCase corresponds to the JSON schema field "snake_Mixed_Case". 19 | SnakeMixedCase *string `json:"snake_Mixed_Case,omitempty" yaml:"snake_Mixed_Case,omitempty" mapstructure:"snake_Mixed_Case,omitempty"` 20 | 21 | // SnakeCase corresponds to the JSON schema field "snake_case". 22 | SnakeCase *string `json:"snake_case,omitempty" yaml:"snake_case,omitempty" mapstructure:"snake_case,omitempty"` 23 | } 24 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/case/case.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/case", 4 | "type": "object", 5 | "properties": { 6 | "lowercase": { 7 | "type": "string" 8 | }, 9 | "camelCase": { 10 | "type": "string" 11 | }, 12 | "snake_case": { 13 | "type": "string" 14 | }, 15 | "snake_Mixed_Case": { 16 | "type": "string" 17 | }, 18 | "CapitalCamelField": { 19 | "type": "string" 20 | }, 21 | "UPPERCASEFIELD": { 22 | "type": "string" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/caseDupes/caseDupes.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type CaseDupes struct { 6 | // SomeField corresponds to the JSON schema field "SomeField". 7 | SomeField *string `json:"SomeField,omitempty" yaml:"SomeField,omitempty" mapstructure:"SomeField,omitempty"` 8 | 9 | // SomeField_2 corresponds to the JSON schema field "someField". 10 | SomeField_2 *string `json:"someField,omitempty" yaml:"someField,omitempty" mapstructure:"someField,omitempty"` 11 | 12 | // SomeField_3 corresponds to the JSON schema field "some_Field". 13 | SomeField_3 *string `json:"some_Field,omitempty" yaml:"some_Field,omitempty" mapstructure:"some_Field,omitempty"` 14 | 15 | // SomeField_4 corresponds to the JSON schema field "some_field". 16 | SomeField_4 *string `json:"some_field,omitempty" yaml:"some_field,omitempty" mapstructure:"some_field,omitempty"` 17 | 18 | // Somefield corresponds to the JSON schema field "somefield". 19 | Somefield *string `json:"somefield,omitempty" yaml:"somefield,omitempty" mapstructure:"somefield,omitempty"` 20 | } 21 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/caseDupes/caseDupes.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/caseDupes", 4 | "type": "object", 5 | "properties": { 6 | "somefield": { 7 | "type": "string" 8 | }, 9 | "someField": { 10 | "type": "string" 11 | }, 12 | "some_field": { 13 | "type": "string" 14 | }, 15 | "some_Field": { 16 | "type": "string" 17 | }, 18 | "SomeField": { 19 | "type": "string" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/cyclic/cyclic.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Bar struct { 6 | // RefToFoo corresponds to the JSON schema field "refToFoo". 7 | RefToFoo *Foo `json:"refToFoo,omitempty" yaml:"refToFoo,omitempty" mapstructure:"refToFoo,omitempty"` 8 | } 9 | 10 | type Cyclic struct { 11 | // A corresponds to the JSON schema field "a". 12 | A *Foo `json:"a,omitempty" yaml:"a,omitempty" mapstructure:"a,omitempty"` 13 | } 14 | 15 | type Foo struct { 16 | // RefToBar corresponds to the JSON schema field "refToBar". 17 | RefToBar *Bar `json:"refToBar,omitempty" yaml:"refToBar,omitempty" mapstructure:"refToBar,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/cyclic/cyclic.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/cyclic", 4 | "type": "object", 5 | "properties": { 6 | "a": { 7 | "$ref": "#/$defs/Foo" 8 | } 9 | }, 10 | "$defs": { 11 | "Foo": { 12 | "type": "object", 13 | "properties": { 14 | "refToBar": { 15 | "$ref": "#/$defs/Bar" 16 | } 17 | } 18 | }, 19 | "Bar": { 20 | "type": "object", 21 | "properties": { 22 | "refToFoo": { 23 | "$ref": "#/$defs/Foo" 24 | } 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type Bar struct { 10 | // RefToFoo corresponds to the JSON schema field "refToFoo". 11 | RefToFoo *Foo `json:"refToFoo,omitempty" yaml:"refToFoo,omitempty" mapstructure:"refToFoo,omitempty"` 12 | } 13 | 14 | type CyclicAndRequired1 struct { 15 | // A corresponds to the JSON schema field "a". 16 | A *Foo `json:"a,omitempty" yaml:"a,omitempty" mapstructure:"a,omitempty"` 17 | } 18 | 19 | type Foo struct { 20 | // RefToBar corresponds to the JSON schema field "refToBar". 21 | RefToBar Bar `json:"refToBar" yaml:"refToBar" mapstructure:"refToBar"` 22 | } 23 | 24 | // UnmarshalJSON implements json.Unmarshaler. 25 | func (j *Foo) UnmarshalJSON(value []byte) error { 26 | var raw map[string]interface{} 27 | if err := json.Unmarshal(value, &raw); err != nil { 28 | return err 29 | } 30 | if _, ok := raw["refToBar"]; raw != nil && !ok { 31 | return fmt.Errorf("field refToBar in Foo: required") 32 | } 33 | type Plain Foo 34 | var plain Plain 35 | if err := json.Unmarshal(value, &plain); err != nil { 36 | return err 37 | } 38 | *j = Foo(plain) 39 | return nil 40 | } 41 | 42 | // UnmarshalYAML implements yaml.Unmarshaler. 43 | func (j *Foo) UnmarshalYAML(value *yaml.Node) error { 44 | var raw map[string]interface{} 45 | if err := value.Decode(&raw); err != nil { 46 | return err 47 | } 48 | if _, ok := raw["refToBar"]; raw != nil && !ok { 49 | return fmt.Errorf("field refToBar in Foo: required") 50 | } 51 | type Plain Foo 52 | var plain Plain 53 | if err := value.Decode(&plain); err != nil { 54 | return err 55 | } 56 | *j = Foo(plain) 57 | return nil 58 | } 59 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/cyclicAndRequired1/cyclicAndRequired1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/cyclicAndRequired1", 4 | "type": "object", 5 | "properties": { 6 | "a": { 7 | "$ref": "#/$defs/Foo" 8 | } 9 | }, 10 | "$defs": { 11 | "Foo": { 12 | "type": "object", 13 | "required": [ 14 | "refToBar" 15 | ], 16 | "properties": { 17 | "refToBar": { 18 | "$ref": "#/$defs/Bar" 19 | } 20 | } 21 | }, 22 | "Bar": { 23 | "type": "object", 24 | "properties": { 25 | "refToFoo": { 26 | "$ref": "#/$defs/Foo" 27 | } 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/rootEmptyJustDefinitions/rootEmptyJustDefinitions.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Thing struct { 6 | // Name corresponds to the JSON schema field "name". 7 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/rootEmptyJustDefinitions/rootEmptyJustDefinitions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/empty_def", 4 | "$defs": { 5 | "Thing": { 6 | "type": "object", 7 | "properties": { 8 | "name": { 9 | "type": "string" 10 | } 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/rootIsArrayOfString/rootIsArrayOfString.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type RootIsArrayOfString []string 6 | -------------------------------------------------------------------------------- /tests/data/miscWithDefaults/rootIsArrayOfString/rootIsArrayOfString.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/rootIsArrayOfString", 4 | "type": "array", 5 | "items": { 6 | "type": "string" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/nameFromTitle/ref/ref.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type ExtRef struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | 9 | // MyThing2 corresponds to the JSON schema field "myThing2". 10 | MyThing2 *Thing `json:"myThing2,omitempty" yaml:"myThing2,omitempty" mapstructure:"myThing2,omitempty"` 11 | } 12 | 13 | type Thing struct { 14 | // Name corresponds to the JSON schema field "name". 15 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /tests/data/nameFromTitle/ref/ref.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/ref", 4 | "title": "Ext Ref", 5 | "type": "object", 6 | "properties": { 7 | "myThing": { 8 | "$ref": "#/$defs/Thing" 9 | }, 10 | "myThing2": { 11 | "$ref": "#/$defs/Thing" 12 | } 13 | }, 14 | "$defs": { 15 | "Thing": { 16 | "type": "object", 17 | "properties": { 18 | "name": { 19 | "type": "string" 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/data/nameFromTitle/refExternalFile/refExternalFile.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type ExtRef struct { 6 | // MyThing corresponds to the JSON schema field "myThing". 7 | MyThing *Thing `json:"myThing,omitempty" yaml:"myThing,omitempty" mapstructure:"myThing,omitempty"` 8 | 9 | // MyThing2 corresponds to the JSON schema field "myThing2". 10 | MyThing2 *Thing `json:"myThing2,omitempty" yaml:"myThing2,omitempty" mapstructure:"myThing2,omitempty"` 11 | } 12 | 13 | type RefExternalFile struct { 14 | // MyExternalThing corresponds to the JSON schema field "myExternalThing". 15 | MyExternalThing *Thing `json:"myExternalThing,omitempty" yaml:"myExternalThing,omitempty" mapstructure:"myExternalThing,omitempty"` 16 | 17 | // SomeOtherExternalThing corresponds to the JSON schema field 18 | // "someOtherExternalThing". 19 | SomeOtherExternalThing *Thing `json:"someOtherExternalThing,omitempty" yaml:"someOtherExternalThing,omitempty" mapstructure:"someOtherExternalThing,omitempty"` 20 | } 21 | 22 | type Thing struct { 23 | // Name corresponds to the JSON schema field "name". 24 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 25 | } 26 | -------------------------------------------------------------------------------- /tests/data/nameFromTitle/refExternalFile/refExternalFile.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/refExternalFile", 4 | "title": "Ref External File", 5 | "type": "object", 6 | "properties": { 7 | "myExternalThing": { 8 | "$ref": "../ref/ref.json#/$defs/Thing" 9 | }, 10 | "someOtherExternalThing": { 11 | "$ref": "../ref/ref.json#/$defs/Thing" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/data/regressions/issue32/issue32.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type TestObject struct { 10 | // Config corresponds to the JSON schema field "config". 11 | Config TestObjectConfig `json:"config,omitempty" yaml:"config,omitempty" mapstructure:"config,omitempty"` 12 | 13 | // Name corresponds to the JSON schema field "name". 14 | Name string `json:"name" yaml:"name" mapstructure:"name"` 15 | 16 | // Owner corresponds to the JSON schema field "owner". 17 | Owner string `json:"owner" yaml:"owner" mapstructure:"owner"` 18 | } 19 | 20 | type TestObjectConfig map[string]interface{} 21 | 22 | // UnmarshalJSON implements json.Unmarshaler. 23 | func (j *TestObject) UnmarshalJSON(value []byte) error { 24 | var raw map[string]interface{} 25 | if err := json.Unmarshal(value, &raw); err != nil { 26 | return err 27 | } 28 | if _, ok := raw["name"]; raw != nil && !ok { 29 | return fmt.Errorf("field name in TestObject: required") 30 | } 31 | if _, ok := raw["owner"]; raw != nil && !ok { 32 | return fmt.Errorf("field owner in TestObject: required") 33 | } 34 | type Plain TestObject 35 | var plain Plain 36 | if err := json.Unmarshal(value, &plain); err != nil { 37 | return err 38 | } 39 | *j = TestObject(plain) 40 | return nil 41 | } 42 | 43 | // UnmarshalYAML implements yaml.Unmarshaler. 44 | func (j *TestObject) UnmarshalYAML(value *yaml.Node) error { 45 | var raw map[string]interface{} 46 | if err := value.Decode(&raw); err != nil { 47 | return err 48 | } 49 | if _, ok := raw["name"]; raw != nil && !ok { 50 | return fmt.Errorf("field name in TestObject: required") 51 | } 52 | if _, ok := raw["owner"]; raw != nil && !ok { 53 | return fmt.Errorf("field owner in TestObject: required") 54 | } 55 | type Plain TestObject 56 | var plain Plain 57 | if err := value.Decode(&plain); err != nil { 58 | return err 59 | } 60 | *j = TestObject(plain) 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /tests/data/regressions/issue32/issue32.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "$ref": "#/definitions/TestObject", 4 | "definitions": { 5 | "TestObject": { 6 | "required": [ 7 | "owner", 8 | "name" 9 | ], 10 | "properties": { 11 | "owner": { 12 | "type": "string" 13 | }, 14 | "name": { 15 | "type": "string" 16 | }, 17 | "config": { 18 | "patternProperties": { 19 | ".*": { 20 | "additionalProperties": true 21 | } 22 | }, 23 | "type": "object" 24 | } 25 | }, 26 | "additionalProperties": false, 27 | "type": "object" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/data/regressions/issue378/issue378.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | import "regexp" 9 | 10 | type Issue378 struct { 11 | // An escaped character that would otherwise be wrongly used 12 | Memory *string `json:"memory,omitempty" yaml:"memory,omitempty" mapstructure:"memory,omitempty"` 13 | } 14 | 15 | // UnmarshalJSON implements json.Unmarshaler. 16 | func (j *Issue378) UnmarshalJSON(value []byte) error { 17 | type Plain Issue378 18 | var plain Plain 19 | if err := json.Unmarshal(value, &plain); err != nil { 20 | return err 21 | } 22 | if plain.Memory != nil { 23 | if matched, _ := regexp.MatchString(`^\d+([tgmk]b)?$`, string(*plain.Memory)); !matched { 24 | return fmt.Errorf("field %s pattern match: must match %s", "Memory", `^\d+([tgmk]b)?$`) 25 | } 26 | } 27 | *j = Issue378(plain) 28 | return nil 29 | } 30 | 31 | // UnmarshalYAML implements yaml.Unmarshaler. 32 | func (j *Issue378) UnmarshalYAML(value *yaml.Node) error { 33 | type Plain Issue378 34 | var plain Plain 35 | if err := value.Decode(&plain); err != nil { 36 | return err 37 | } 38 | if plain.Memory != nil { 39 | if matched, _ := regexp.MatchString(`^\d+([tgmk]b)?$`, string(*plain.Memory)); !matched { 40 | return fmt.Errorf("field %s pattern match: must match %s", "Memory", `^\d+([tgmk]b)?$`) 41 | } 42 | } 43 | *j = Issue378(plain) 44 | return nil 45 | } 46 | -------------------------------------------------------------------------------- /tests/data/regressions/issue378/issue378.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "properties": { 5 | "memory": { 6 | "type": "string", 7 | "pattern": "^\\d+([tgmk]b)?$", 8 | "description": "An escaped character that would otherwise be wrongly used" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/data/regressions/issue51/issue51.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Issue51 struct { 6 | // Name corresponds to the JSON schema field "name". 7 | Name *string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 8 | 9 | AdditionalProperties interface{} `mapstructure:",remain"` 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/regressions/issue51/issue51.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "additionalProperties": true, 5 | "properties": { 6 | "name": { 7 | "type": "string" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/schemaExtensions/nillable/nillability.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Nillability struct { 6 | // Name corresponds to the JSON schema field "name". 7 | Name map[bool]string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/schemaExtensions/nillable/nillability.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string", 7 | "goJSONSchema": { 8 | "nillable": true, 9 | "type": "map[bool]string" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/data/schemaExtensions/nonNillable/nillability.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type Nillability struct { 6 | // Name corresponds to the JSON schema field "name". 7 | Name *map[bool]string `json:"name,omitempty" yaml:"name,omitempty" mapstructure:"name,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/schemaExtensions/nonNillable/nillability.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string", 7 | "goJSONSchema": { 8 | "nillable": false, 9 | "type": "map[bool]string" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/data/validation/description/description.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | // A simple schema. 6 | type Description struct { 7 | // MyDescriptionlessField corresponds to the JSON schema field 8 | // "myDescriptionlessField". 9 | MyDescriptionlessField *string `json:"myDescriptionlessField,omitempty" yaml:"myDescriptionlessField,omitempty" mapstructure:"myDescriptionlessField,omitempty"` 10 | 11 | // A string field. 12 | MyField *string `json:"myField,omitempty" yaml:"myField,omitempty" mapstructure:"myField,omitempty"` 13 | } 14 | -------------------------------------------------------------------------------- /tests/data/validation/description/description.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/description", 4 | "description": "A simple schema.", 5 | "type": "object", 6 | "properties": { 7 | "myField": { 8 | "type": "string", 9 | "description": "A string field." 10 | }, 11 | "myDescriptionlessField": { 12 | "type": "string" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/data/validation/enum/enum.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/enum", 4 | "type": "object", 5 | "properties": { 6 | "myStringUntypedEnum": { 7 | "enum": [ 8 | "red", 9 | "blue", 10 | "green" 11 | ] 12 | }, 13 | "myNumberUntypedEnum": { 14 | "enum": [ 15 | 1, 16 | 2, 17 | 3 18 | ] 19 | }, 20 | "myBooleanUntypedEnum": { 21 | "enum": [ 22 | true, 23 | false 24 | ] 25 | }, 26 | "myNullUntypedEnum": { 27 | "enum": [ 28 | null 29 | ] 30 | }, 31 | "myMixedUntypedEnum": { 32 | "enum": [ 33 | "red", 34 | 1, 35 | true, 36 | null 37 | ] 38 | }, 39 | "myStringTypedEnum": { 40 | "type": "string", 41 | "enum": [ 42 | "red", 43 | "blue", 44 | "green" 45 | ] 46 | }, 47 | "myNumberTypedEnum": { 48 | "type": "number", 49 | "enum": [ 50 | 1, 51 | 2, 52 | 3 53 | ] 54 | }, 55 | "myIntegerTypedEnum": { 56 | "type": "integer", 57 | "enum": [ 58 | 1, 59 | 2, 60 | 3 61 | ] 62 | }, 63 | "myBooleanTypedEnum": { 64 | "type": "boolean", 65 | "enum": [ 66 | true, 67 | false 68 | ] 69 | }, 70 | "myNullTypedEnum": { 71 | "type": "null", 72 | "enum": [ 73 | null 74 | ] 75 | }, 76 | "myMixedTypeEnum": { 77 | "type": [ 78 | "string", 79 | "number" 80 | ], 81 | "enum": [ 82 | 42, 83 | "smurf" 84 | ] 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tests/data/validation/exclusiveMaximum/exclusiveMaximum.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/exclusiveMaximum", 4 | "type": "object", 5 | "properties": { 6 | "myNumber": { 7 | "type": "number", 8 | "exclusiveMaximum": 1.2 9 | }, 10 | "myInteger": { 11 | "type": "integer", 12 | "exclusiveMaximum": 2 13 | }, 14 | "myNullableNumber": { 15 | "type": "number", 16 | "exclusiveMaximum": 1.2 17 | }, 18 | "myNullableInteger": { 19 | "type": "integer", 20 | "exclusiveMaximum": 2 21 | } 22 | }, 23 | "required": [ 24 | "myNumber", 25 | "myInteger" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/data/validation/exclusiveMaximum/exclusiveMaximumOld.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/exclusiveMaximum", 4 | "type": "object", 5 | "properties": { 6 | "myNumber": { 7 | "type": "number", 8 | "maximum": 1.2, 9 | "exclusiveMaximum": true 10 | }, 11 | "myInteger": { 12 | "type": "integer", 13 | "maximum": 2, 14 | "exclusiveMaximum": true 15 | }, 16 | "myNullableNumber": { 17 | "maximum": 1.2, 18 | "exclusiveMaximum": true 19 | }, 20 | "myNullableInteger": { 21 | "type": "integer", 22 | "maximum": 2, 23 | "exclusiveMaximum": true 24 | } 25 | }, 26 | "required": [ 27 | "myNumber", 28 | "myInteger" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tests/data/validation/exclusiveMinimum/exclusiveMinimum.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "id": "https://example.com/exclusiveMinimum", 4 | "type": "object", 5 | "properties": { 6 | "myNumber": { 7 | "type": "number", 8 | "exclusiveMinimum": 1.2 9 | }, 10 | "myInteger": { 11 | "type": "integer", 12 | "exclusiveMinimum": 2 13 | }, 14 | "myNullableNumber": { 15 | "type": "number", 16 | "exclusiveMinimum": 1.2 17 | }, 18 | "myNullableInteger": { 19 | "type": "integer", 20 | "exclusiveMinimum": 2 21 | } 22 | }, 23 | "required": [ 24 | "myNumber", 25 | "myInteger" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/data/validation/exclusiveMinimum/exclusiveMinimumOld.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/exclusiveMinimum", 4 | "type": "object", 5 | "properties": { 6 | "myNumber": { 7 | "type": "number", 8 | "minimum": 1.2, 9 | "exclusiveMinimum": true 10 | }, 11 | "myInteger": { 12 | "type": "integer", 13 | "minimum": 2, 14 | "exclusiveMinimum": true 15 | }, 16 | "myNullableNumber": { 17 | "minimum": 1.2, 18 | "exclusiveMinimum": true 19 | }, 20 | "myNullableInteger": { 21 | "type": "integer", 22 | "minimum": 2, 23 | "exclusiveMinimum": true 24 | } 25 | }, 26 | "required": [ 27 | "myNumber", 28 | "myInteger" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tests/data/validation/maxItems/maxItems.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type MaxItems struct { 10 | // MyNestedArray corresponds to the JSON schema field "myNestedArray". 11 | MyNestedArray [][]interface{} `json:"myNestedArray,omitempty" yaml:"myNestedArray,omitempty" mapstructure:"myNestedArray,omitempty"` 12 | 13 | // MyStringArray corresponds to the JSON schema field "myStringArray". 14 | MyStringArray []string `json:"myStringArray,omitempty" yaml:"myStringArray,omitempty" mapstructure:"myStringArray,omitempty"` 15 | } 16 | 17 | // UnmarshalJSON implements json.Unmarshaler. 18 | func (j *MaxItems) UnmarshalJSON(value []byte) error { 19 | type Plain MaxItems 20 | var plain Plain 21 | if err := json.Unmarshal(value, &plain); err != nil { 22 | return err 23 | } 24 | if len(plain.MyNestedArray) > 5 { 25 | return fmt.Errorf("field %s length: must be <= %d", "myNestedArray", 5) 26 | } 27 | for i1 := range plain.MyNestedArray { 28 | if len(plain.MyNestedArray[i1]) > 5 { 29 | return fmt.Errorf("field %s length: must be <= %d", fmt.Sprintf("myNestedArray[%d]", i1), 5) 30 | } 31 | } 32 | if len(plain.MyStringArray) > 5 { 33 | return fmt.Errorf("field %s length: must be <= %d", "myStringArray", 5) 34 | } 35 | *j = MaxItems(plain) 36 | return nil 37 | } 38 | 39 | // UnmarshalYAML implements yaml.Unmarshaler. 40 | func (j *MaxItems) UnmarshalYAML(value *yaml.Node) error { 41 | type Plain MaxItems 42 | var plain Plain 43 | if err := value.Decode(&plain); err != nil { 44 | return err 45 | } 46 | if len(plain.MyNestedArray) > 5 { 47 | return fmt.Errorf("field %s length: must be <= %d", "myNestedArray", 5) 48 | } 49 | for i1 := range plain.MyNestedArray { 50 | if len(plain.MyNestedArray[i1]) > 5 { 51 | return fmt.Errorf("field %s length: must be <= %d", fmt.Sprintf("myNestedArray[%d]", i1), 5) 52 | } 53 | } 54 | if len(plain.MyStringArray) > 5 { 55 | return fmt.Errorf("field %s length: must be <= %d", "myStringArray", 5) 56 | } 57 | *j = MaxItems(plain) 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /tests/data/validation/maxItems/maxItems.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myStringArray": { 7 | "type": "array", 8 | "items": { 9 | "type": "string" 10 | }, 11 | "maxItems": 5 12 | }, 13 | "myNestedArray": { 14 | "type": "array", 15 | "items": { 16 | "type": "array", 17 | "maxItems": 3 18 | }, 19 | "maxItems": 5 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/validation/maxLength/maxLength.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type MaxLength struct { 10 | // MyNullableString corresponds to the JSON schema field "myNullableString". 11 | MyNullableString *string `json:"myNullableString,omitempty" yaml:"myNullableString,omitempty" mapstructure:"myNullableString,omitempty"` 12 | 13 | // MyString corresponds to the JSON schema field "myString". 14 | MyString string `json:"myString" yaml:"myString" mapstructure:"myString"` 15 | } 16 | 17 | // UnmarshalJSON implements json.Unmarshaler. 18 | func (j *MaxLength) UnmarshalJSON(value []byte) error { 19 | var raw map[string]interface{} 20 | if err := json.Unmarshal(value, &raw); err != nil { 21 | return err 22 | } 23 | if _, ok := raw["myString"]; raw != nil && !ok { 24 | return fmt.Errorf("field myString in MaxLength: required") 25 | } 26 | type Plain MaxLength 27 | var plain Plain 28 | if err := json.Unmarshal(value, &plain); err != nil { 29 | return err 30 | } 31 | if plain.MyNullableString != nil && len(*plain.MyNullableString) > 10 { 32 | return fmt.Errorf("field %s length: must be <= %d", "myNullableString", 10) 33 | } 34 | if len(plain.MyString) > 5 { 35 | return fmt.Errorf("field %s length: must be <= %d", "myString", 5) 36 | } 37 | *j = MaxLength(plain) 38 | return nil 39 | } 40 | 41 | // UnmarshalYAML implements yaml.Unmarshaler. 42 | func (j *MaxLength) UnmarshalYAML(value *yaml.Node) error { 43 | var raw map[string]interface{} 44 | if err := value.Decode(&raw); err != nil { 45 | return err 46 | } 47 | if _, ok := raw["myString"]; raw != nil && !ok { 48 | return fmt.Errorf("field myString in MaxLength: required") 49 | } 50 | type Plain MaxLength 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if plain.MyNullableString != nil && len(*plain.MyNullableString) > 10 { 56 | return fmt.Errorf("field %s length: must be <= %d", "myNullableString", 10) 57 | } 58 | if len(plain.MyString) > 5 { 59 | return fmt.Errorf("field %s length: must be <= %d", "myString", 5) 60 | } 61 | *j = MaxLength(plain) 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /tests/data/validation/maxLength/maxLength.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myString": { 7 | "type": "string", 8 | "maxLength": 5 9 | }, 10 | "myNullableString": { 11 | "type": "string", 12 | "maxLength": 10 13 | } 14 | }, 15 | "required": [ 16 | "myString" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/data/validation/maximum/maximum.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "type": "object", 4 | "properties": { 5 | "myNumber": { 6 | "type": "number", 7 | "maximum": 1.2 8 | }, 9 | "myInteger": { 10 | "type": "integer", 11 | "maximum": 2 12 | }, 13 | "myNullableNumber": { 14 | "type": "number", 15 | "maximum": 1.2 16 | }, 17 | "myNullableInteger": { 18 | "type": "integer", 19 | "maximum": 2 20 | } 21 | }, 22 | "required": [ 23 | "myNumber", 24 | "myInteger" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/data/validation/minItems/minItems.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type MinItems struct { 10 | // MyNestedArray corresponds to the JSON schema field "myNestedArray". 11 | MyNestedArray [][]interface{} `json:"myNestedArray,omitempty" yaml:"myNestedArray,omitempty" mapstructure:"myNestedArray,omitempty"` 12 | 13 | // MyStringArray corresponds to the JSON schema field "myStringArray". 14 | MyStringArray []string `json:"myStringArray,omitempty" yaml:"myStringArray,omitempty" mapstructure:"myStringArray,omitempty"` 15 | } 16 | 17 | // UnmarshalJSON implements json.Unmarshaler. 18 | func (j *MinItems) UnmarshalJSON(value []byte) error { 19 | type Plain MinItems 20 | var plain Plain 21 | if err := json.Unmarshal(value, &plain); err != nil { 22 | return err 23 | } 24 | if plain.MyNestedArray != nil && len(plain.MyNestedArray) < 5 { 25 | return fmt.Errorf("field %s length: must be >= %d", "myNestedArray", 5) 26 | } 27 | for i1 := range plain.MyNestedArray { 28 | if plain.MyNestedArray[i1] != nil && len(plain.MyNestedArray[i1]) < 5 { 29 | return fmt.Errorf("field %s length: must be >= %d", fmt.Sprintf("myNestedArray[%d]", i1), 5) 30 | } 31 | } 32 | if plain.MyStringArray != nil && len(plain.MyStringArray) < 5 { 33 | return fmt.Errorf("field %s length: must be >= %d", "myStringArray", 5) 34 | } 35 | *j = MinItems(plain) 36 | return nil 37 | } 38 | 39 | // UnmarshalYAML implements yaml.Unmarshaler. 40 | func (j *MinItems) UnmarshalYAML(value *yaml.Node) error { 41 | type Plain MinItems 42 | var plain Plain 43 | if err := value.Decode(&plain); err != nil { 44 | return err 45 | } 46 | if plain.MyNestedArray != nil && len(plain.MyNestedArray) < 5 { 47 | return fmt.Errorf("field %s length: must be >= %d", "myNestedArray", 5) 48 | } 49 | for i1 := range plain.MyNestedArray { 50 | if plain.MyNestedArray[i1] != nil && len(plain.MyNestedArray[i1]) < 5 { 51 | return fmt.Errorf("field %s length: must be >= %d", fmt.Sprintf("myNestedArray[%d]", i1), 5) 52 | } 53 | } 54 | if plain.MyStringArray != nil && len(plain.MyStringArray) < 5 { 55 | return fmt.Errorf("field %s length: must be >= %d", "myStringArray", 5) 56 | } 57 | *j = MinItems(plain) 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /tests/data/validation/minItems/minItems.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myStringArray": { 7 | "type": "array", 8 | "items": { 9 | "type": "string" 10 | }, 11 | "minItems": 5 12 | }, 13 | "myNestedArray": { 14 | "type": "array", 15 | "items": { 16 | "type": "array", 17 | "minItems": 3 18 | }, 19 | "minItems": 5 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/validation/minLength/minLength.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type MinLength struct { 10 | // MyNullableString corresponds to the JSON schema field "myNullableString". 11 | MyNullableString *string `json:"myNullableString,omitempty" yaml:"myNullableString,omitempty" mapstructure:"myNullableString,omitempty"` 12 | 13 | // MyString corresponds to the JSON schema field "myString". 14 | MyString string `json:"myString" yaml:"myString" mapstructure:"myString"` 15 | } 16 | 17 | // UnmarshalJSON implements json.Unmarshaler. 18 | func (j *MinLength) UnmarshalJSON(value []byte) error { 19 | var raw map[string]interface{} 20 | if err := json.Unmarshal(value, &raw); err != nil { 21 | return err 22 | } 23 | if _, ok := raw["myString"]; raw != nil && !ok { 24 | return fmt.Errorf("field myString in MinLength: required") 25 | } 26 | type Plain MinLength 27 | var plain Plain 28 | if err := json.Unmarshal(value, &plain); err != nil { 29 | return err 30 | } 31 | if plain.MyNullableString != nil && len(*plain.MyNullableString) < 10 { 32 | return fmt.Errorf("field %s length: must be >= %d", "myNullableString", 10) 33 | } 34 | if len(plain.MyString) < 5 { 35 | return fmt.Errorf("field %s length: must be >= %d", "myString", 5) 36 | } 37 | *j = MinLength(plain) 38 | return nil 39 | } 40 | 41 | // UnmarshalYAML implements yaml.Unmarshaler. 42 | func (j *MinLength) UnmarshalYAML(value *yaml.Node) error { 43 | var raw map[string]interface{} 44 | if err := value.Decode(&raw); err != nil { 45 | return err 46 | } 47 | if _, ok := raw["myString"]; raw != nil && !ok { 48 | return fmt.Errorf("field myString in MinLength: required") 49 | } 50 | type Plain MinLength 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | if plain.MyNullableString != nil && len(*plain.MyNullableString) < 10 { 56 | return fmt.Errorf("field %s length: must be >= %d", "myNullableString", 10) 57 | } 58 | if len(plain.MyString) < 5 { 59 | return fmt.Errorf("field %s length: must be >= %d", "myString", 5) 60 | } 61 | *j = MinLength(plain) 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /tests/data/validation/minLength/minLength.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myString": { 7 | "type": "string", 8 | "minLength": 5 9 | }, 10 | "myNullableString": { 11 | "type": "string", 12 | "minLength": 10 13 | } 14 | }, 15 | "required": [ 16 | "myString" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/data/validation/minMaxItems/minMaxItems.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myStringArray": { 7 | "type": "array", 8 | "items": { 9 | "type": "string" 10 | }, 11 | "minItems": 1, 12 | "maxItems": 3 13 | }, 14 | "myNestedArray": { 15 | "type": "array", 16 | "items": { 17 | "type": "array", 18 | "minItems": 1, 19 | "maxItems": 3 20 | }, 21 | "minItems": 1, 22 | "maxItems": 5 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/data/validation/minimum/minimum.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/minimum", 4 | "type": "object", 5 | "properties": { 6 | "myNumber": { 7 | "type": "number", 8 | "minimum": 1.2 9 | }, 10 | "myInteger": { 11 | "type": "integer", 12 | "minimum": 2 13 | }, 14 | "myNullableNumber": { 15 | "type": "number", 16 | "minimum": 1.2 17 | }, 18 | "myNullableInteger": { 19 | "type": "integer", 20 | "minimum": 2 21 | } 22 | }, 23 | "required": [ 24 | "myNumber", 25 | "myInteger" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/data/validation/multipleOf/multipleOf.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/multipleOf", 4 | "type": "object", 5 | "properties": { 6 | "myNumber": { 7 | "type": "number", 8 | "multipleOf": 0.2 9 | }, 10 | "myInteger": { 11 | "type": "integer", 12 | "multipleOf": 2 13 | }, 14 | "myNullableNumber": { 15 | "type": "number", 16 | "multipleOf": 0.2 17 | }, 18 | "myNullableInteger": { 19 | "type": "integer", 20 | "multipleOf": 2 21 | } 22 | }, 23 | "required": [ 24 | "myNumber", 25 | "myInteger" 26 | ] 27 | } -------------------------------------------------------------------------------- /tests/data/validation/pattern/pattern.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myString": { 7 | "type": "string", 8 | "pattern": "^0x[0-9a-f]{10}\\.$" 9 | }, 10 | "myNullableString": { 11 | "type": "string", 12 | "pattern": "^0x[0-9a-f]{10}$" 13 | }, 14 | "myEscapedString": { 15 | "type": "string", 16 | "pattern": "^\\$\\{\\{(.|[\r\n])*\\}\\}$" 17 | } 18 | }, 19 | "required": [ 20 | "myString" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/validation/primitive_defs/primitive_defs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "$defs": { 6 | "minStr": { 7 | "type": "string", 8 | "minLength": 5 9 | } 10 | }, 11 | "properties": { 12 | "myString": { 13 | "$ref": "#/$defs/minStr" 14 | }, 15 | "myNullableString": { 16 | "$ref": "#/$defs/minStr" 17 | } 18 | }, 19 | "required": [ 20 | "myString" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/data/validation/readOnly/readOnly.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type ReadOnly struct { 10 | // MyReadOnlyString corresponds to the JSON schema field "myReadOnlyString". 11 | MyReadOnlyString *string `json:"myReadOnlyString,omitempty" yaml:"myReadOnlyString,omitempty" mapstructure:"myReadOnlyString,omitempty"` 12 | 13 | // MyString corresponds to the JSON schema field "myString". 14 | MyString string `json:"myString" yaml:"myString" mapstructure:"myString"` 15 | } 16 | 17 | // UnmarshalJSON implements json.Unmarshaler. 18 | func (j *ReadOnly) UnmarshalJSON(value []byte) error { 19 | var raw map[string]interface{} 20 | if err := json.Unmarshal(value, &raw); err != nil { 21 | return err 22 | } 23 | if _, ok := raw["myString"]; raw != nil && !ok { 24 | return fmt.Errorf("field myString in ReadOnly: required") 25 | } 26 | if _, ok := raw["myReadOnlyString"]; raw != nil && ok { 27 | return fmt.Errorf("field myReadOnlyString in ReadOnly: read only") 28 | } 29 | type Plain ReadOnly 30 | var plain Plain 31 | if err := json.Unmarshal(value, &plain); err != nil { 32 | return err 33 | } 34 | *j = ReadOnly(plain) 35 | return nil 36 | } 37 | 38 | // UnmarshalYAML implements yaml.Unmarshaler. 39 | func (j *ReadOnly) UnmarshalYAML(value *yaml.Node) error { 40 | var raw map[string]interface{} 41 | if err := value.Decode(&raw); err != nil { 42 | return err 43 | } 44 | if _, ok := raw["myString"]; raw != nil && !ok { 45 | return fmt.Errorf("field myString in ReadOnly: required") 46 | } 47 | if _, ok := raw["myReadOnlyString"]; raw != nil && ok { 48 | return fmt.Errorf("field myReadOnlyString in ReadOnly: read only") 49 | } 50 | type Plain ReadOnly 51 | var plain Plain 52 | if err := value.Decode(&plain); err != nil { 53 | return err 54 | } 55 | *j = ReadOnly(plain) 56 | return nil 57 | } 58 | -------------------------------------------------------------------------------- /tests/data/validation/readOnly/readOnly.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myReadOnlyString": { 7 | "type": "string", 8 | "readOnly": true 9 | }, 10 | "myString": { 11 | "type": "string" 12 | } 13 | }, 14 | "required": [ "myString" ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/data/validation/readOnlyAndRequired/readOnlyAndRequired.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type ReadOnlyAndRequired struct { 10 | // MyReadOnlyRequiredString corresponds to the JSON schema field 11 | // "myReadOnlyRequiredString". 12 | MyReadOnlyRequiredString string `json:"myReadOnlyRequiredString" yaml:"myReadOnlyRequiredString" mapstructure:"myReadOnlyRequiredString"` 13 | } 14 | 15 | // UnmarshalJSON implements json.Unmarshaler. 16 | func (j *ReadOnlyAndRequired) UnmarshalJSON(value []byte) error { 17 | var raw map[string]interface{} 18 | if err := json.Unmarshal(value, &raw); err != nil { 19 | return err 20 | } 21 | if _, ok := raw["myReadOnlyRequiredString"]; raw != nil && !ok { 22 | return fmt.Errorf("field myReadOnlyRequiredString in ReadOnlyAndRequired: required") 23 | } 24 | if _, ok := raw["myReadOnlyRequiredString"]; raw != nil && ok { 25 | return fmt.Errorf("field myReadOnlyRequiredString in ReadOnlyAndRequired: read only") 26 | } 27 | type Plain ReadOnlyAndRequired 28 | var plain Plain 29 | if err := json.Unmarshal(value, &plain); err != nil { 30 | return err 31 | } 32 | *j = ReadOnlyAndRequired(plain) 33 | return nil 34 | } 35 | 36 | // UnmarshalYAML implements yaml.Unmarshaler. 37 | func (j *ReadOnlyAndRequired) UnmarshalYAML(value *yaml.Node) error { 38 | var raw map[string]interface{} 39 | if err := value.Decode(&raw); err != nil { 40 | return err 41 | } 42 | if _, ok := raw["myReadOnlyRequiredString"]; raw != nil && !ok { 43 | return fmt.Errorf("field myReadOnlyRequiredString in ReadOnlyAndRequired: required") 44 | } 45 | if _, ok := raw["myReadOnlyRequiredString"]; raw != nil && ok { 46 | return fmt.Errorf("field myReadOnlyRequiredString in ReadOnlyAndRequired: read only") 47 | } 48 | type Plain ReadOnlyAndRequired 49 | var plain Plain 50 | if err := value.Decode(&plain); err != nil { 51 | return err 52 | } 53 | *j = ReadOnlyAndRequired(plain) 54 | return nil 55 | } 56 | -------------------------------------------------------------------------------- /tests/data/validation/readOnlyAndRequired/readOnlyAndRequired.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myReadOnlyRequiredString": { 7 | "type": "string", 8 | "readOnly": true 9 | } 10 | }, 11 | "required": [ "myReadOnlyRequiredString" ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/data/validation/requiredFields/requiredFields.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/requiredFields", 4 | "type": "object", 5 | "required": [ 6 | "myString", 7 | "myNumber", 8 | "myBoolean", 9 | "myNull", 10 | "myObject", 11 | "myStringArray", 12 | "myNumberArray", 13 | "myBooleanArray", 14 | "myNullArray", 15 | "myObjectArray" 16 | ], 17 | "properties": { 18 | "myString": { 19 | "type": "string" 20 | }, 21 | "myNumber": { 22 | "type": "number" 23 | }, 24 | "myInteger": { 25 | "type": "integer" 26 | }, 27 | "myBoolean": { 28 | "type": "boolean" 29 | }, 30 | "myNull": { 31 | "type": "null" 32 | }, 33 | "myObject": { 34 | "type": "object", 35 | "required": [ 36 | "myNestedObjectString" 37 | ], 38 | "properties": { 39 | "myNestedObjectString": { 40 | "type": "string" 41 | } 42 | } 43 | }, 44 | "myStringArray": { 45 | "type": "array", 46 | "items": { 47 | "type": "string" 48 | } 49 | }, 50 | "myNumberArray": { 51 | "type": "array", 52 | "items": { 53 | "type": "number" 54 | } 55 | }, 56 | "myIntegerArray": { 57 | "type": "array", 58 | "items": { 59 | "type": "integer" 60 | } 61 | }, 62 | "myBooleanArray": { 63 | "type": "array", 64 | "items": { 65 | "type": "boolean" 66 | } 67 | }, 68 | "myNullArray": { 69 | "type": "array", 70 | "items": { 71 | "type": "null" 72 | } 73 | }, 74 | "myObjectArray": { 75 | "type": "array", 76 | "items": { 77 | "type": "object", 78 | "required": [ 79 | "myNestedObjectString" 80 | ], 81 | "properties": { 82 | "myNestedObjectString": { 83 | "type": "string" 84 | } 85 | } 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tests/data/validation/requiredFields/requiredNullable.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/requiredNullable", 4 | "type": "object", 5 | "properties": { 6 | "myNullableString": { 7 | "type": [ 8 | "string", 9 | "null" 10 | ] 11 | }, 12 | "myNullableStringArray": { 13 | "type": [ 14 | "array", 15 | "null" 16 | ], 17 | "items": { 18 | "type": "string" 19 | } 20 | }, 21 | "myNullableObject": { 22 | "type": [ 23 | "object", 24 | "null" 25 | ], 26 | "properties": { 27 | "myNestedProp": { 28 | "type": "string" 29 | } 30 | }, 31 | "required": [ 32 | "myNestedProp" 33 | ] 34 | } 35 | }, 36 | "required": [ 37 | "myNullableString", 38 | "myNullableStringArray", 39 | "myNullableObject" 40 | ] 41 | } -------------------------------------------------------------------------------- /tests/data/validation/typeMultiple/typeMultiple.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type TypeMultiple struct { 6 | // All corresponds to the JSON schema field "all". 7 | All interface{} `json:"all,omitempty" yaml:"all,omitempty" mapstructure:"all,omitempty"` 8 | 9 | // AllPrimitives corresponds to the JSON schema field "allPrimitives". 10 | AllPrimitives interface{} `json:"allPrimitives,omitempty" yaml:"allPrimitives,omitempty" mapstructure:"allPrimitives,omitempty"` 11 | 12 | // ArrayOfAll corresponds to the JSON schema field "arrayOfAll". 13 | ArrayOfAll []interface{} `json:"arrayOfAll,omitempty" yaml:"arrayOfAll,omitempty" mapstructure:"arrayOfAll,omitempty"` 14 | 15 | // ArrayOfAllPrimitives corresponds to the JSON schema field 16 | // "arrayOfAllPrimitives". 17 | ArrayOfAllPrimitives []interface{} `json:"arrayOfAllPrimitives,omitempty" yaml:"arrayOfAllPrimitives,omitempty" mapstructure:"arrayOfAllPrimitives,omitempty"` 18 | 19 | // OnlyTwoOptions corresponds to the JSON schema field "onlyTwoOptions". 20 | OnlyTwoOptions interface{} `json:"onlyTwoOptions,omitempty" yaml:"onlyTwoOptions,omitempty" mapstructure:"onlyTwoOptions,omitempty"` 21 | } 22 | -------------------------------------------------------------------------------- /tests/data/validation/typeMultiple/typeMultiple.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/enum", 4 | "type": "object", 5 | "properties": { 6 | "all": { 7 | "type": [ 8 | "number", 9 | "string", 10 | "boolean", 11 | "null", 12 | "object", 13 | "array" 14 | ] 15 | }, 16 | "allPrimitives": { 17 | "type": [ 18 | "number", 19 | "string", 20 | "boolean", 21 | "null" 22 | ] 23 | }, 24 | "arrayOfAll": { 25 | "type": "array", 26 | "items": { 27 | "type": [ 28 | "number", 29 | "string", 30 | "boolean", 31 | "null", 32 | "object", 33 | "array" 34 | ] 35 | } 36 | }, 37 | "arrayOfAllPrimitives": { 38 | "type": "array", 39 | "items": { 40 | "type": [ 41 | "number", 42 | "string", 43 | "boolean", 44 | "null" 45 | ] 46 | } 47 | }, 48 | "onlyTwoOptions": { 49 | "type": [ 50 | "number", 51 | "boolean" 52 | ] 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/data/validation/typedDefault/typedDefault.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import yaml "gopkg.in/yaml.v3" 7 | 8 | type TypedDefault struct { 9 | // TopLevelDomains corresponds to the JSON schema field "topLevelDomains". 10 | TopLevelDomains []string `json:"topLevelDomains,omitempty" yaml:"topLevelDomains,omitempty" mapstructure:"topLevelDomains,omitempty"` 11 | } 12 | 13 | // UnmarshalJSON implements json.Unmarshaler. 14 | func (j *TypedDefault) UnmarshalJSON(value []byte) error { 15 | var raw map[string]interface{} 16 | if err := json.Unmarshal(value, &raw); err != nil { 17 | return err 18 | } 19 | type Plain TypedDefault 20 | var plain Plain 21 | if err := json.Unmarshal(value, &plain); err != nil { 22 | return err 23 | } 24 | if v, ok := raw["topLevelDomains"]; !ok || v == nil { 25 | plain.TopLevelDomains = []string{ 26 | ".com", 27 | ".org", 28 | ".info", 29 | ".gov", 30 | } 31 | } 32 | *j = TypedDefault(plain) 33 | return nil 34 | } 35 | 36 | // UnmarshalYAML implements yaml.Unmarshaler. 37 | func (j *TypedDefault) UnmarshalYAML(value *yaml.Node) error { 38 | var raw map[string]interface{} 39 | if err := value.Decode(&raw); err != nil { 40 | return err 41 | } 42 | type Plain TypedDefault 43 | var plain Plain 44 | if err := value.Decode(&plain); err != nil { 45 | return err 46 | } 47 | if v, ok := raw["topLevelDomains"]; !ok || v == nil { 48 | plain.TopLevelDomains = []string{ 49 | ".com", 50 | ".org", 51 | ".info", 52 | ".gov", 53 | } 54 | } 55 | *j = TypedDefault(plain) 56 | return nil 57 | } 58 | -------------------------------------------------------------------------------- /tests/data/validation/typedDefault/typedDefault.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/enum", 4 | "type": "object", 5 | "properties": { 6 | "topLevelDomains": { 7 | "type": "array", 8 | "items": { 9 | "type": "string" 10 | }, 11 | "default": [ 12 | ".com", 13 | ".org", 14 | ".info", 15 | ".gov" 16 | ] 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/data/validation/typedDefaultEmpty/typedDefaultEmpty.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import yaml "gopkg.in/yaml.v3" 7 | 8 | type TypedDefaultEmpty struct { 9 | // TopLevelDomains corresponds to the JSON schema field "topLevelDomains". 10 | TopLevelDomains []string `json:"topLevelDomains,omitempty" yaml:"topLevelDomains,omitempty" mapstructure:"topLevelDomains,omitempty"` 11 | } 12 | 13 | // UnmarshalJSON implements json.Unmarshaler. 14 | func (j *TypedDefaultEmpty) UnmarshalJSON(value []byte) error { 15 | var raw map[string]interface{} 16 | if err := json.Unmarshal(value, &raw); err != nil { 17 | return err 18 | } 19 | type Plain TypedDefaultEmpty 20 | var plain Plain 21 | if err := json.Unmarshal(value, &plain); err != nil { 22 | return err 23 | } 24 | if v, ok := raw["topLevelDomains"]; !ok || v == nil { 25 | plain.TopLevelDomains = []string{} 26 | } 27 | *j = TypedDefaultEmpty(plain) 28 | return nil 29 | } 30 | 31 | // UnmarshalYAML implements yaml.Unmarshaler. 32 | func (j *TypedDefaultEmpty) UnmarshalYAML(value *yaml.Node) error { 33 | var raw map[string]interface{} 34 | if err := value.Decode(&raw); err != nil { 35 | return err 36 | } 37 | type Plain TypedDefaultEmpty 38 | var plain Plain 39 | if err := value.Decode(&plain); err != nil { 40 | return err 41 | } 42 | if v, ok := raw["topLevelDomains"]; !ok || v == nil { 43 | plain.TopLevelDomains = []string{} 44 | } 45 | *j = TypedDefaultEmpty(plain) 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /tests/data/validation/typedDefaultEmpty/typedDefaultEmpty.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/enum", 4 | "type": "object", 5 | "properties": { 6 | "topLevelDomains": { 7 | "type": "array", 8 | "items": { 9 | "type": "string" 10 | }, 11 | "default": [] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/data/validation/typedDefaultEnums/typedDefaultEnums.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/enum", 4 | "type": "object", 5 | "properties": { 6 | "some": { 7 | "type": "string", 8 | "default": "random", 9 | "enum": [ 10 | "random", 11 | "other" 12 | ] 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/data/validationDisabled/readOnly/readOnlyNoValidation.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | import "encoding/json" 6 | import "fmt" 7 | import yaml "gopkg.in/yaml.v3" 8 | 9 | type ReadOnlyNoValidation struct { 10 | // MyReadOnlyString corresponds to the JSON schema field "myReadOnlyString". 11 | MyReadOnlyString *string `json:"myReadOnlyString,omitempty" yaml:"myReadOnlyString,omitempty" mapstructure:"myReadOnlyString,omitempty"` 12 | 13 | // MyString corresponds to the JSON schema field "myString". 14 | MyString string `json:"myString" yaml:"myString" mapstructure:"myString"` 15 | } 16 | 17 | // UnmarshalJSON implements json.Unmarshaler. 18 | func (j *ReadOnlyNoValidation) UnmarshalJSON(value []byte) error { 19 | var raw map[string]interface{} 20 | if err := json.Unmarshal(value, &raw); err != nil { 21 | return err 22 | } 23 | if _, ok := raw["myString"]; raw != nil && !ok { 24 | return fmt.Errorf("field myString in ReadOnlyNoValidation: required") 25 | } 26 | type Plain ReadOnlyNoValidation 27 | var plain Plain 28 | if err := json.Unmarshal(value, &plain); err != nil { 29 | return err 30 | } 31 | *j = ReadOnlyNoValidation(plain) 32 | return nil 33 | } 34 | 35 | // UnmarshalYAML implements yaml.Unmarshaler. 36 | func (j *ReadOnlyNoValidation) UnmarshalYAML(value *yaml.Node) error { 37 | var raw map[string]interface{} 38 | if err := value.Decode(&raw); err != nil { 39 | return err 40 | } 41 | if _, ok := raw["myString"]; raw != nil && !ok { 42 | return fmt.Errorf("field myString in ReadOnlyNoValidation: required") 43 | } 44 | type Plain ReadOnlyNoValidation 45 | var plain Plain 46 | if err := value.Decode(&plain); err != nil { 47 | return err 48 | } 49 | *j = ReadOnlyNoValidation(plain) 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /tests/data/validationDisabled/readOnly/readOnlyNoValidation.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "https://example.com/array", 4 | "type": "object", 5 | "properties": { 6 | "myReadOnlyString": { 7 | "type": "string", 8 | "readOnly": true 9 | }, 10 | "myString": { 11 | "type": "string" 12 | } 13 | }, 14 | "required": [ "myString" ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/data/yaml/yamlMultilineDescriptions/yamlMultilineDescriptions.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type YamlMultilineDescriptions struct { 6 | // I'm a multiline description in a literal block. Literal blocks, on the other 7 | // hand, 8 | // should have hard line breaks and may end in a line break, too. 9 | // 10 | // This may look funky when Go code is generated to a specific line width, though. 11 | // 12 | Bar *string `json:"bar,omitempty" yaml:"bar,omitempty" mapstructure:"bar,omitempty"` 13 | 14 | // I'm a multiline description in a folded block. 15 | // Folded blocks should not have hard line breaks after parsing. 16 | // They should also not end in a line break. 17 | // 18 | Foo *string `json:"foo,omitempty" yaml:"foo,omitempty" mapstructure:"foo,omitempty"` 19 | } 20 | -------------------------------------------------------------------------------- /tests/data/yaml/yamlMultilineDescriptions/yamlMultilineDescriptions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | $schema: http://json-schema.org/draft-04/schema# 3 | $id: https://example.com/yaml_multiline_description 4 | title: MyObject 5 | type: object 6 | properties: 7 | foo: 8 | description: | 9 | I'm a multiline description in a folded block. 10 | Folded blocks should not have hard line breaks after parsing. 11 | They should also not end in a line break. 12 | type: string 13 | bar: 14 | description: | 15 | I'm a multiline description in a literal block. Literal blocks, on the other hand, 16 | should have hard line breaks and may end in a line break, too. 17 | 18 | This may look funky when Go code is generated to a specific line width, though. 19 | type: string 20 | -------------------------------------------------------------------------------- /tests/data/yaml/yamlStructNameFromFile/yamlStructNameFromFile.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. 2 | 3 | package test 4 | 5 | type YamlStructNameFromFile struct { 6 | // Foo corresponds to the JSON schema field "foo". 7 | Foo *string `json:"foo,omitempty" yaml:"foo,omitempty" mapstructure:"foo,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/data/yaml/yamlStructNameFromFile/yamlStructNameFromFile.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # mySchema.yaml 3 | $schema: http://json-schema.org/draft-04/schema# 4 | $id: https://example.com/yaml_root_type_name 5 | type: object 6 | properties: 7 | foo: 8 | type: string 9 | -------------------------------------------------------------------------------- /tests/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/atombender/go-jsonschema/tests 2 | 3 | go 1.23.0 4 | 5 | replace ( 6 | github.com/atombender/go-jsonschema => ../ 7 | github.com/atombender/go-jsonschema/tests/helpers/other => ./helpers/other 8 | ) 9 | 10 | require ( 11 | github.com/atombender/go-jsonschema v0.20.0 12 | github.com/atombender/go-jsonschema/tests/helpers/other v0.0.0-20250601000041-458aecabb68c 13 | github.com/go-viper/mapstructure/v2 v2.2.1 14 | github.com/google/go-cmp v0.7.0 15 | github.com/stretchr/testify v1.10.0 16 | gopkg.in/yaml.v3 v3.0.1 17 | ) 18 | 19 | require ( 20 | dario.cat/mergo v1.0.2 // indirect 21 | github.com/davecgh/go-spew v1.1.1 // indirect 22 | github.com/goccy/go-yaml v1.18.0 // indirect 23 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 24 | github.com/pkg/errors v0.9.1 // indirect 25 | github.com/pmezard/go-difflib v1.0.0 // indirect 26 | github.com/sanity-io/litter v1.5.8 // indirect 27 | github.com/sosodev/duration v1.3.1 // indirect 28 | ) 29 | -------------------------------------------------------------------------------- /tests/helpers/checks.go: -------------------------------------------------------------------------------- 1 | package helpers 2 | 3 | import "testing" 4 | 5 | func CheckError(t *testing.T, wantErr, gotErr error) { 6 | t.Helper() 7 | 8 | if wantErr == nil && gotErr != nil { 9 | t.Errorf("got error %v, want nil", gotErr) 10 | 11 | return 12 | } 13 | 14 | if wantErr != nil && gotErr == nil { 15 | t.Errorf("got nil, want error %v", wantErr) 16 | 17 | return 18 | } 19 | 20 | if wantErr != nil && gotErr != nil && gotErr.Error() != wantErr.Error() { 21 | t.Errorf("got error %v, want %v", gotErr, wantErr) 22 | 23 | return 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/helpers/other/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/atombender/go-jsonschema/tests/example/other 2 | 3 | go 1.23.0 4 | -------------------------------------------------------------------------------- /tests/helpers/other/main.go: -------------------------------------------------------------------------------- 1 | package other 2 | 3 | func main() {} 4 | 5 | type Thing struct { 6 | Label string 7 | } 8 | -------------------------------------------------------------------------------- /tests/unmarshal_yaml_test.go: -------------------------------------------------------------------------------- 1 | package tests_test 2 | 3 | import ( 4 | "os" 5 | "reflect" 6 | "strings" 7 | "testing" 8 | 9 | yamlv3 "gopkg.in/yaml.v3" 10 | 11 | test "github.com/atombender/go-jsonschema/tests/data/extraImports/gopkgYAMLv3" 12 | ) 13 | 14 | func TestYamlV3Unmarshal(t *testing.T) { 15 | t.Parallel() 16 | 17 | data, err := os.ReadFile("./data/extraImports/gopkgYAMLv3/gopkgYAMLv3.yaml") 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | 22 | var conf test.GopkgYAMLv3 23 | 24 | if err := yamlv3.Unmarshal(data, &conf); err != nil { 25 | t.Fatal(err) 26 | } 27 | 28 | s := "example" 29 | n := 123.456 30 | i := 123 31 | b := true 32 | e := test.GopkgYAMLv3MyEnumX 33 | 34 | want := test.GopkgYAMLv3{ 35 | MyString: &s, 36 | MyNumber: &n, 37 | MyInteger: &i, 38 | MyBoolean: &b, 39 | MyNull: nil, 40 | MyEnum: &e, 41 | } 42 | 43 | if !reflect.DeepEqual(conf, want) { 44 | t.Errorf( 45 | "Unmarshalled data does not match expected\nWant: %s\nGot: %s", 46 | formatGopkgYAMLv3(want), 47 | formatGopkgYAMLv3(conf), 48 | ) 49 | } 50 | } 51 | 52 | func TestYamlV3UnmarshalInvalidEnum(t *testing.T) { 53 | t.Parallel() 54 | 55 | data, err := os.ReadFile("./data/extraImports/gopkgYAMLv3invalidEnum/gopkgYAMLv3invalidEnum.yaml") 56 | if err != nil { 57 | t.Fatal(err) 58 | } 59 | 60 | var conf test.GopkgYAMLv3 61 | 62 | err = yamlv3.Unmarshal(data, &conf) 63 | if err == nil { 64 | t.Fatal("Expected unmarshal error") 65 | } 66 | 67 | if !strings.Contains(err.Error(), "invalid value (expected one of") { 68 | t.Error("Expected unmarshal error to contain enum values") 69 | } 70 | } 71 | --------------------------------------------------------------------------------