@versionzero/schema 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +177 -0
- package/README.md +246 -0
- package/package.json +84 -0
- package/src/compilation/handler-compilation.js +28 -0
- package/src/compilation/metadata-compilation.js +35 -0
- package/src/compilation/schema-compilation.js +142 -0
- package/src/compilation/selection-compilation.js +84 -0
- package/src/compilation/union-compilation.js +510 -0
- package/src/compilation/values-compilation.js +35 -0
- package/src/compiled-schema.js +1709 -0
- package/src/constants.js +1 -0
- package/src/core-library/index.js +32 -0
- package/src/core-library/processors/aggregation-operators.js +75 -0
- package/src/core-library/processors/alpha-constraint.js +20 -0
- package/src/core-library/processors/alphanum-constraint.js +20 -0
- package/src/core-library/processors/array-operator.js +51 -0
- package/src/core-library/processors/assert-constraint.js +75 -0
- package/src/core-library/processors/base64-constraint.js +26 -0
- package/src/core-library/processors/camel-case-operator.js +24 -0
- package/src/core-library/processors/capitalize-operator.js +16 -0
- package/src/core-library/processors/cardnum-constraint.js +193 -0
- package/src/core-library/processors/ceil-operator.js +44 -0
- package/src/core-library/processors/collapse-operator.js +29 -0
- package/src/core-library/processors/compact-operator.js +34 -0
- package/src/core-library/processors/compile-operator.js +65 -0
- package/src/core-library/processors/concat-operator.js +51 -0
- package/src/core-library/processors/conditional-operators.js +301 -0
- package/src/core-library/processors/constant-case-operator.js +16 -0
- package/src/core-library/processors/data-size-operator.js +86 -0
- package/src/core-library/processors/date-object-operator.js +54 -0
- package/src/core-library/processors/date-operator.js +67 -0
- package/src/core-library/processors/date-range-constraint.js +76 -0
- package/src/core-library/processors/defined-constraint.js +30 -0
- package/src/core-library/processors/each-operator.js +57 -0
- package/src/core-library/processors/email-constraint.js +112 -0
- package/src/core-library/processors/entries-operator.js +25 -0
- package/src/core-library/processors/eq-constraint.js +37 -0
- package/src/core-library/processors/filter-operator.js +74 -0
- package/src/core-library/processors/find-schema-operator.js +45 -0
- package/src/core-library/processors/flatten-operator.js +40 -0
- package/src/core-library/processors/floor-operator.js +47 -0
- package/src/core-library/processors/get-operator.js +44 -0
- package/src/core-library/processors/group-by-operator.js +84 -0
- package/src/core-library/processors/has-prefix-constraint.js +37 -0
- package/src/core-library/processors/has-suffix-constraint.js +35 -0
- package/src/core-library/processors/hex-constraint.js +20 -0
- package/src/core-library/processors/hostname-constraint.js +22 -0
- package/src/core-library/processors/http-url-constraint.js +27 -0
- package/src/core-library/processors/in-constraint.js +66 -0
- package/src/core-library/processors/index-by-operator.js +98 -0
- package/src/core-library/processors/index.js +131 -0
- package/src/core-library/processors/input-operator.js +23 -0
- package/src/core-library/processors/instanceof-constraint.js +38 -0
- package/src/core-library/processors/integer-constraint.js +22 -0
- package/src/core-library/processors/invoke-operator.js +33 -0
- package/src/core-library/processors/ipv4-constraint.js +188 -0
- package/src/core-library/processors/ipv6-constraint.js +205 -0
- package/src/core-library/processors/is-array-constraint.js +21 -0
- package/src/core-library/processors/is-date-constraint.js +22 -0
- package/src/core-library/processors/is-number-constraint.js +21 -0
- package/src/core-library/processors/is-object-constraint.js +21 -0
- package/src/core-library/processors/is-string-constraint.js +21 -0
- package/src/core-library/processors/join-operator.js +41 -0
- package/src/core-library/processors/json-constraint.js +22 -0
- package/src/core-library/processors/json-decode-operator.js +25 -0
- package/src/core-library/processors/json-encode-operator.js +35 -0
- package/src/core-library/processors/kebab-case-operator.js +23 -0
- package/src/core-library/processors/keys-operator.js +20 -0
- package/src/core-library/processors/length-constraint.js +85 -0
- package/src/core-library/processors/lookup-operator.js +84 -0
- package/src/core-library/processors/lowercase-operator.js +14 -0
- package/src/core-library/processors/map-operator.js +84 -0
- package/src/core-library/processors/match-operator.js +64 -0
- package/src/core-library/processors/matches-constraint.js +54 -0
- package/src/core-library/processors/math-operators.js +151 -0
- package/src/core-library/processors/merge-deep-operator.js +61 -0
- package/src/core-library/processors/merge-operator.js +54 -0
- package/src/core-library/processors/metadata-operator.js +100 -0
- package/src/core-library/processors/negative-constraint.js +23 -0
- package/src/core-library/processors/never-constraint.js +69 -0
- package/src/core-library/processors/non-empty-constraint.js +59 -0
- package/src/core-library/processors/not-constraint.js +71 -0
- package/src/core-library/processors/number-operator.js +24 -0
- package/src/core-library/processors/numeric-constraint.js +22 -0
- package/src/core-library/processors/object-operator.js +38 -0
- package/src/core-library/processors/omit-operator.js +57 -0
- package/src/core-library/processors/parallel-operator.js +64 -0
- package/src/core-library/processors/pascal-case-operator.js +16 -0
- package/src/core-library/processors/phone-constraint.js +235 -0
- package/src/core-library/processors/pick-operator.js +62 -0
- package/src/core-library/processors/pipeline-operator.js +63 -0
- package/src/core-library/processors/port-constraint.js +22 -0
- package/src/core-library/processors/positive-constraint.js +23 -0
- package/src/core-library/processors/process-operator.js +55 -0
- package/src/core-library/processors/property-operator.js +49 -0
- package/src/core-library/processors/range-constraint.js +72 -0
- package/src/core-library/processors/reference-operator.js +79 -0
- package/src/core-library/processors/require-constraint.js +74 -0
- package/src/core-library/processors/reverse-operator.js +20 -0
- package/src/core-library/processors/round-operator.js +53 -0
- package/src/core-library/processors/schema-handler-operators.js +54 -0
- package/src/core-library/processors/semver-constraint.js +282 -0
- package/src/core-library/processors/sequence-processors.js +406 -0
- package/src/core-library/processors/sort-operator.js +52 -0
- package/src/core-library/processors/split-operator.js +43 -0
- package/src/core-library/processors/string-extra-operators.js +141 -0
- package/src/core-library/processors/string-operator.js +34 -0
- package/src/core-library/processors/target-operator.js +30 -0
- package/src/core-library/processors/template-operator.js +60 -0
- package/src/core-library/processors/title-case-operator.js +17 -0
- package/src/core-library/processors/trim-operator.js +14 -0
- package/src/core-library/processors/truthy-constraint.js +35 -0
- package/src/core-library/processors/type-operator.js +24 -0
- package/src/core-library/processors/unique-operator.js +21 -0
- package/src/core-library/processors/uppercase-operator.js +14 -0
- package/src/core-library/processors/url-constraint.js +31 -0
- package/src/core-library/processors/url-decode-operator.js +50 -0
- package/src/core-library/processors/url-encode-operator.js +44 -0
- package/src/core-library/processors/uuid-constraint.js +31 -0
- package/src/core-library/processors/values-operator.js +20 -0
- package/src/core-library/schemas/any-schema.js +23 -0
- package/src/core-library/schemas/array-schema.js +8 -0
- package/src/core-library/schemas/boolean-schema.js +10 -0
- package/src/core-library/schemas/date-schema.js +12 -0
- package/src/core-library/schemas/function-schema.js +40 -0
- package/src/core-library/schemas/number-schema.js +9 -0
- package/src/core-library/schemas/object-schema.js +10 -0
- package/src/core-library/schemas/root-schema.js +21 -0
- package/src/core-library/schemas/string-schema.js +9 -0
- package/src/core-library-node/index.js +47 -0
- package/src/core-library-node/processors/base64-decode-operator.js +20 -0
- package/src/core-library-node/processors/base64-encode-operator.js +20 -0
- package/src/core-library-node/processors/buffer-operator.js +39 -0
- package/src/core-library-node/processors/directory-constraint.js +35 -0
- package/src/core-library-node/processors/executable-constraint.js +34 -0
- package/src/core-library-node/processors/file-constraint.js +34 -0
- package/src/core-library-node/processors/file-size-constraint.js +94 -0
- package/src/core-library-node/processors/is-buffer-constraint.js +21 -0
- package/src/core-library-node/processors/reachable-constraint.js +28 -0
- package/src/core-library-node/processors/readable-constraint.js +34 -0
- package/src/core-library-node/processors/writable-constraint.js +59 -0
- package/src/core-library-node/schemas/buffer-schema.js +10 -0
- package/src/errors.js +209 -0
- package/src/executor/array-executor.js +78 -0
- package/src/executor/conditional-executor.js +134 -0
- package/src/executor/each-executor.js +68 -0
- package/src/executor/executor.js +123 -0
- package/src/executor/object-executor.js +98 -0
- package/src/executor/parallel-executor.js +43 -0
- package/src/executor/pipeline-executor.js +65 -0
- package/src/executor/sequence-executor.js +206 -0
- package/src/executor/serial-executor.js +24 -0
- package/src/executor/step-executor.js +68 -0
- package/src/helpers/case.js +124 -0
- package/src/helpers/data-size.js +144 -0
- package/src/helpers/debug-sink.js +15 -0
- package/src/helpers/deep.js +280 -0
- package/src/helpers/format.js +121 -0
- package/src/helpers/has-string-properties.js +30 -0
- package/src/helpers/index.js +16 -0
- package/src/helpers/object.js +115 -0
- package/src/helpers/parse-date.js +75 -0
- package/src/helpers/path.js +28 -0
- package/src/helpers/regex.js +18 -0
- package/src/helpers/stringify.js +309 -0
- package/src/helpers/to-data.js +64 -0
- package/src/helpers/truthy.js +55 -0
- package/src/index.js +29 -0
- package/src/schema-compiler.js +531 -0
- package/src/schema-location.js +200 -0
- package/src/schema-resolver.js +546 -0
- package/src/schema.js +1182 -0
- package/src/traversal/executors/check-condition.js +42 -0
- package/src/traversal/executors/check-input.js +27 -0
- package/src/traversal/executors/check-required.js +19 -0
- package/src/traversal/executors/check-schema.js +45 -0
- package/src/traversal/executors/defaults.js +21 -0
- package/src/traversal/executors/enter-existing.js +25 -0
- package/src/traversal/executors/enter-input.js +25 -0
- package/src/traversal/executors/enter.js +37 -0
- package/src/traversal/executors/exit.js +74 -0
- package/src/traversal/executors/finalize.js +64 -0
- package/src/traversal/executors/index.js +42 -0
- package/src/traversal/executors/normalize.js +38 -0
- package/src/traversal/executors/prepare-existing.js +27 -0
- package/src/traversal/executors/prepare-pending.js +54 -0
- package/src/traversal/executors/resolve-union.js +50 -0
- package/src/traversal/executors/serialize.js +48 -0
- package/src/traversal/executors/transform-early.js +51 -0
- package/src/traversal/executors/transform.js +68 -0
- package/src/traversal/executors/traversal-state-executor.js +46 -0
- package/src/traversal/executors/validate.js +63 -0
- package/src/traversal/traversal-context.js +231 -0
- package/src/traversal/traversal-state.js +809 -0
- package/src/types.js +102 -0
- package/src/value-processor/composed-value-processor.js +43 -0
- package/src/value-processor/defined-value-processor.js +72 -0
- package/src/value-processor/function-value-processor.js +68 -0
- package/src/value-processor/parameterized-value-processor.js +45 -0
- package/src/value-processor/parameters-value-processor.js +178 -0
- package/src/value-processor/spec.js +89 -0
- package/src/value-processor/value-processor.js +105 -0
- package/types/compilation/handler-compilation.d.ts +13 -0
- package/types/compilation/metadata-compilation.d.ts +6 -0
- package/types/compilation/schema-compilation.d.ts +32 -0
- package/types/compilation/selection-compilation.d.ts +9 -0
- package/types/compilation/union-compilation.d.ts +42 -0
- package/types/compilation/values-compilation.d.ts +12 -0
- package/types/compiled-schema.d.ts +883 -0
- package/types/constants.d.ts +1 -0
- package/types/core-library/index.d.ts +7 -0
- package/types/core-library/processors/aggregation-operators.d.ts +24 -0
- package/types/core-library/processors/alpha-constraint.d.ts +9 -0
- package/types/core-library/processors/alphanum-constraint.d.ts +9 -0
- package/types/core-library/processors/array-operator.d.ts +12 -0
- package/types/core-library/processors/assert-constraint.d.ts +30 -0
- package/types/core-library/processors/base64-constraint.d.ts +11 -0
- package/types/core-library/processors/camel-case-operator.d.ts +17 -0
- package/types/core-library/processors/capitalize-operator.d.ts +11 -0
- package/types/core-library/processors/cardnum-constraint.d.ts +51 -0
- package/types/core-library/processors/ceil-operator.d.ts +30 -0
- package/types/core-library/processors/collapse-operator.d.ts +24 -0
- package/types/core-library/processors/compact-operator.d.ts +29 -0
- package/types/core-library/processors/compile-operator.d.ts +34 -0
- package/types/core-library/processors/concat-operator.d.ts +23 -0
- package/types/core-library/processors/conditional-operators.d.ts +219 -0
- package/types/core-library/processors/constant-case-operator.d.ts +9 -0
- package/types/core-library/processors/data-size-operator.d.ts +31 -0
- package/types/core-library/processors/date-object-operator.d.ts +16 -0
- package/types/core-library/processors/date-operator.d.ts +21 -0
- package/types/core-library/processors/date-range-constraint.d.ts +26 -0
- package/types/core-library/processors/defined-constraint.d.ts +20 -0
- package/types/core-library/processors/each-operator.d.ts +34 -0
- package/types/core-library/processors/email-constraint.d.ts +54 -0
- package/types/core-library/processors/entries-operator.d.ts +13 -0
- package/types/core-library/processors/eq-constraint.d.ts +20 -0
- package/types/core-library/processors/filter-operator.d.ts +35 -0
- package/types/core-library/processors/find-schema-operator.d.ts +28 -0
- package/types/core-library/processors/flatten-operator.d.ts +26 -0
- package/types/core-library/processors/floor-operator.d.ts +33 -0
- package/types/core-library/processors/get-operator.d.ts +31 -0
- package/types/core-library/processors/group-by-operator.d.ts +36 -0
- package/types/core-library/processors/has-prefix-constraint.d.ts +22 -0
- package/types/core-library/processors/has-suffix-constraint.d.ts +20 -0
- package/types/core-library/processors/hex-constraint.d.ts +9 -0
- package/types/core-library/processors/hostname-constraint.d.ts +11 -0
- package/types/core-library/processors/http-url-constraint.d.ts +9 -0
- package/types/core-library/processors/in-constraint.d.ts +27 -0
- package/types/core-library/processors/index-by-operator.d.ts +26 -0
- package/types/core-library/processors/index.d.ts +8 -0
- package/types/core-library/processors/input-operator.d.ts +20 -0
- package/types/core-library/processors/instanceof-constraint.d.ts +23 -0
- package/types/core-library/processors/integer-constraint.d.ts +9 -0
- package/types/core-library/processors/invoke-operator.d.ts +12 -0
- package/types/core-library/processors/ipv4-constraint.d.ts +37 -0
- package/types/core-library/processors/ipv6-constraint.d.ts +34 -0
- package/types/core-library/processors/is-array-constraint.d.ts +10 -0
- package/types/core-library/processors/is-date-constraint.d.ts +10 -0
- package/types/core-library/processors/is-number-constraint.d.ts +10 -0
- package/types/core-library/processors/is-object-constraint.d.ts +10 -0
- package/types/core-library/processors/is-string-constraint.d.ts +10 -0
- package/types/core-library/processors/join-operator.d.ts +29 -0
- package/types/core-library/processors/json-constraint.d.ts +10 -0
- package/types/core-library/processors/json-decode-operator.d.ts +9 -0
- package/types/core-library/processors/json-encode-operator.d.ts +27 -0
- package/types/core-library/processors/kebab-case-operator.d.ts +16 -0
- package/types/core-library/processors/keys-operator.d.ts +9 -0
- package/types/core-library/processors/length-constraint.d.ts +34 -0
- package/types/core-library/processors/lookup-operator.d.ts +36 -0
- package/types/core-library/processors/lowercase-operator.d.ts +9 -0
- package/types/core-library/processors/map-operator.d.ts +38 -0
- package/types/core-library/processors/match-operator.d.ts +34 -0
- package/types/core-library/processors/matches-constraint.d.ts +29 -0
- package/types/core-library/processors/math-operators.d.ts +91 -0
- package/types/core-library/processors/merge-deep-operator.d.ts +32 -0
- package/types/core-library/processors/merge-operator.d.ts +26 -0
- package/types/core-library/processors/metadata-operator.d.ts +56 -0
- package/types/core-library/processors/negative-constraint.d.ts +13 -0
- package/types/core-library/processors/never-constraint.d.ts +26 -0
- package/types/core-library/processors/non-empty-constraint.d.ts +28 -0
- package/types/core-library/processors/not-constraint.d.ts +28 -0
- package/types/core-library/processors/number-operator.d.ts +9 -0
- package/types/core-library/processors/numeric-constraint.d.ts +10 -0
- package/types/core-library/processors/object-operator.d.ts +10 -0
- package/types/core-library/processors/omit-operator.d.ts +24 -0
- package/types/core-library/processors/parallel-operator.d.ts +41 -0
- package/types/core-library/processors/pascal-case-operator.d.ts +9 -0
- package/types/core-library/processors/phone-constraint.d.ts +65 -0
- package/types/core-library/processors/pick-operator.d.ts +27 -0
- package/types/core-library/processors/pipeline-operator.d.ts +40 -0
- package/types/core-library/processors/port-constraint.d.ts +11 -0
- package/types/core-library/processors/positive-constraint.d.ts +13 -0
- package/types/core-library/processors/process-operator.d.ts +37 -0
- package/types/core-library/processors/property-operator.d.ts +34 -0
- package/types/core-library/processors/range-constraint.d.ts +30 -0
- package/types/core-library/processors/reference-operator.d.ts +38 -0
- package/types/core-library/processors/require-constraint.d.ts +29 -0
- package/types/core-library/processors/reverse-operator.d.ts +9 -0
- package/types/core-library/processors/round-operator.d.ts +34 -0
- package/types/core-library/processors/schema-handler-operators.d.ts +28 -0
- package/types/core-library/processors/semver-constraint.d.ts +43 -0
- package/types/core-library/processors/sequence-processors.d.ts +213 -0
- package/types/core-library/processors/sort-operator.d.ts +31 -0
- package/types/core-library/processors/split-operator.d.ts +33 -0
- package/types/core-library/processors/string-extra-operators.d.ts +83 -0
- package/types/core-library/processors/string-operator.d.ts +10 -0
- package/types/core-library/processors/target-operator.d.ts +27 -0
- package/types/core-library/processors/template-operator.d.ts +31 -0
- package/types/core-library/processors/title-case-operator.d.ts +12 -0
- package/types/core-library/processors/trim-operator.d.ts +9 -0
- package/types/core-library/processors/truthy-constraint.d.ts +23 -0
- package/types/core-library/processors/type-operator.d.ts +11 -0
- package/types/core-library/processors/unique-operator.d.ts +10 -0
- package/types/core-library/processors/uppercase-operator.d.ts +9 -0
- package/types/core-library/processors/url-constraint.d.ts +20 -0
- package/types/core-library/processors/url-decode-operator.d.ts +31 -0
- package/types/core-library/processors/url-encode-operator.d.ts +36 -0
- package/types/core-library/processors/uuid-constraint.d.ts +20 -0
- package/types/core-library/processors/values-operator.d.ts +9 -0
- package/types/core-library/schemas/any-schema.d.ts +2 -0
- package/types/core-library/schemas/array-schema.d.ts +2 -0
- package/types/core-library/schemas/boolean-schema.d.ts +2 -0
- package/types/core-library/schemas/date-schema.d.ts +2 -0
- package/types/core-library/schemas/function-schema.d.ts +2 -0
- package/types/core-library/schemas/number-schema.d.ts +2 -0
- package/types/core-library/schemas/object-schema.d.ts +2 -0
- package/types/core-library/schemas/root-schema.d.ts +2 -0
- package/types/core-library/schemas/string-schema.d.ts +2 -0
- package/types/core-library-node/index.d.ts +12 -0
- package/types/core-library-node/processors/base64-decode-operator.d.ts +9 -0
- package/types/core-library-node/processors/base64-encode-operator.d.ts +9 -0
- package/types/core-library-node/processors/buffer-operator.d.ts +15 -0
- package/types/core-library-node/processors/directory-constraint.d.ts +14 -0
- package/types/core-library-node/processors/executable-constraint.d.ts +17 -0
- package/types/core-library-node/processors/file-constraint.d.ts +13 -0
- package/types/core-library-node/processors/file-size-constraint.d.ts +43 -0
- package/types/core-library-node/processors/is-buffer-constraint.d.ts +10 -0
- package/types/core-library-node/processors/reachable-constraint.d.ts +13 -0
- package/types/core-library-node/processors/readable-constraint.d.ts +17 -0
- package/types/core-library-node/processors/writable-constraint.d.ts +18 -0
- package/types/core-library-node/schemas/buffer-schema.d.ts +2 -0
- package/types/errors.d.ts +58 -0
- package/types/executor/array-executor.d.ts +17 -0
- package/types/executor/conditional-executor.d.ts +45 -0
- package/types/executor/each-executor.d.ts +15 -0
- package/types/executor/executor.d.ts +84 -0
- package/types/executor/object-executor.d.ts +14 -0
- package/types/executor/parallel-executor.d.ts +27 -0
- package/types/executor/pipeline-executor.d.ts +11 -0
- package/types/executor/sequence-executor.d.ts +32 -0
- package/types/executor/serial-executor.d.ts +16 -0
- package/types/executor/step-executor.d.ts +14 -0
- package/types/helpers/case.d.ts +30 -0
- package/types/helpers/data-size.d.ts +25 -0
- package/types/helpers/debug-sink.d.ts +9 -0
- package/types/helpers/deep.d.ts +33 -0
- package/types/helpers/format.d.ts +14 -0
- package/types/helpers/has-string-properties.d.ts +5 -0
- package/types/helpers/index.d.ts +13 -0
- package/types/helpers/object.d.ts +46 -0
- package/types/helpers/parse-date.d.ts +6 -0
- package/types/helpers/path.d.ts +13 -0
- package/types/helpers/regex.d.ts +7 -0
- package/types/helpers/stringify.d.ts +33 -0
- package/types/helpers/to-data.d.ts +13 -0
- package/types/helpers/truthy.d.ts +26 -0
- package/types/index.d.ts +6 -0
- package/types/schema-compiler.d.ts +49 -0
- package/types/schema-location.d.ts +64 -0
- package/types/schema-resolver.d.ts +145 -0
- package/types/schema.d.ts +586 -0
- package/types/traversal/executors/check-condition.d.ts +8 -0
- package/types/traversal/executors/check-input.d.ts +6 -0
- package/types/traversal/executors/check-required.d.ts +6 -0
- package/types/traversal/executors/check-schema.d.ts +7 -0
- package/types/traversal/executors/defaults.d.ts +8 -0
- package/types/traversal/executors/enter-existing.d.ts +6 -0
- package/types/traversal/executors/enter-input.d.ts +8 -0
- package/types/traversal/executors/enter.d.ts +7 -0
- package/types/traversal/executors/exit.d.ts +6 -0
- package/types/traversal/executors/finalize.d.ts +6 -0
- package/types/traversal/executors/index.d.ts +15 -0
- package/types/traversal/executors/normalize.d.ts +7 -0
- package/types/traversal/executors/prepare-existing.d.ts +6 -0
- package/types/traversal/executors/prepare-pending.d.ts +6 -0
- package/types/traversal/executors/resolve-union.d.ts +6 -0
- package/types/traversal/executors/serialize.d.ts +11 -0
- package/types/traversal/executors/transform-early.d.ts +6 -0
- package/types/traversal/executors/transform.d.ts +6 -0
- package/types/traversal/executors/traversal-state-executor.d.ts +19 -0
- package/types/traversal/executors/validate.d.ts +6 -0
- package/types/traversal/traversal-context.d.ts +67 -0
- package/types/traversal/traversal-state.d.ts +97 -0
- package/types/types.d.ts +218 -0
- package/types/value-processor/composed-value-processor.d.ts +17 -0
- package/types/value-processor/defined-value-processor.d.ts +16 -0
- package/types/value-processor/function-value-processor.d.ts +15 -0
- package/types/value-processor/parameterized-value-processor.d.ts +14 -0
- package/types/value-processor/parameters-value-processor.d.ts +28 -0
- package/types/value-processor/spec.d.ts +22 -0
- package/types/value-processor/value-processor.d.ts +92 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
import { CompiledSchema } from './compiled-schema.js';
|
|
2
|
+
import { Schema } from './schema.js';
|
|
3
|
+
import { SchemaCompiler } from './schema-compiler.js';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
ConstantExecutor,
|
|
7
|
+
Executor, FALSE_EXECUTOR,
|
|
8
|
+
FunctionExecutor,
|
|
9
|
+
NULL_EXECUTOR,
|
|
10
|
+
toExecutor, TRUE_EXECUTOR,
|
|
11
|
+
UNDEFINED_EXECUTOR
|
|
12
|
+
} from './executor/executor.js';
|
|
13
|
+
import { FunctionValueProcessor } from './value-processor/function-value-processor.js';
|
|
14
|
+
import {
|
|
15
|
+
extractKeywordValueProcessorSpec,
|
|
16
|
+
isKeywordValueProcessorSpec,
|
|
17
|
+
isLegalValueProcessorSpec
|
|
18
|
+
} from './value-processor/spec.js';
|
|
19
|
+
import { ComposedValueProcessor } from './value-processor/composed-value-processor.js';
|
|
20
|
+
import { ValueProcessor } from './value-processor/value-processor.js';
|
|
21
|
+
import { ObjectExecutor } from './executor/object-executor.js';
|
|
22
|
+
import { ArrayExecutor } from './executor/array-executor.js';
|
|
23
|
+
import { DefinedValueProcessor } from './value-processor/defined-value-processor.js';
|
|
24
|
+
import { ResolverError, SchemaError } from './errors.js';
|
|
25
|
+
import { toKebabCase } from './helpers/case.js';
|
|
26
|
+
import { isNativeClass, map } from './helpers/object.js';
|
|
27
|
+
import { parseRegExp } from './helpers/regex.js';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Module-level registry of core library functions. Populated by the package entry
|
|
31
|
+
* point (`src/index.js`) before any SchemaResolver is constructed. Each registered
|
|
32
|
+
* function is called synchronously in the constructor of every new SchemaResolver.
|
|
33
|
+
*
|
|
34
|
+
* @type {Array<(resolver: SchemaResolver, options: object) => void>}
|
|
35
|
+
*/
|
|
36
|
+
const _coreLibraries = [];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Register a core library function to be loaded into every new SchemaResolver.
|
|
40
|
+
* Called by the package entry point; not part of the public API.
|
|
41
|
+
*
|
|
42
|
+
* @param {(resolver: SchemaResolver, options: object) => void} libraryFn
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export function registerCoreLibrary(libraryFn) {
|
|
46
|
+
_coreLibraries.push(libraryFn);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** @typedef {{name:string, [key:string]:any}} SchemaResolverLibraryOptions */
|
|
50
|
+
|
|
51
|
+
/** @import { SchemaData } from './types.js' */
|
|
52
|
+
/** @import { ValueProcessorDefinition, ValueProcessorSpec, ValueProcessorBuilder, ValueProcessorFunction, ValueProcessorArgs, ValueProcessorParameter, KeywordValueProcessorSpec } from './value-processor/value-processor.js' */
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The SchemaResolver uses its internal registries of named schemas and value processor keywords to
|
|
56
|
+
* convert Schemas containing unresolved references into resolved Schemas that are fully self-contained.
|
|
57
|
+
*/
|
|
58
|
+
export class SchemaResolver
|
|
59
|
+
{
|
|
60
|
+
/**
|
|
61
|
+
* @type {Map<string,Schema>}
|
|
62
|
+
*/
|
|
63
|
+
#schemaMap = new Map();
|
|
64
|
+
/**
|
|
65
|
+
* @type {Map<string,ValueProcessorDefinition>}
|
|
66
|
+
*/
|
|
67
|
+
#processorMap = new Map();
|
|
68
|
+
|
|
69
|
+
#resolveCache = new Map();
|
|
70
|
+
|
|
71
|
+
constructor() {
|
|
72
|
+
for (const lib of _coreLibraries) {
|
|
73
|
+
this.use(lib, { sync: true });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* add a schema to the registry
|
|
79
|
+
* @param {string} name
|
|
80
|
+
* @param {Schema} schema
|
|
81
|
+
* @returns {SchemaResolver}
|
|
82
|
+
*/
|
|
83
|
+
registerSchema(name, schema) {
|
|
84
|
+
if (!(schema instanceof Schema)) {
|
|
85
|
+
throw new ResolverError(`Registry can only store Schema instances`);
|
|
86
|
+
}
|
|
87
|
+
const registryName = toKebabCase(name);
|
|
88
|
+
this.#schemaMap.set(registryName, schema);
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* return the registered schema with a given name
|
|
94
|
+
* @param {string} name
|
|
95
|
+
* @returns {Schema}
|
|
96
|
+
*/
|
|
97
|
+
getSchema(name) {
|
|
98
|
+
const registryName = toKebabCase(name);
|
|
99
|
+
const schema = this.#schemaMap.get(registryName);
|
|
100
|
+
if (!schema) {
|
|
101
|
+
throw new ResolverError(`Unable to resolve "${name}"`);
|
|
102
|
+
}
|
|
103
|
+
return schema;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* return true if there exists a registered schema with a given name
|
|
108
|
+
* @param {string} name
|
|
109
|
+
* @returns {boolean}
|
|
110
|
+
*/
|
|
111
|
+
hasSchema(name) {
|
|
112
|
+
const registryName = toKebabCase(name);
|
|
113
|
+
return this.#schemaMap.has(registryName);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Register a value processor definition
|
|
118
|
+
* @param {ValueProcessorDefinition} definition
|
|
119
|
+
* @returns {SchemaResolver}
|
|
120
|
+
*/
|
|
121
|
+
registerValueProcessorDefinition(definition) {
|
|
122
|
+
const {keyword, process, description, build} = definition;
|
|
123
|
+
|
|
124
|
+
if (!keyword) {
|
|
125
|
+
throw new ResolverError('Missing keyword in processor definition');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (process && build) {
|
|
129
|
+
throw new ResolverError(`Processor definition for '${keyword}' cannot define both process and build functions`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!process && !build) {
|
|
133
|
+
throw new ResolverError(`Processor definition for '${keyword}' must have define a process or build function`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (description && typeof description !== 'string') {
|
|
137
|
+
throw new ResolverError(`Processor definition description for '${keyword}' must be a string`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this.#processorMap.set(keyword, definition);
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* register a named "simple" ValueProcessor
|
|
146
|
+
* @param {string} keyword
|
|
147
|
+
* @param {ValueProcessorFunction} process
|
|
148
|
+
* @param {string} [description]
|
|
149
|
+
* @returns {SchemaResolver}
|
|
150
|
+
*/
|
|
151
|
+
registerValueProcessor(keyword, process, description) {
|
|
152
|
+
if (typeof process !== 'function') {
|
|
153
|
+
throw new ResolverError(`Processor for keyword '${keyword}' must be a function`);
|
|
154
|
+
}
|
|
155
|
+
return this.registerValueProcessorDefinition({
|
|
156
|
+
keyword,
|
|
157
|
+
parameters: [],
|
|
158
|
+
process,
|
|
159
|
+
description: description ?? keyword
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* register a complex ValueProcessor that needs to be built based on schema processor spec
|
|
165
|
+
* @param {string} keyword
|
|
166
|
+
* @param {ValueProcessorBuilder} build
|
|
167
|
+
* @returns {SchemaResolver}
|
|
168
|
+
*/
|
|
169
|
+
registerValueProcessorBuilder(keyword, build) {
|
|
170
|
+
if (typeof build !== 'function') {
|
|
171
|
+
throw new ResolverError(`Processor builder for keyword '${keyword}' must be a function`);
|
|
172
|
+
}
|
|
173
|
+
return this.registerValueProcessorDefinition({
|
|
174
|
+
keyword,
|
|
175
|
+
build
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Load a library of schemas and/or value processors.
|
|
182
|
+
*
|
|
183
|
+
* Expects a (potentially async) library function accepting a SchemaResolver. Options passed to `use`
|
|
184
|
+
* will be propagated to the library function.
|
|
185
|
+
*
|
|
186
|
+
* The `name` option is used for error messages.
|
|
187
|
+
* The `sync` option is used internally to enforce the core library does not get loaded asynchronously.
|
|
188
|
+
*
|
|
189
|
+
* @param {(resolver:SchemaResolver, options:object) => Promise<void>|void} libraryFunction
|
|
190
|
+
* @param {object} [options]
|
|
191
|
+
* @returns {Promise<void>}
|
|
192
|
+
*/
|
|
193
|
+
async use(libraryFunction, options = {}) {
|
|
194
|
+
try {
|
|
195
|
+
const libraryResult = libraryFunction(this, options);
|
|
196
|
+
if (libraryResult instanceof Promise && options.sync) {
|
|
197
|
+
throw new ResolverError('Cannot load async library');
|
|
198
|
+
}
|
|
199
|
+
return await libraryResult;
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
if (error instanceof ResolverError) {
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
throw new ResolverError(`Error loading library`, {cause: error});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
_constantKeywords = {
|
|
215
|
+
$null: NULL_EXECUTOR,
|
|
216
|
+
$undefined: UNDEFINED_EXECUTOR,
|
|
217
|
+
$true: TRUE_EXECUTOR,
|
|
218
|
+
$false: FALSE_EXECUTOR
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* @param {SchemaCompiler} compiler
|
|
223
|
+
* @param {KeywordValueProcessorSpec} spec
|
|
224
|
+
* @param {boolean} [recursive]
|
|
225
|
+
* @returns {ValueProcessor}
|
|
226
|
+
*/
|
|
227
|
+
compileKeywordValueProcessorSpec(compiler, spec, recursive) {
|
|
228
|
+
if (!isKeywordValueProcessorSpec(spec)) {
|
|
229
|
+
throw new ResolverError('Not a keyword processor spec');
|
|
230
|
+
}
|
|
231
|
+
const [keyword, rawArgs] = extractKeywordValueProcessorSpec(spec);
|
|
232
|
+
|
|
233
|
+
if (this._constantKeywords[spec]) {
|
|
234
|
+
return new ComposedValueProcessor(this._constantKeywords[spec], spec);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (keyword === 'literal') {
|
|
238
|
+
// note that in the semantically odd case where a user didn't provide args, the literal will be an empty array!
|
|
239
|
+
return new ComposedValueProcessor(new ConstantExecutor(rawArgs), spec);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const definition = this.#processorMap.get(keyword);
|
|
243
|
+
|
|
244
|
+
if (!definition) {
|
|
245
|
+
throw new ResolverError(`Unknown processor keyword: $${keyword}`);
|
|
246
|
+
}
|
|
247
|
+
// This "map" call will wrap any non-collection as an array:
|
|
248
|
+
const args = map(rawArgs, arg => this.compileValueProcessorSpec(compiler, arg, recursive));
|
|
249
|
+
|
|
250
|
+
if (definition.build) {
|
|
251
|
+
const processor = definition.build(args, {compiler});
|
|
252
|
+
if (processor?.['process']) {
|
|
253
|
+
return this.compileValueProcessorSpec(compiler, processor, recursive);
|
|
254
|
+
}
|
|
255
|
+
if (!(processor instanceof ValueProcessor)) {
|
|
256
|
+
throw new SchemaError(`ValueProcessor builder for $${keyword} returned invalid`, {value:processor});
|
|
257
|
+
}
|
|
258
|
+
return processor;
|
|
259
|
+
}
|
|
260
|
+
return new DefinedValueProcessor(definition, args);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
compileSchemaValueProcessorSpec(compiler, spec) {
|
|
265
|
+
let compiledSchema;
|
|
266
|
+
|
|
267
|
+
if (compiler.compileCache.has(spec)) {
|
|
268
|
+
return new ComposedValueProcessor(new ConstantExecutor(compiler.compileCache.get(spec)), spec);
|
|
269
|
+
}
|
|
270
|
+
return new ComposedValueProcessor(
|
|
271
|
+
new FunctionExecutor(
|
|
272
|
+
async () => {
|
|
273
|
+
if (compiler.compileCache.has(spec)) {
|
|
274
|
+
return compiler.compileCache.get(spec);
|
|
275
|
+
}
|
|
276
|
+
compiledSchema ??= (spec instanceof CompiledSchema)? spec : await compiler.compile(spec);
|
|
277
|
+
return compiledSchema;
|
|
278
|
+
}
|
|
279
|
+
), spec);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Convert a processor specification into an executor
|
|
284
|
+
* @param {SchemaCompiler} compiler
|
|
285
|
+
* @param {ValueProcessorSpec} spec - The processor specification
|
|
286
|
+
* @param {boolean} [recursive]
|
|
287
|
+
* @returns {ValueProcessor}
|
|
288
|
+
*/
|
|
289
|
+
compileValueProcessorSpecObject(compiler, spec, recursive = false) {
|
|
290
|
+
|
|
291
|
+
if (typeof spec !== 'object') {
|
|
292
|
+
throw new ResolverError('not a spec object');
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** @type {{[key:string]:ValueProcessor}} */
|
|
296
|
+
const out = {};
|
|
297
|
+
for (const [key, value] of Object.entries(spec)) {
|
|
298
|
+
out[key] = this.compileValueProcessorSpec(compiler, value, recursive);
|
|
299
|
+
}
|
|
300
|
+
return new ComposedValueProcessor(new ObjectExecutor(out), map(out, p => p.spec));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Convert a processor specification into an executor
|
|
305
|
+
* @param {SchemaCompiler} compiler
|
|
306
|
+
* @param {ValueProcessorSpec} spec - The processor specification
|
|
307
|
+
* @param {boolean} [recursive]
|
|
308
|
+
* @returns {ValueProcessor}
|
|
309
|
+
*/
|
|
310
|
+
compileValueProcessorSpecArray(compiler, spec, recursive = false) {
|
|
311
|
+
|
|
312
|
+
if (!Array.isArray(spec)) {
|
|
313
|
+
throw new ResolverError('not a spec array');
|
|
314
|
+
}
|
|
315
|
+
/** @type {ValueProcessor[]} */
|
|
316
|
+
const out = [];
|
|
317
|
+
for (let i = 0; i < spec.length; ++i) {
|
|
318
|
+
out[i] = this.compileValueProcessorSpec(compiler, spec[i], recursive);
|
|
319
|
+
}
|
|
320
|
+
return new ComposedValueProcessor(new ArrayExecutor(out), map(out, p => p.spec));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Convert a value processor specification into a value processor executor
|
|
326
|
+
*
|
|
327
|
+
* @param {SchemaCompiler} compiler
|
|
328
|
+
* @param {ValueProcessorSpec} spec - The processor specification
|
|
329
|
+
* @param {boolean} [recursive]
|
|
330
|
+
* @returns {ValueProcessor}
|
|
331
|
+
*/
|
|
332
|
+
compileValueProcessorSpec(compiler, spec, recursive = false) {
|
|
333
|
+
|
|
334
|
+
if (!isLegalValueProcessorSpec(spec)) {
|
|
335
|
+
throw new SchemaError(`Invalid value processor specification`, {value: spec});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** @type {ValueProcessor} */
|
|
339
|
+
let valueProcessor;
|
|
340
|
+
|
|
341
|
+
if (spec === undefined) {
|
|
342
|
+
valueProcessor = new ValueProcessor(); // passthrough
|
|
343
|
+
}
|
|
344
|
+
else if (spec === null) {
|
|
345
|
+
spec = '$null';
|
|
346
|
+
valueProcessor = new ComposedValueProcessor(NULL_EXECUTOR, '$null');
|
|
347
|
+
}
|
|
348
|
+
else if (spec === '$resolver') {
|
|
349
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(this), spec);
|
|
350
|
+
}
|
|
351
|
+
else if (spec === '$compiler') {
|
|
352
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(compiler), spec);
|
|
353
|
+
}
|
|
354
|
+
else if (spec instanceof ValueProcessor) {
|
|
355
|
+
valueProcessor = spec;
|
|
356
|
+
}
|
|
357
|
+
else if (spec instanceof Schema) {
|
|
358
|
+
valueProcessor = this.compileSchemaValueProcessorSpec(compiler, spec);
|
|
359
|
+
}
|
|
360
|
+
else if (spec instanceof CompiledSchema) {
|
|
361
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(spec), spec);
|
|
362
|
+
}
|
|
363
|
+
else if (isKeywordValueProcessorSpec(spec)) {
|
|
364
|
+
valueProcessor = this.compileKeywordValueProcessorSpec(compiler, spec, recursive);
|
|
365
|
+
}
|
|
366
|
+
else if (spec instanceof Executor) {
|
|
367
|
+
valueProcessor = new ComposedValueProcessor(spec, spec);
|
|
368
|
+
}
|
|
369
|
+
else if (spec instanceof RegExp) {
|
|
370
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(spec), spec, `${spec}`);
|
|
371
|
+
}
|
|
372
|
+
else if (spec instanceof Date) {
|
|
373
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(spec), spec, spec.toISOString());
|
|
374
|
+
}
|
|
375
|
+
else if (typeof spec === 'string' && spec.startsWith('/') && spec.lastIndexOf('/') > 0) {
|
|
376
|
+
try {
|
|
377
|
+
const regex = parseRegExp(spec);
|
|
378
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(regex), regex, `${regex}`);
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
throw new SchemaError(`Invalid regex pattern`, {value: spec});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else if (spec instanceof SchemaCompiler) {
|
|
385
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(spec), spec);
|
|
386
|
+
}
|
|
387
|
+
else if (typeof spec === 'object' && typeof spec.process === 'function') {
|
|
388
|
+
valueProcessor = new DefinedValueProcessor(spec);
|
|
389
|
+
}
|
|
390
|
+
else if (isNativeClass(spec)) {
|
|
391
|
+
valueProcessor = new ComposedValueProcessor(new ConstantExecutor(spec), spec, spec.name);
|
|
392
|
+
}
|
|
393
|
+
else if (typeof spec === 'function') {
|
|
394
|
+
valueProcessor = new FunctionValueProcessor(spec);
|
|
395
|
+
}
|
|
396
|
+
else if (Array.isArray(spec)) {
|
|
397
|
+
valueProcessor = this.compileValueProcessorSpecArray(compiler, spec, recursive);
|
|
398
|
+
}
|
|
399
|
+
else if (typeof spec === 'object') {
|
|
400
|
+
valueProcessor = this.compileValueProcessorSpecObject(compiler, spec, recursive);
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
valueProcessor = new ComposedValueProcessor(toExecutor(spec), spec)
|
|
404
|
+
}
|
|
405
|
+
if (valueProcessor.spec === undefined) {
|
|
406
|
+
valueProcessor.spec = spec;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return valueProcessor;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
compiler() {
|
|
413
|
+
return new SchemaCompiler(this);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Build a compiled schema from the schema definition.
|
|
419
|
+
* @param {Schema|CompiledSchema|SchemaData} inputSchema
|
|
420
|
+
* @returns {CompiledSchema}
|
|
421
|
+
*/
|
|
422
|
+
compile(inputSchema) {
|
|
423
|
+
if (inputSchema instanceof CompiledSchema) {
|
|
424
|
+
return inputSchema;
|
|
425
|
+
}
|
|
426
|
+
const compiler = new SchemaCompiler(this);
|
|
427
|
+
return compiler.compile(inputSchema);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Create a new Schema that contains the flattened hierarchy of all resolved base schemas.
|
|
432
|
+
*
|
|
433
|
+
* This can be useful if you need to make changes to the full schema, e.g. prepending processors
|
|
434
|
+
* before the base class handlers.
|
|
435
|
+
*
|
|
436
|
+
* @param {Schema|CompiledSchema|SchemaData|string} inputSchema
|
|
437
|
+
* @param {boolean} [recursive]
|
|
438
|
+
* @returns {Schema|CompiledSchema}
|
|
439
|
+
*/
|
|
440
|
+
resolve(inputSchema, recursive = true) {
|
|
441
|
+
if (inputSchema instanceof CompiledSchema) {
|
|
442
|
+
return inputSchema;
|
|
443
|
+
}
|
|
444
|
+
if (typeof inputSchema === 'string') {
|
|
445
|
+
if (this.hasSchema(inputSchema)) {
|
|
446
|
+
inputSchema = this.getSchema(inputSchema);
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
// we don't know it - let's pretend it was just a base.
|
|
450
|
+
inputSchema = new Schema(inputSchema);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (this.#resolveCache.has(inputSchema)) {
|
|
454
|
+
return this.#resolveCache.get(inputSchema);
|
|
455
|
+
}
|
|
456
|
+
const outputSchema = new Schema();
|
|
457
|
+
|
|
458
|
+
this.#resolveCache.set(inputSchema, outputSchema);
|
|
459
|
+
this.#resolveCache.set(outputSchema, outputSchema);
|
|
460
|
+
|
|
461
|
+
/** @type {Schema|CompiledSchema|SchemaData|undefined} */
|
|
462
|
+
let source = inputSchema;
|
|
463
|
+
|
|
464
|
+
let strictCompileError;
|
|
465
|
+
|
|
466
|
+
let foundType = false; // we need to hit one of our fundamental types, otherwise we'll use "any"
|
|
467
|
+
|
|
468
|
+
while (source !== undefined) {
|
|
469
|
+
for (const [propName, propSchema] of Object.entries(source.properties ?? {})) {
|
|
470
|
+
if (!outputSchema.properties.hasOwnProperty(propName)) {
|
|
471
|
+
const needsResolve = recursive || !(propSchema instanceof Schema || propSchema instanceof CompiledSchema)
|
|
472
|
+
outputSchema.properties[propName] = needsResolve ? this.resolve(propSchema) : propSchema;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
for (const [metaName, metaValue] of Object.entries(source.metadata ?? {})) {
|
|
476
|
+
if (!outputSchema.metadata.hasOwnProperty(metaName)) {
|
|
477
|
+
outputSchema.metadata[metaName] = metaValue;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
for (const [discriminatorValue, unionSchema] of Object.entries(source.unionSchemas ?? {})) {
|
|
481
|
+
if (!outputSchema.unionSchemas.hasOwnProperty(discriminatorValue)) {
|
|
482
|
+
const needsResolve = recursive || !(unionSchema instanceof Schema || unionSchema instanceof CompiledSchema)
|
|
483
|
+
outputSchema.unionSchemas[discriminatorValue] = needsResolve ? this.resolve(unionSchema) : unionSchema;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
for (const [handlerName, handlerValues] of Object.entries(source.handlers ?? {})) {
|
|
487
|
+
// TODO - add an option that enables a schema to opt out of base handler inheritance
|
|
488
|
+
if (!outputSchema.handlers.hasOwnProperty(handlerName)) {
|
|
489
|
+
outputSchema.handlers[handlerName] = [];
|
|
490
|
+
}
|
|
491
|
+
outputSchema.handlers[handlerName].unshift(...handlerValues);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
for (const [optionName, optionValue] of Object.entries(source.options ?? {})) {
|
|
495
|
+
if (!outputSchema.options.hasOwnProperty(optionName)) {
|
|
496
|
+
outputSchema.options[optionName] = optionValue;
|
|
497
|
+
if (optionName === 'type') {
|
|
498
|
+
foundType = true;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if (source instanceof CompiledSchema) {
|
|
503
|
+
source = undefined;
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
if (source.base === undefined && !foundType) {
|
|
507
|
+
source.base = 'any';
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (source.base) {
|
|
511
|
+
if (this.hasSchema(source.base)) {
|
|
512
|
+
source = this.getSchema(source.base);
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
// base schema is undefined; this is only an error if you actually try to use it
|
|
516
|
+
// allow error to be omitted if the schema is marked "lax"
|
|
517
|
+
const base = `${source.base}`
|
|
518
|
+
|
|
519
|
+
strictCompileError = new ResolverError(`Unable to resolve "${base}"`)
|
|
520
|
+
outputSchema.normalizer((value, config, location, options) => {
|
|
521
|
+
const strict = location.schema?.strict ?? options?.strict;
|
|
522
|
+
if (strict !== false) {
|
|
523
|
+
throw strictCompileError;
|
|
524
|
+
}
|
|
525
|
+
return undefined;
|
|
526
|
+
});
|
|
527
|
+
source = undefined;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
source = undefined;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
//source = (source instanceof CompiledSchema)? undefined : (source.base ? this.getSchema(source.base) : undefined);
|
|
535
|
+
}
|
|
536
|
+
if (!(inputSchema instanceof CompiledSchema) && inputSchema.base && !outputSchema.metadata.parserTypeHint) {
|
|
537
|
+
outputSchema.metadata.parserTypeHint = inputSchema.base;
|
|
538
|
+
}
|
|
539
|
+
if (outputSchema.options.strict !== false && strictCompileError) {
|
|
540
|
+
throw strictCompileError;
|
|
541
|
+
}
|
|
542
|
+
return outputSchema;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
}
|