@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
package/src/types.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} ISchema
|
|
3
|
+
* @property {string} [base] - Base schema name for extension
|
|
4
|
+
* @property {ISchemaProperties} properties - Schema properties
|
|
5
|
+
* @property {ISchemaOptions} options - Schema options
|
|
6
|
+
* @property {ISchemaMetadata} metadata - Schema metadata
|
|
7
|
+
* @property {ISchemaHandlers} handlers - Schema handlers
|
|
8
|
+
* @property {ISchemaUnion} unionSchemas - Union schema definitions
|
|
9
|
+
* @property {(schema:ISchema) => SchemaData|undefined} toData - Serialize schema to plain object
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** @import { ValueProcessorSpec } from './value-processor/value-processor.js' */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {object} ISchemaMetadataCommon
|
|
16
|
+
* @property {string} [description] - help text description of the property; used by CommandLineSource
|
|
17
|
+
* @property {string} [valueName] - help text type name of the property value; used by CommandLineSource
|
|
18
|
+
* @property {string} [valueDescription] - help text description of the property value; used by CommandLineSource
|
|
19
|
+
* @property {string} [flagHint] - request a specific flag character; used by CommandLineSource
|
|
20
|
+
* @property {boolean} [advanced] - filter from basic help text; used by CommandLineSource
|
|
21
|
+
* @property {boolean} [hidden] - hide from help; used by CommandLineSource
|
|
22
|
+
* @property {boolean} [general] - mark this field for CommandLineSource to be used without a flag or option
|
|
23
|
+
* @property {string} [parserTypeHint] - set to base/primitive types to help source parsers interpret values
|
|
24
|
+
* @property {boolean} [omitFromSerialize] - set to true to omit this schema's value when serializing
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/** @typedef {ISchemaMetadataCommon & {[key:string]: any}} ISchemaMetadata */
|
|
28
|
+
|
|
29
|
+
/** @typedef {"any"|"string"|"number"|"boolean"|"bigint"|"symbol"|"object"|"array"|"function"|"buffer"|"null"} SchemaFundamentalType */
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {object} ISchemaOptionsCommon
|
|
33
|
+
* @property {SchemaFundamentalType} [type] - should only be set on the core types supported by the schema
|
|
34
|
+
* @property {function(string,ISchema):void} [compileHook] - a function called during schema compilation
|
|
35
|
+
* @property {boolean} [allowEmpty] - whether an array type or string type can be empty
|
|
36
|
+
* @property {boolean} [allowUndefined] - whether undefined values can be passed through this schema
|
|
37
|
+
* @property {boolean} [allowErrors] - whether to throw when a processor returns an Error, or treat it as a legal value
|
|
38
|
+
* @property {boolean} [allowUnknownValues] - when true, values are advisory (for expansion/metadata) and do not gate ensureAccepts
|
|
39
|
+
* @property {boolean} [strict] - whether to do strict typechecking (defaults to true; must be explicitly false to be "lax")
|
|
40
|
+
* @property {boolean} [reference] - disallow direct assignment; value will be inherited from a parent
|
|
41
|
+
* @property {boolean} [required] - flag indicating whether this field is required
|
|
42
|
+
* @property {boolean} [literal] - flag indicating that this field always returns the option value
|
|
43
|
+
* @property {boolean} [implicit] - flag indicating that this field exists implicitly in the post-transform value
|
|
44
|
+
* @property {boolean} [dynamic] - true/undefined means treat functional values as dynamic lookups; false means treat functions as values
|
|
45
|
+
* @property {string} [context] - triggers value to be copied to the context field with this name
|
|
46
|
+
* @property {any} [default] - default value
|
|
47
|
+
* @property {Array<any>} [values] - list of legal input values for this field (each is normalized during compilation)
|
|
48
|
+
* @property {boolean} [selector] - true if this schema acts as a selector
|
|
49
|
+
* @property {boolean|string} [selection] - this schema activates if the selector matches the value, or matches this prop name if true
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/** @typedef {ISchemaOptionsCommon & {[key:string]: any}} ISchemaOptions */
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {object} ISchemaHandlers
|
|
56
|
+
* @property {Array<ValueProcessorSpec>} [normalizers]
|
|
57
|
+
* @property {Array<ValueProcessorSpec>} [conditions]
|
|
58
|
+
* @property {Array<ValueProcessorSpec>} [transformers]
|
|
59
|
+
* @property {Array<ValueProcessorSpec>} [serializers]
|
|
60
|
+
* @property {ValueProcessorSpec} [unionDiscriminator]
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @typedef {object} ISchemaMetadataAttributesCommon
|
|
67
|
+
* @property {string} [_description] - help text description of the property; used by CommandLineSource
|
|
68
|
+
* @property {string} [_valueName] - help text type name of the property value; used by CommandLineSource
|
|
69
|
+
* @property {string} [_valueDescription] - help text description of the property value; used by CommandLineSource
|
|
70
|
+
* @property {string} [_flagHint] - request a specific flag character; used by CommandLineSource
|
|
71
|
+
* @property {boolean} [_advanced] - filter from basic help text; used by CommandLineSource
|
|
72
|
+
* @property {boolean} [_hidden] - hide from help; used by CommandLineSource
|
|
73
|
+
* @property {boolean} [_general] - mark this field for CommandLineSource to be used without a flag or option
|
|
74
|
+
* @property {string} [_parserTypeHint] - set to base/primitive types to help source parsers interpret values
|
|
75
|
+
* @property {boolean} [_omitFromSerialize] - set to true to omit this schema's value when serializing
|
|
76
|
+
* @deprecated
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @typedef {ISchemaOptionsCommon & ISchemaMetadataAttributesCommon & {[key:string]: any}} ISchemaAttributes
|
|
81
|
+
* @deprecated
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @typedef {{[key:string]: ISchema}} ISchemaProperties
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @typedef {{[key:string]: ISchema}} ISchemaUnion
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @typedef {object} SchemaData
|
|
94
|
+
* @property {string} [base]
|
|
95
|
+
* @property {{[key:string]: SchemaData}} [properties]
|
|
96
|
+
* @property {{[key:string]: any}} [handlers]
|
|
97
|
+
* @property {{[key:string]: string}} [metadata]
|
|
98
|
+
* @property {{[key:string]: any}} [options]
|
|
99
|
+
* @property {{[key:string]: SchemaData}} [unionSchemas]
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
export {}; // Make this a module
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Executor } from "../executor/executor.js";
|
|
2
|
+
import { stringify } from "../helpers/stringify.js";
|
|
3
|
+
import { ValueProcessor } from './value-processor.js';
|
|
4
|
+
import { isPrimitive } from '../helpers/object.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Wrap an existing executor as a ValueProcessor
|
|
9
|
+
*
|
|
10
|
+
* @augments {ValueProcessor}
|
|
11
|
+
*/
|
|
12
|
+
export class ComposedValueProcessor extends ValueProcessor
|
|
13
|
+
{
|
|
14
|
+
/** @type {Executor<any>} */
|
|
15
|
+
#executor;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {Executor<any>} executor
|
|
19
|
+
* @param {any} spec
|
|
20
|
+
* @param {string} [description]
|
|
21
|
+
*/
|
|
22
|
+
constructor(executor, spec, description) {
|
|
23
|
+
if (executor instanceof ValueProcessor) {
|
|
24
|
+
description = executor.description;
|
|
25
|
+
}
|
|
26
|
+
if (!description && executor.isConstant) {
|
|
27
|
+
const results = executor.execute(true);
|
|
28
|
+
description = isPrimitive(results)? `${results}`: stringify(results);
|
|
29
|
+
}
|
|
30
|
+
super(spec, description);
|
|
31
|
+
this.#executor = executor;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
execute(value, target, location, options) {
|
|
35
|
+
return this.#executor.execute(value, target, location, options);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get isConstant() {
|
|
39
|
+
return this.#executor.isConstant;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ValueProcessor } from './value-processor.js';
|
|
2
|
+
import { ComposedValueProcessor } from './composed-value-processor.js';
|
|
3
|
+
import { ArrayExecutor } from '../executor/array-executor.js';
|
|
4
|
+
import { ObjectExecutor } from '../executor/object-executor.js';
|
|
5
|
+
import { ParametersValueProcessor } from './parameters-value-processor.js';
|
|
6
|
+
import { FunctionValueProcessor } from './function-value-processor.js';
|
|
7
|
+
import { ParameterizedValueProcessor } from './parameterized-value-processor.js';
|
|
8
|
+
import { SchemaCompilationError, SchemaError } from '../errors.js';
|
|
9
|
+
import { isEmpty, map } from '../helpers/object.js';
|
|
10
|
+
import { CompiledSchema } from '../compiled-schema.js';
|
|
11
|
+
|
|
12
|
+
/** @import {ValueProcessorFunction, ValueProcessorDefinition, ValueProcessorArgs} from './value-processor.js' */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @augments {ParameterizedValueProcessor}
|
|
16
|
+
*/
|
|
17
|
+
export class DefinedValueProcessor extends ParameterizedValueProcessor
|
|
18
|
+
{
|
|
19
|
+
/**
|
|
20
|
+
* @param {ValueProcessorDefinition} definition
|
|
21
|
+
* @param {ValueProcessor[]|{[parameter:string]:ValueProcessor}} [args]
|
|
22
|
+
*/
|
|
23
|
+
constructor(definition, args) {
|
|
24
|
+
|
|
25
|
+
if (!definition.keyword) {
|
|
26
|
+
throw new SchemaError('No keyword found in processor definition');
|
|
27
|
+
}
|
|
28
|
+
if (!definition.process) {
|
|
29
|
+
throw new SchemaError('No process function found in processor definition');
|
|
30
|
+
}
|
|
31
|
+
if (definition.build) {
|
|
32
|
+
// This should have been handled upstream!
|
|
33
|
+
throw new SchemaCompilationError('Internal compiler error: factory definitions unsupported by DefinedValueProcessor');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (definition instanceof CompiledSchema) {
|
|
37
|
+
// coding error!
|
|
38
|
+
throw new SchemaCompilationError('Internal compiler error: a CompiledSchema was incorrectly identified as a DefinedValueProcessor');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let argsProcessor;
|
|
42
|
+
let spec;
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if (definition.parameters !== undefined) {
|
|
46
|
+
argsProcessor = new ParametersValueProcessor(definition.parameters, args);
|
|
47
|
+
spec = {[`$${definition.keyword}`]: argsProcessor.spec}
|
|
48
|
+
}
|
|
49
|
+
else if (!isEmpty(args)) {
|
|
50
|
+
const argSpecs = map(args, arg => arg.spec);
|
|
51
|
+
|
|
52
|
+
if (Array.isArray(args)) {
|
|
53
|
+
argsProcessor = new ComposedValueProcessor(new ArrayExecutor(args), argSpecs);
|
|
54
|
+
}
|
|
55
|
+
else if (typeof args === 'object') {
|
|
56
|
+
argsProcessor = new ComposedValueProcessor(new ObjectExecutor(args), argSpecs)
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
throw new SchemaCompilationError('Internal compiler error: unsupported keyword arguments type')
|
|
60
|
+
}
|
|
61
|
+
spec = {[`$${definition.keyword}`]: argsProcessor.spec}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
spec = `$${definition.keyword}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const description = definition.description ?? (definition.describe?.(args) ?? `${definition.keyword}`)
|
|
68
|
+
|
|
69
|
+
super(new FunctionValueProcessor(definition.process), argsProcessor, spec, description);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ValueProcessor } from './value-processor.js';
|
|
2
|
+
import { SchemaLocation } from "../schema-location.js";
|
|
3
|
+
|
|
4
|
+
import { SchemaError } from '../errors.js';
|
|
5
|
+
import { isEmpty, map } from '../helpers/object.js';
|
|
6
|
+
|
|
7
|
+
/** @import {ValueProcessorFunction, ValueProcessorDefinition, ValueProcessorArgs} from './value-processor.js' */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @augments {ValueProcessor}
|
|
11
|
+
*/
|
|
12
|
+
export class FunctionValueProcessor extends ValueProcessor
|
|
13
|
+
{
|
|
14
|
+
/** @type {ValueProcessor|undefined} */
|
|
15
|
+
#argsProcessor;
|
|
16
|
+
|
|
17
|
+
/** @type {ValueProcessorFunction} */
|
|
18
|
+
#process;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {ValueProcessorFunction} process
|
|
22
|
+
* @param {ValueProcessor} [args]
|
|
23
|
+
*/
|
|
24
|
+
constructor(process, args) {
|
|
25
|
+
super();
|
|
26
|
+
|
|
27
|
+
if (args) {
|
|
28
|
+
if (!(args instanceof ValueProcessor)) {
|
|
29
|
+
throw new SchemaError('FunctionValueProcessor args must be a ValueProcessor');
|
|
30
|
+
}
|
|
31
|
+
this.#argsProcessor = args;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
this.#process = process;
|
|
35
|
+
this.spec = process;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {any} value
|
|
40
|
+
* @param {any} target
|
|
41
|
+
* @param {SchemaLocation} location
|
|
42
|
+
* @param {object} options
|
|
43
|
+
* @returns {any|null|undefined|Promise<any|null|undefined>}
|
|
44
|
+
*/
|
|
45
|
+
execute(value, target, location, options) {
|
|
46
|
+
if (this.#argsProcessor) {
|
|
47
|
+
const args = this.#argsProcessor.execute(value, target, location, options);
|
|
48
|
+
|
|
49
|
+
if (args instanceof Promise) {
|
|
50
|
+
return args.then(argsResolved => this.#process(value, target, location, {...options, args: argsResolved}))
|
|
51
|
+
}
|
|
52
|
+
return this.#process(value, target, location, {...options, args});
|
|
53
|
+
}
|
|
54
|
+
return this.#process(value, target, location, options);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {string} keyword
|
|
60
|
+
* @param {ValueProcessorArgs|undefined} args
|
|
61
|
+
* @returns {any}
|
|
62
|
+
*/
|
|
63
|
+
function getSpec(keyword, args) {
|
|
64
|
+
if (!args || isEmpty(args)) {
|
|
65
|
+
return `$${keyword}`;
|
|
66
|
+
}
|
|
67
|
+
return {[`$${keyword}`]: map(args, arg => arg.spec)};
|
|
68
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ValueProcessor } from './value-processor.js';
|
|
2
|
+
import { SchemaLocation } from "../schema-location.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @augments {ValueProcessor}
|
|
6
|
+
*/
|
|
7
|
+
export class ParameterizedValueProcessor extends ValueProcessor
|
|
8
|
+
{
|
|
9
|
+
/** @type {ValueProcessor} */
|
|
10
|
+
#mainProcessor;
|
|
11
|
+
/** @type {ValueProcessor|undefined} */
|
|
12
|
+
#argsProcessor;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {ValueProcessor} mainProcessor
|
|
16
|
+
* @param {ValueProcessor|undefined} argsProcessor
|
|
17
|
+
* @param {any} spec
|
|
18
|
+
* @param {string} [description]
|
|
19
|
+
*/
|
|
20
|
+
constructor(mainProcessor, argsProcessor, spec, description) {
|
|
21
|
+
|
|
22
|
+
super(spec, description);
|
|
23
|
+
this.#mainProcessor = mainProcessor;
|
|
24
|
+
this.#argsProcessor = argsProcessor;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {any} value
|
|
29
|
+
* @param {any} target
|
|
30
|
+
* @param {SchemaLocation} location
|
|
31
|
+
* @param {object} options
|
|
32
|
+
* @returns {any|null|undefined|Promise<any|null|undefined>}
|
|
33
|
+
*/
|
|
34
|
+
execute(value, target, location, options) {
|
|
35
|
+
if (this.#argsProcessor) {
|
|
36
|
+
const args = this.#argsProcessor.execute(value, target, location, options);
|
|
37
|
+
|
|
38
|
+
if (args instanceof Promise) {
|
|
39
|
+
return args.then(argsResolved => this.#mainProcessor.execute(value, target, location, {...options, args: argsResolved}))
|
|
40
|
+
}
|
|
41
|
+
return this.#mainProcessor.execute(value, target, location, {...options, args});
|
|
42
|
+
}
|
|
43
|
+
return this.#mainProcessor.execute(value, target, location, options);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { ConstantExecutor, Executor, toExecutor } from '../executor/executor.js';
|
|
2
|
+
import { ObjectExecutor } from '../executor/object-executor.js';
|
|
3
|
+
import { ValueProcessor } from './value-processor.js';
|
|
4
|
+
import { SchemaLocation } from "../schema-location.js";
|
|
5
|
+
import { ComposedValueProcessor } from './composed-value-processor.js';
|
|
6
|
+
import { SchemaError } from '../errors.js';
|
|
7
|
+
import { map } from '../helpers/object.js';
|
|
8
|
+
import { formatValue } from '../helpers/format.js';
|
|
9
|
+
|
|
10
|
+
/** @typedef {[key:string, executor:Executor]} ObjectExecutorEntry */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* ParametersValueProcessor is an Executor that uses a list of parameter definitions to validate and execute
|
|
14
|
+
* provided argument Executors.
|
|
15
|
+
*
|
|
16
|
+
* Parameters are managed as follows:
|
|
17
|
+
* - The first optional parameter without an explicit default will use the pipeline value as its default.
|
|
18
|
+
* - If a type option is specified, that argument will be validated against that type.
|
|
19
|
+
* - Constant executors will be checked at construction.
|
|
20
|
+
* - If all parameters are passed constant executor arguments, the entire executor will be constant.
|
|
21
|
+
* - Receiving "undefined" as an argument value at runtime should not be interpreted as a missing argument,
|
|
22
|
+
* as it may simply indicate that the value is not yet available (but may become available later.)
|
|
23
|
+
*
|
|
24
|
+
* @augments {ValueProcessor}
|
|
25
|
+
*/
|
|
26
|
+
export class ParametersValueProcessor extends ValueProcessor {
|
|
27
|
+
|
|
28
|
+
/** @type {Executor} */
|
|
29
|
+
#executor;
|
|
30
|
+
|
|
31
|
+
/** @type {object[]} */
|
|
32
|
+
#parameters;
|
|
33
|
+
|
|
34
|
+
/** @type {any} */
|
|
35
|
+
#constantValue;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {object[]} [parameters]
|
|
39
|
+
* @param {ValueProcessor[]|{[parameter:string]:ValueProcessor}} [argsProcessors]
|
|
40
|
+
*/
|
|
41
|
+
constructor(parameters = [], argsProcessors = {}) {
|
|
42
|
+
|
|
43
|
+
super();
|
|
44
|
+
|
|
45
|
+
const processorObject = {};
|
|
46
|
+
|
|
47
|
+
if (Array.isArray(argsProcessors)) {
|
|
48
|
+
if (argsProcessors.length > parameters.length) {
|
|
49
|
+
throw new SchemaError(`Too many arguments`);
|
|
50
|
+
}
|
|
51
|
+
for (let p = 0; p < parameters.length; ++p) {
|
|
52
|
+
if (p < argsProcessors.length) {
|
|
53
|
+
processorObject[parameters[p].parameter] = argsProcessors[p];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
if (Object.keys(argsProcessors).length > parameters.length) {
|
|
59
|
+
throw new SchemaError('Too many arguments');
|
|
60
|
+
}
|
|
61
|
+
for (let p = 0; p < parameters.length; ++p) {
|
|
62
|
+
const arg = argsProcessors[parameters[p].parameter];
|
|
63
|
+
if (arg) {
|
|
64
|
+
processorObject[parameters[p].parameter] = arg;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (const parameter of Object.keys(argsProcessors)) {
|
|
68
|
+
if (processorObject[parameter] === undefined) {
|
|
69
|
+
throw new SchemaError(`Unknown parameter ${parameter}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Parameter sequence matters!
|
|
75
|
+
let considerUsingInput = true;
|
|
76
|
+
let handlingUndefaultedOptionals = false;
|
|
77
|
+
|
|
78
|
+
for (let p = 0; p < parameters.length; ++p) {
|
|
79
|
+
const hasDefault = parameters[p].hasOwnProperty('default'); // we want to be able to explicitly have an undefined default
|
|
80
|
+
if (parameters[p].required) {
|
|
81
|
+
if (handlingUndefaultedOptionals) {
|
|
82
|
+
throw new SchemaError(`Required parameter ${parameters[p].parameter} cannot follow optional parameter`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (!hasDefault) {
|
|
86
|
+
if (handlingUndefaultedOptionals) {
|
|
87
|
+
considerUsingInput = false;
|
|
88
|
+
}
|
|
89
|
+
handlingUndefaultedOptionals = true;
|
|
90
|
+
}
|
|
91
|
+
if (processorObject[parameters[p].parameter] === undefined && hasDefault) {
|
|
92
|
+
processorObject[parameters[p].parameter] = new ComposedValueProcessor(new ConstantExecutor(parameters[p].default), parameters[p].default);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (processorObject[parameters[p].parameter] === undefined) {
|
|
96
|
+
if (parameters[p].required) {
|
|
97
|
+
throw new SchemaError(`Missing required argument for parameter ${parameters[p].parameter}`);
|
|
98
|
+
}
|
|
99
|
+
if (handlingUndefaultedOptionals && considerUsingInput && !hasDefault) {
|
|
100
|
+
processorObject[parameters[p].parameter] = new ComposedValueProcessor(new Executor(), '$input');
|
|
101
|
+
considerUsingInput = false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (processorObject[parameters[p].parameter]?.isConstant && parameters[p].type !== undefined) {
|
|
106
|
+
const value = processorObject[parameters[p].parameter].execute(true);
|
|
107
|
+
if (parameters[p].type !== undefined && value !== undefined && typeof value !== parameters[p].type) {
|
|
108
|
+
throw new SchemaError(`Invalid ${parameters[p].type} type for parameter "${parameters[p].parameter}"`, {value});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
this.#executor = new ObjectExecutor(processorObject);
|
|
113
|
+
this.#parameters = parameters;
|
|
114
|
+
if (this.#executor.isConstant) {
|
|
115
|
+
const args = this.#executor.execute(true);
|
|
116
|
+
this.#constantValue = this.#check(args);
|
|
117
|
+
|
|
118
|
+
let d='';
|
|
119
|
+
for (const [p,v] of Object.entries(args)) {
|
|
120
|
+
if (d.length) {
|
|
121
|
+
d += ','
|
|
122
|
+
}
|
|
123
|
+
d += `${p}=${v}`
|
|
124
|
+
}
|
|
125
|
+
this.description=`[${d}]`
|
|
126
|
+
}
|
|
127
|
+
this.spec = map(processorObject, param => param.spec);
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Note: required / default are compilation checks, not runtime!
|
|
132
|
+
// All processors should expect they may receive undefined argument values, as sometimes they are resolved
|
|
133
|
+
// dynamically and may not have a value yet. Some processors may treat this as an error and throw, others
|
|
134
|
+
// may simply return undefined. If an argument having an undefined value might lead to surprising results,
|
|
135
|
+
// it should be guarded externally. For example:
|
|
136
|
+
//
|
|
137
|
+
// .validator({$length: {min: {$reference: '^^.settings.minimum'}}})
|
|
138
|
+
//
|
|
139
|
+
// It may be the case that the reference value is not set, which would result in $length not enforcing
|
|
140
|
+
// a minimum at all. To ensure it only gets set when the dependency is available, it should be written as:
|
|
141
|
+
//
|
|
142
|
+
// .validator({$require: {$reference: '^^.settings.minimum'}})
|
|
143
|
+
|
|
144
|
+
#check(args) {
|
|
145
|
+
for (const p of this.#parameters) {
|
|
146
|
+
if (args[p.parameter] !== undefined) {
|
|
147
|
+
if (p.type && (typeof args[p.parameter] !== p.type)) {
|
|
148
|
+
throw new SchemaError(`Invalid type for parameter ${p.parameter}, expected ${p.type}`)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return args;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @param {object} args
|
|
158
|
+
* @param {any} target
|
|
159
|
+
* @param {SchemaLocation} location
|
|
160
|
+
* @param {object} options
|
|
161
|
+
* @returns {object|Promise<object>}
|
|
162
|
+
*/
|
|
163
|
+
execute(args, target, location, options) {
|
|
164
|
+
if (this.#constantValue !== undefined) {
|
|
165
|
+
return this.#constantValue;
|
|
166
|
+
}
|
|
167
|
+
const result = this.#executor.execute(args, target, location, options);
|
|
168
|
+
|
|
169
|
+
if (result instanceof Promise) {
|
|
170
|
+
return result.then(resolved => this.#check(resolved))
|
|
171
|
+
}
|
|
172
|
+
return this.#check(result);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
get isConstant() {
|
|
176
|
+
return this.#constantValue !== undefined;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ValueProcessor } from './value-processor.js';
|
|
2
|
+
import { SchemaError } from '../errors.js';
|
|
3
|
+
import { isPlainObject } from '../helpers/object.js';
|
|
4
|
+
/** @import { ValueProcessorSpec, KeywordValueProcessorSpec } from './value-processor.js' */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {ValueProcessorSpec} spec
|
|
8
|
+
* @returns {spec is KeywordValueProcessorSpec}
|
|
9
|
+
* @package
|
|
10
|
+
*/
|
|
11
|
+
export function isKeywordValueProcessorSpec(spec) {
|
|
12
|
+
|
|
13
|
+
if (typeof spec === 'string' && spec.charAt(0) === '$') {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (typeof spec === 'object' && spec !== null) {
|
|
17
|
+
const keys = Object.keys(spec);
|
|
18
|
+
if (keys.length === 1 && keys[0].charAt(0) === '$') {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {KeywordValueProcessorSpec} keywordSpec
|
|
27
|
+
* @returns {[string,any]}
|
|
28
|
+
* @package
|
|
29
|
+
*/
|
|
30
|
+
export function extractKeywordValueProcessorSpec(keywordSpec) {
|
|
31
|
+
let keyword;
|
|
32
|
+
let args = [];
|
|
33
|
+
if (typeof keywordSpec === 'string' && (keywordSpec.charAt(0) === '$')) {
|
|
34
|
+
keyword = keywordSpec.slice(1);
|
|
35
|
+
}
|
|
36
|
+
else if (typeof keywordSpec === 'object' && keywordSpec !== null) {
|
|
37
|
+
const keys = Object.keys(keywordSpec);
|
|
38
|
+
|
|
39
|
+
if (keys.length === 1 && keys[0].charAt(0) === '$') {
|
|
40
|
+
keyword = keys[0].slice(1);
|
|
41
|
+
args = keywordSpec[keys[0]];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!keyword) {
|
|
46
|
+
throw new SchemaError('Not a keyword operation');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return [keyword, args];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check whether a candidate spec is legal
|
|
54
|
+
* @param {any} spec
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
* @package
|
|
57
|
+
*/
|
|
58
|
+
export function isLegalValueProcessorSpec(spec) {
|
|
59
|
+
if (spec === null || spec === undefined) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (spec instanceof ValueProcessor) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(spec)) {
|
|
66
|
+
for (let s = 0; s < spec.length; ++s) {
|
|
67
|
+
if (!isLegalValueProcessorSpec(spec[s])) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
if (isPlainObject(spec)) {
|
|
74
|
+
let dollar = 0;
|
|
75
|
+
for (const key of Object.keys(spec)) {
|
|
76
|
+
if (key.charAt(0) === '$') {
|
|
77
|
+
dollar++
|
|
78
|
+
}
|
|
79
|
+
if (dollar > 1) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
if (key !== '$literal' && !isLegalValueProcessorSpec(spec[key])) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|