@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,85 @@
|
|
|
1
|
+
|
|
2
|
+
import { SchemaLocation } from "../../schema-location.js";
|
|
3
|
+
import { ConstraintError, ResolverError } from '../../errors.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ## $length
|
|
7
|
+
*
|
|
8
|
+
* Validates that the length of a string or array falls within specified bounds (inclusive).
|
|
9
|
+
* Can specify minimum, maximum, exact length, or any combination of min/max.
|
|
10
|
+
*
|
|
11
|
+
* For strings, length is measured in characters. For arrays, length is measured in elements.
|
|
12
|
+
*
|
|
13
|
+
* ### Parameters
|
|
14
|
+
* - `exact` (number, optional): Exact required length. If specified, min/max are ignored.
|
|
15
|
+
* - `min` (number, optional): Minimum length (inclusive). If omitted, no lower bound.
|
|
16
|
+
* - `max` (number, optional): Maximum length (inclusive). If omitted, no upper bound.
|
|
17
|
+
*
|
|
18
|
+
* - With `{min: 3, max: 10}`: strings "abc" to "abcdefghij", arrays with 3-10 elements
|
|
19
|
+
* - With `{exact: 5}`: string "hello", array [1,2,3,4,5]
|
|
20
|
+
*
|
|
21
|
+
* - With `{min: 3, max: 10}`: string "ab" (too short), array with 11 elements (too long)
|
|
22
|
+
* - With `{exact: 5}`: string "hi" (wrong length), array [1,2,3] (wrong length)
|
|
23
|
+
*
|
|
24
|
+
* ### Example
|
|
25
|
+
* ```js
|
|
26
|
+
* // Validate a username is between 3 and 32 characters
|
|
27
|
+
* new Schema('string').validator({$length: {min: 3, max: 32}})
|
|
28
|
+
*
|
|
29
|
+
* // Require an exact number of elements in an array
|
|
30
|
+
* new Schema('array').validator({$length: 3})
|
|
31
|
+
*
|
|
32
|
+
* // Validate a fixed-length code (e.g., ISO country code)
|
|
33
|
+
* new Schema('string').normalizer('$uppercase').validator({$length: {exact: 2}})
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
37
|
+
*/
|
|
38
|
+
export const LENGTH_CONSTRAINT = {
|
|
39
|
+
keyword: 'length',
|
|
40
|
+
parameters: [ { parameter: 'exact', default: undefined, type: 'number' }, { parameter: 'min', default: undefined, type: 'number' }, { parameter: 'max', default: undefined, type: 'number' } ],
|
|
41
|
+
|
|
42
|
+
process: (value, _target, _location, options) => {
|
|
43
|
+
const { min, max, exact } = options.args;
|
|
44
|
+
const length = Array.isArray(value) ? value.length : String(value).length;
|
|
45
|
+
const unit = Array.isArray(value) ? 'elements' : 'characters';
|
|
46
|
+
|
|
47
|
+
if (exact !== undefined) {
|
|
48
|
+
if (length !== exact) {
|
|
49
|
+
throw new ConstraintError(`Length must be exactly ${exact} ${unit}`);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
if (min !== undefined && length < min) {
|
|
54
|
+
throw new ConstraintError(`Length must be at least ${min} ${unit}`);
|
|
55
|
+
}
|
|
56
|
+
if (max !== undefined && length > max) {
|
|
57
|
+
throw new ConstraintError(`Length must be at most ${max} ${unit}`);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
},
|
|
61
|
+
describe: (args) => {
|
|
62
|
+
|
|
63
|
+
if (!args) {
|
|
64
|
+
return undefined; // should never happen
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const minProcessor = (Array.isArray(args)? args[0] : args.min);
|
|
68
|
+
const maxProcessor = (Array.isArray(args)? args[1] : args.max);
|
|
69
|
+
const exactProcessor = (Array.isArray(args)? args[2] : args.exact);
|
|
70
|
+
|
|
71
|
+
const min = minProcessor?.description;
|
|
72
|
+
const max = maxProcessor?.description;
|
|
73
|
+
const exact = exactProcessor?.description;
|
|
74
|
+
|
|
75
|
+
return exact !== undefined
|
|
76
|
+
? `len=${exact}`
|
|
77
|
+
: min !== undefined && max !== undefined
|
|
78
|
+
? `len=${min}-${max}`
|
|
79
|
+
: min !== undefined
|
|
80
|
+
? `len≥${min}`
|
|
81
|
+
: max !== undefined
|
|
82
|
+
? `len≤${max}`
|
|
83
|
+
: undefined
|
|
84
|
+
}
|
|
85
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
2
|
+
import { FunctionValueProcessor } from '../../value-processor/function-value-processor.js';
|
|
3
|
+
import { ObjectExecutor } from '../../executor/object-executor.js';
|
|
4
|
+
import { SchemaError } from '../../errors.js';
|
|
5
|
+
import { deepValue } from '../../helpers/deep.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ## $lookup
|
|
9
|
+
*
|
|
10
|
+
* Uses the pipeline value as a key to look up a corresponding value from the argument
|
|
11
|
+
* collection. This is the inverse of `$get`: the input value is the key, the argument is the
|
|
12
|
+
* collection.
|
|
13
|
+
*
|
|
14
|
+
* Returns `undefined` if the key is not found in the collection.
|
|
15
|
+
*
|
|
16
|
+
* ### Parameters
|
|
17
|
+
* - Object collection (object, required): The key/value lookup table.
|
|
18
|
+
*
|
|
19
|
+
* ### Example
|
|
20
|
+
* ```js
|
|
21
|
+
* // Map a string value to a numeric code
|
|
22
|
+
* new Schema('string').transformer({$lookup: {low: 1, medium: 2, high: 3}})
|
|
23
|
+
* // 'medium' → 2
|
|
24
|
+
*
|
|
25
|
+
* // Use a role name to look up its permission set
|
|
26
|
+
* new Schema('string').transformer({
|
|
27
|
+
* $lookup: {$literal: {
|
|
28
|
+
* admin: ['read', 'write', 'delete'],
|
|
29
|
+
* editor: ['read', 'write'],
|
|
30
|
+
* viewer: ['read'],
|
|
31
|
+
* }}
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* // Validate that a key exists in the table (require a defined result)
|
|
35
|
+
* new Schema('string').validator({
|
|
36
|
+
* $require: {$lookup: {$literal: {us: 'United States', uk: 'United Kingdom', ca: 'Canada'}}}
|
|
37
|
+
* })
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
41
|
+
*/
|
|
42
|
+
export const LOOKUP_OPERATOR = {
|
|
43
|
+
keyword: 'lookup',
|
|
44
|
+
parameters: [{parameter: 'from', required: true, type: 'object'}, {parameter: 'path', type: 'string'}],
|
|
45
|
+
process: (value, target, location, options) => {
|
|
46
|
+
// We have a single optional parameter "path", so we know it will automatically get populated with the input value if no argument was supplied
|
|
47
|
+
const {from, path} = options.args;
|
|
48
|
+
|
|
49
|
+
if (from === undefined || path === undefined) {
|
|
50
|
+
// we enforce argument passing during compilation; since this is an operator, receiving an undefined
|
|
51
|
+
// collection or path should just be interpreted as "not available".
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// but we do enforce proper typing!
|
|
56
|
+
if (typeof from !== 'object') {
|
|
57
|
+
throw new SchemaError('$lookup requires an object argument for "from"', {location});
|
|
58
|
+
}
|
|
59
|
+
if (typeof path !== 'string') {
|
|
60
|
+
throw new SchemaError('$lookup requires a string argument for "path"', {location});
|
|
61
|
+
}
|
|
62
|
+
return deepValue(from, path);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const LOOKUP_OPERATOR1 = {
|
|
66
|
+
keyword: 'lookup',
|
|
67
|
+
|
|
68
|
+
build: (args) => {
|
|
69
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args)) {
|
|
70
|
+
throw new SchemaError('$lookup requires an object argument (the lookup table)');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const argsSpec = Object.fromEntries(
|
|
74
|
+
Object.entries(args).map(([k, v]) => [k, v?.spec ?? v])
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return new FunctionValueProcessor(
|
|
78
|
+
(value, _target, _location, options) => {
|
|
79
|
+
return options.args?.[value];
|
|
80
|
+
},
|
|
81
|
+
new ComposedValueProcessor(new ObjectExecutor(args), {$lookup: argsSpec})
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## $lowercase
|
|
3
|
+
*
|
|
4
|
+
* Converts a string value to lowercase.
|
|
5
|
+
* Safe to use in normalize phase (non-throwing).
|
|
6
|
+
*
|
|
7
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
8
|
+
*/
|
|
9
|
+
export const LOWERCASE_OPERATOR = {
|
|
10
|
+
keyword: 'lowercase',
|
|
11
|
+
process: (value) => {
|
|
12
|
+
return String(value).toLowerCase();
|
|
13
|
+
}
|
|
14
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
3
|
+
import { FunctionValueProcessor } from '../../value-processor/function-value-processor.js';
|
|
4
|
+
import { EachExecutor } from '../../executor/each-executor.js';
|
|
5
|
+
import { isPlainObject } from '../../helpers/object.js';
|
|
6
|
+
import { ConstraintError, SchemaError } from '../../errors.js';
|
|
7
|
+
import { formatValue } from '../../helpers/format.js';
|
|
8
|
+
|
|
9
|
+
/** @import { ValueProcessorDefinition } from '../../value-processor/value-processor.js' */
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ## $map
|
|
13
|
+
*
|
|
14
|
+
* Polymorphic map operator. Applies a processor to each element of an array, or to each
|
|
15
|
+
* value of a plain object. Returns a new collection of the same shape with transformed values.
|
|
16
|
+
*
|
|
17
|
+
* - **Array input**: maps over elements; `undefined` results from the processor appear as `undefined` in output.
|
|
18
|
+
* - **Object input**: maps over values; keys are always preserved in the output.
|
|
19
|
+
* - **Non-collection input**: throws a `ConstraintError`.
|
|
20
|
+
*
|
|
21
|
+
* Note that `null` returned by the processor is the standard prune signal and will remove
|
|
22
|
+
* the element/entry from the output.
|
|
23
|
+
*
|
|
24
|
+
* ### Parameters
|
|
25
|
+
* - `processor` (any valid processor spec, required): Applied to each element or value.
|
|
26
|
+
*
|
|
27
|
+
* ### Example
|
|
28
|
+
* ```js
|
|
29
|
+
* // Uppercase every string in an array
|
|
30
|
+
* new Schema('array').transformer({$map: '$uppercase'})
|
|
31
|
+
*
|
|
32
|
+
* // Parse every element as a number
|
|
33
|
+
* new Schema('array').transformer({$map: '$number'})
|
|
34
|
+
*
|
|
35
|
+
* // Apply a pipeline to every value in an object
|
|
36
|
+
* new Schema('object').transformer({$map: ['$trim', '$lowercase']})
|
|
37
|
+
* // {name: ' Alice ', city: ' NYC '} → {name: 'alice', city: 'nyc'}
|
|
38
|
+
*
|
|
39
|
+
* // Extract a nested field from each element
|
|
40
|
+
* new Schema('array').transformer({$map: {$get: 'id'}})
|
|
41
|
+
* // [{id: 1, name: 'a'}, {id: 2, name: 'b'}] → [1, 2]
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @type {ValueProcessorDefinition}
|
|
45
|
+
*/
|
|
46
|
+
export const MAP_OPERATOR = {
|
|
47
|
+
keyword: 'map',
|
|
48
|
+
parameters: [{parameter: 'processor', required: true}],
|
|
49
|
+
build: (args) => {
|
|
50
|
+
let processor;
|
|
51
|
+
if (Array.isArray(args)) {
|
|
52
|
+
if (args.length > 1) {
|
|
53
|
+
throw new SchemaError('Expected exactly one argument for $map operator');
|
|
54
|
+
}
|
|
55
|
+
processor = args[0];
|
|
56
|
+
}
|
|
57
|
+
else if (typeof args === 'object') {
|
|
58
|
+
if (Object.keys(args).length !== 1) {
|
|
59
|
+
throw new SchemaError('Expected only "processor" argument for $map operator');
|
|
60
|
+
}
|
|
61
|
+
processor = args.processor;
|
|
62
|
+
}
|
|
63
|
+
processor ??= new FunctionValueProcessor(v => (v === undefined || v === null) ? undefined : v);
|
|
64
|
+
|
|
65
|
+
return new ComposedValueProcessor(
|
|
66
|
+
new EachExecutor(processor,
|
|
67
|
+
(input) => {
|
|
68
|
+
if (Array.isArray(input)) { return input }
|
|
69
|
+
if (isPlainObject(input)) { return Object.values(input) }
|
|
70
|
+
|
|
71
|
+
throw new ConstraintError(`$map requires an array or plain object, got ${formatValue(input)}`);
|
|
72
|
+
},
|
|
73
|
+
(output, input) => {
|
|
74
|
+
if (Array.isArray(input)) { return output }
|
|
75
|
+
if (isPlainObject(input)) {
|
|
76
|
+
return Object.fromEntries(Object.keys(input).map((key, index) => ([key, output[index]])))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
{$map: processor.spec}
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
import { FunctionValueProcessor } from '../../value-processor/function-value-processor.js';
|
|
3
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
4
|
+
import { ConstraintError, SchemaError } from '../../errors.js';
|
|
5
|
+
import { parseRegExp } from '../../helpers/regex.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ## $match
|
|
9
|
+
*
|
|
10
|
+
* Operator that executes a RegExp match against a string input and returns the extracted result.
|
|
11
|
+
* Non-string values are passed through unchanged. Returns `undefined` if the string does not match.
|
|
12
|
+
*
|
|
13
|
+
* - If the RegExp contains named capture groups (`(?<name>...)`), returns the `groups`
|
|
14
|
+
* object (ES2018 named captures) as a plain object.
|
|
15
|
+
* - Otherwise, returns a plain array of the full match and positional capture groups.
|
|
16
|
+
*
|
|
17
|
+
* ### Parameters
|
|
18
|
+
* - `pattern` (RegExp, required): The pattern to match against.
|
|
19
|
+
*
|
|
20
|
+
* ### Example
|
|
21
|
+
* ```js
|
|
22
|
+
* // Extract named capture groups from a date string
|
|
23
|
+
* new Schema('string').transformer({$match: /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/})
|
|
24
|
+
* // '2026-03-21' → {year: '2026', month: '03', day: '21'}
|
|
25
|
+
*
|
|
26
|
+
* // Extract positional captures from a version string
|
|
27
|
+
* new Schema('string').transformer({$match: /^(\d+)\.(\d+)\.(\d+)$/})
|
|
28
|
+
* // '1.2.3' → ['1.2.3', '1', '2', '3']
|
|
29
|
+
*
|
|
30
|
+
* // Use with $when to only proceed when the pattern matched
|
|
31
|
+
* new Schema('string').transformer({
|
|
32
|
+
* $when: [{$match: /^Bearer (.+)$/}]
|
|
33
|
+
* })
|
|
34
|
+
* // 'Bearer abc123' → ['Bearer abc123', 'abc123']
|
|
35
|
+
* // 'Basic xyz' → undefined (no match)
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
39
|
+
*/
|
|
40
|
+
export const MATCH_OPERATOR = {
|
|
41
|
+
keyword: 'match',
|
|
42
|
+
build: (args) => {
|
|
43
|
+
let regex = (Array.isArray(args) ? args[0] : args)?.spec;
|
|
44
|
+
if (typeof regex === 'string') {
|
|
45
|
+
regex = parseRegExp(regex);
|
|
46
|
+
}
|
|
47
|
+
if (!(regex instanceof RegExp)) {
|
|
48
|
+
throw new SchemaError('$match requires a RegExp argument');
|
|
49
|
+
}
|
|
50
|
+
return new ComposedValueProcessor(
|
|
51
|
+
new FunctionValueProcessor((value, _target, location) => {
|
|
52
|
+
if (typeof value !== 'string') {
|
|
53
|
+
throw new ConstraintError('$match requires a string input', {location});
|
|
54
|
+
}
|
|
55
|
+
const result = value.match(regex);
|
|
56
|
+
if (result === null) return undefined;
|
|
57
|
+
if (result.groups && Object.keys(result.groups).length > 0) return {...result.groups};
|
|
58
|
+
return [...result];
|
|
59
|
+
}),
|
|
60
|
+
{$match: regex},
|
|
61
|
+
`${regex}`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
import { FunctionValueProcessor } from '../../value-processor/function-value-processor.js';
|
|
3
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
4
|
+
import { ConstraintError, SchemaError } from '../../errors.js';
|
|
5
|
+
import { parseRegExp } from '../../helpers/regex.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ## $matches
|
|
9
|
+
*
|
|
10
|
+
* Constraint that tests the string representation of the input against a RegExp.
|
|
11
|
+
* Throws a `ConstraintError` if the input does not match. Returns the original value unchanged.
|
|
12
|
+
*
|
|
13
|
+
* This is the explicit constraint form; bare RegExp values in processor specs are no longer
|
|
14
|
+
* treated as implicit constraints and must be wrapped with `$matches`.
|
|
15
|
+
*
|
|
16
|
+
* ### Parameters
|
|
17
|
+
* - `pattern` (RegExp, required): The pattern to test against.
|
|
18
|
+
*
|
|
19
|
+
* ### Example
|
|
20
|
+
* ```js
|
|
21
|
+
* // Validate a semantic version string
|
|
22
|
+
* new Schema('string').validator({$matches: /^\d+\.\d+\.\d+$/})
|
|
23
|
+
*
|
|
24
|
+
* // Validate a slug (lowercase letters, numbers, hyphens only)
|
|
25
|
+
* new Schema('string').validator({$matches: /^[a-z0-9]+(?:-[a-z0-9]+)*$/})
|
|
26
|
+
*
|
|
27
|
+
* // Validate a hex color code
|
|
28
|
+
* new Schema('object', {
|
|
29
|
+
* color: new Schema('string').validator({$matches: /^#[0-9a-fA-F]{6}$/}),
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
34
|
+
*/
|
|
35
|
+
export const MATCHES_CONSTRAINT = {
|
|
36
|
+
keyword: 'matches',
|
|
37
|
+
build: (args) => {
|
|
38
|
+
let regex = (Array.isArray(args) ? args[0] : args)?.spec;
|
|
39
|
+
if (typeof regex === 'string') {
|
|
40
|
+
regex = parseRegExp(regex);
|
|
41
|
+
}
|
|
42
|
+
if (!(regex instanceof RegExp)) {
|
|
43
|
+
throw new SchemaError('$matches requires a RegExp argument');
|
|
44
|
+
}
|
|
45
|
+
const fn = new FunctionValueProcessor((value, _target, location) => {
|
|
46
|
+
if (!regex.test(String(value))) {
|
|
47
|
+
throw new ConstraintError(`Value does not match pattern ${regex}`, {location});
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
});
|
|
51
|
+
fn.description = `${regex}`;
|
|
52
|
+
return new ComposedValueProcessor(fn, {$matches: regex});
|
|
53
|
+
}
|
|
54
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { ConstraintError } from '../../errors.js';
|
|
2
|
+
import { formatValue } from '../../helpers/format.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ## $abs
|
|
6
|
+
*
|
|
7
|
+
* Returns the absolute value of a number.
|
|
8
|
+
*
|
|
9
|
+
* ### Example
|
|
10
|
+
* ```js
|
|
11
|
+
* // Normalize a signed offset to always be non-negative
|
|
12
|
+
* new Schema('number').transformer('$abs')
|
|
13
|
+
*
|
|
14
|
+
* // Ensure a distance value is always positive
|
|
15
|
+
* new Schema('object', {
|
|
16
|
+
* distance: new Schema('number').transformer('$abs'),
|
|
17
|
+
* })
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
21
|
+
*/
|
|
22
|
+
export const ABS_OPERATOR = {
|
|
23
|
+
keyword: 'abs',
|
|
24
|
+
|
|
25
|
+
process: (value, _target, location) => {
|
|
26
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
27
|
+
throw new ConstraintError(`$abs requires a finite number, got ${formatValue(value)}`, {location});
|
|
28
|
+
}
|
|
29
|
+
return Math.abs(value);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* ## $pow
|
|
35
|
+
*
|
|
36
|
+
* Raises a number to a power.
|
|
37
|
+
*
|
|
38
|
+
* - `{$pow: exponent}` — raises the input value to the given exponent
|
|
39
|
+
* - `{$pow: {exponent, base}}` — raises `base` to `exponent`, ignoring the input value
|
|
40
|
+
*
|
|
41
|
+
* ### Parameters
|
|
42
|
+
* - `exponent` (number, required): The exponent.
|
|
43
|
+
* - `base` (number, optional): Override the base. Defaults to the input value.
|
|
44
|
+
*
|
|
45
|
+
* ### Example
|
|
46
|
+
* ```js
|
|
47
|
+
* // Square the input value
|
|
48
|
+
* new Schema('number').transformer({$pow: {exponent: 2}})
|
|
49
|
+
* // 4 → 16, 3 → 9
|
|
50
|
+
*
|
|
51
|
+
* // Compute 2^n where n is the input
|
|
52
|
+
* new Schema('number').transformer({$pow: {exponent: '$number', base: 2}})
|
|
53
|
+
*
|
|
54
|
+
* // Convert bytes to kilobytes using inverse power
|
|
55
|
+
* new Schema('number').transformer({$pow: {exponent: -1}})
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
59
|
+
*/
|
|
60
|
+
export const POW_OPERATOR = {
|
|
61
|
+
keyword: 'pow',
|
|
62
|
+
parameters: [ { parameter: 'exponent', required: true }, { parameter: 'base' } ],
|
|
63
|
+
|
|
64
|
+
process: (value, _target, location, options) => {
|
|
65
|
+
const exponent = options.args['exponent'];
|
|
66
|
+
const base = options.args['base'] !== undefined ? options.args['base'] : value;
|
|
67
|
+
|
|
68
|
+
if (typeof base !== 'number' || !Number.isFinite(base)) {
|
|
69
|
+
throw new ConstraintError(`$pow requires a finite number base, got ${formatValue(base)}`, {location});
|
|
70
|
+
}
|
|
71
|
+
return Math.pow(base, exponent);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* ## $sqrt
|
|
77
|
+
*
|
|
78
|
+
* Returns the square root of a number.
|
|
79
|
+
*
|
|
80
|
+
* ### Example
|
|
81
|
+
* ```js
|
|
82
|
+
* // Compute the magnitude of a value
|
|
83
|
+
* new Schema('number').transformer('$sqrt')
|
|
84
|
+
*
|
|
85
|
+
* // Validate then take the square root
|
|
86
|
+
* new Schema('number').validator('$positive').transformer('$sqrt')
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
90
|
+
*/
|
|
91
|
+
export const SQRT_OPERATOR = {
|
|
92
|
+
keyword: 'sqrt',
|
|
93
|
+
|
|
94
|
+
process: (value, _target, location) => {
|
|
95
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
|
|
96
|
+
throw new ConstraintError(`$sqrt requires a non-negative finite number, got ${formatValue(value)}`, {location});
|
|
97
|
+
}
|
|
98
|
+
return Math.sqrt(value);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* ## $clamp
|
|
104
|
+
*
|
|
105
|
+
* Constrains a number to a `[min, max]` range by returning the nearest boundary when the value
|
|
106
|
+
* falls outside. Unlike `$range` (which throws), `$clamp` transforms.
|
|
107
|
+
*
|
|
108
|
+
* Both `min` and `max` are optional; omitting either leaves that end unclamped.
|
|
109
|
+
*
|
|
110
|
+
* ### Parameters
|
|
111
|
+
* - `min` (number, optional): Lower bound.
|
|
112
|
+
* - `max` (number, optional): Upper bound.
|
|
113
|
+
*
|
|
114
|
+
* ### Example
|
|
115
|
+
* ```js
|
|
116
|
+
* // Clamp a volume setting to [0, 100]
|
|
117
|
+
* new Schema('number').transformer({$clamp: {min: 0, max: 100}})
|
|
118
|
+
*
|
|
119
|
+
* // Clamp retry count to at most 10 (no lower bound)
|
|
120
|
+
* new Schema('number').transformer({$clamp: {max: 10}})
|
|
121
|
+
*
|
|
122
|
+
* // Ensure a timeout is at least 100ms
|
|
123
|
+
* new Schema('number').transformer({$clamp: {min: 100}})
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
127
|
+
*/
|
|
128
|
+
export const CLAMP_OPERATOR = {
|
|
129
|
+
keyword: 'clamp',
|
|
130
|
+
parameters: [ { parameter: 'min' }, { parameter: 'max' } ],
|
|
131
|
+
|
|
132
|
+
process: (value, _target, location, options) => {
|
|
133
|
+
const min = options.args['min'];
|
|
134
|
+
const max = options.args['max'];
|
|
135
|
+
|
|
136
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
137
|
+
throw new ConstraintError(`$clamp requires a finite number, got ${formatValue(value)}`, {location});
|
|
138
|
+
}
|
|
139
|
+
if (min !== undefined && (typeof min !== 'number' || !Number.isFinite(min))) {
|
|
140
|
+
throw new ConstraintError(`$clamp min must be a finite number, got ${formatValue(min)}`, {location});
|
|
141
|
+
}
|
|
142
|
+
if (max !== undefined && (typeof max !== 'number' || !Number.isFinite(max))) {
|
|
143
|
+
throw new ConstraintError(`$clamp max must be a finite number, got ${formatValue(max)}`, {location});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
let result = value;
|
|
147
|
+
if (min !== undefined) result = Math.max(min, result);
|
|
148
|
+
if (max !== undefined) result = Math.min(max, result);
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
|
|
2
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
3
|
+
import { FunctionValueProcessor } from '../../value-processor/function-value-processor.js';
|
|
4
|
+
import { ObjectExecutor } from '../../executor/object-executor.js';
|
|
5
|
+
import { deepMerge } from '../../helpers/deep.js';
|
|
6
|
+
import { ConstraintError, SchemaError } from '../../errors.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* ## $merge-deep
|
|
10
|
+
*
|
|
11
|
+
* Recursively deep-merges the argument object into the input object, returning
|
|
12
|
+
* a new object. Nested plain objects are merged rather than replaced; arrays
|
|
13
|
+
* and primitive values are overwritten. The input is not mutated.
|
|
14
|
+
*
|
|
15
|
+
* Use `$merge` for shallow (one-level) merging.
|
|
16
|
+
*
|
|
17
|
+
* ### Parameters
|
|
18
|
+
* - Object of fields to deep-merge (object, required): Key/value pairs to apply over the input.
|
|
19
|
+
*
|
|
20
|
+
* ### Example
|
|
21
|
+
* ```js
|
|
22
|
+
* // Deep-merge default nested config into the user-supplied object
|
|
23
|
+
* new Schema('object').transformer({
|
|
24
|
+
* '$merge-deep': {
|
|
25
|
+
* logging: {level: 'info', format: 'json'},
|
|
26
|
+
* server: {port: 3000},
|
|
27
|
+
* }
|
|
28
|
+
* })
|
|
29
|
+
* // {logging: {level: 'debug'}, server: {host: 'localhost'}}
|
|
30
|
+
* // → {logging: {level: 'debug', format: 'json'}, server: {host: 'localhost', port: 3000}}
|
|
31
|
+
*
|
|
32
|
+
* // Inject a nested metadata field without overwriting sibling keys
|
|
33
|
+
* new Schema('object').transformer({'$merge-deep': {meta: {version: 1}}})
|
|
34
|
+
* // {meta: {author: 'rg'}} → {meta: {author: 'rg', version: 1}}
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
38
|
+
*/
|
|
39
|
+
export const MERGE_DEEP_OPERATOR = {
|
|
40
|
+
keyword: 'merge-deep',
|
|
41
|
+
|
|
42
|
+
build: (args) => {
|
|
43
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args)) {
|
|
44
|
+
throw new SchemaError('$merge-deep requires an object argument');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const argsSpec = Object.fromEntries(
|
|
48
|
+
Object.entries(args).map(([k, v]) => [k, v?.spec ?? v])
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return new FunctionValueProcessor(
|
|
52
|
+
(value, _target, location, options) => {
|
|
53
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
54
|
+
throw new ConstraintError(`$merge-deep requires a plain object input`, {location});
|
|
55
|
+
}
|
|
56
|
+
return deepMerge({}, value, options.args);
|
|
57
|
+
},
|
|
58
|
+
new ComposedValueProcessor(new ObjectExecutor(args), {'$merge-deep': argsSpec})
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
3
|
+
import { FunctionValueProcessor } from '../../value-processor/function-value-processor.js';
|
|
4
|
+
import { ObjectExecutor } from '../../executor/object-executor.js';
|
|
5
|
+
import { ConstraintError, SchemaError } from '../../errors.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ## $merge
|
|
9
|
+
*
|
|
10
|
+
* Merges the argument object into the input object (shallow). The argument fields take
|
|
11
|
+
* precedence over same-named fields in the input, consistent with the "apply to the
|
|
12
|
+
* value being passed through" pattern.
|
|
13
|
+
*
|
|
14
|
+
* The input object is not mutated; a new object is returned.
|
|
15
|
+
*
|
|
16
|
+
* ### Parameters
|
|
17
|
+
* - Object of fields to merge (object, required): Key/value pairs to apply over the input.
|
|
18
|
+
*
|
|
19
|
+
* ### Example
|
|
20
|
+
* ```js
|
|
21
|
+
* // Inject default fields into every output object
|
|
22
|
+
* new Schema('object').transformer({$merge: {version: 1, active: true}})
|
|
23
|
+
* // {id: 42} → {id: 42, version: 1, active: true}
|
|
24
|
+
*
|
|
25
|
+
* // Overwrite a specific field in the result
|
|
26
|
+
* new Schema('object').transformer({$merge: {status: 'normalized'}})
|
|
27
|
+
* // {id: 1, status: 'raw'} → {id: 1, status: 'normalized'}
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
31
|
+
*/
|
|
32
|
+
export const MERGE_OPERATOR = {
|
|
33
|
+
keyword: 'merge',
|
|
34
|
+
|
|
35
|
+
build: (args) => {
|
|
36
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args)) {
|
|
37
|
+
throw new SchemaError('$merge requires an object argument');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const argsSpec = Object.fromEntries(
|
|
41
|
+
Object.entries(args).map(([k, v]) => [k, v?.spec ?? v])
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return new FunctionValueProcessor(
|
|
45
|
+
(value, _target, location, options) => {
|
|
46
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
47
|
+
throw new ConstraintError(`$merge requires a plain object input`, {location});
|
|
48
|
+
}
|
|
49
|
+
return {...value, ...options.args};
|
|
50
|
+
},
|
|
51
|
+
new ComposedValueProcessor(new ObjectExecutor(args), {$merge: argsSpec})
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
};
|