@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,406 @@
|
|
|
1
|
+
|
|
2
|
+
import { ConditionalExecutor } from '../../executor/conditional-executor.js';
|
|
3
|
+
import { ValueProcessor } from '../../value-processor/value-processor.js';
|
|
4
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
5
|
+
import { SequenceExecutor } from '../../executor/sequence-executor.js';
|
|
6
|
+
import { ConstraintError, ResolverError } from '../../errors.js';
|
|
7
|
+
import { formatValue } from '../../helpers/format.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @import {ValueProcessorDefinition} from '../../value-processor/value-processor.js'
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {string} keyword
|
|
16
|
+
* @param {string} joiner
|
|
17
|
+
* @param {(processors:ValueProcessor[], spec:any, description:string) => ValueProcessor} builder
|
|
18
|
+
* @returns {function(*): *}
|
|
19
|
+
* @package
|
|
20
|
+
*/
|
|
21
|
+
function generateBuilderFunction(keyword, joiner, builder) {
|
|
22
|
+
return (args) => {
|
|
23
|
+
|
|
24
|
+
let processors;
|
|
25
|
+
if (Array.isArray(args)) {
|
|
26
|
+
processors = args;
|
|
27
|
+
}
|
|
28
|
+
else if (typeof args === 'object' && args !== null) {
|
|
29
|
+
processors = Object.values(args);
|
|
30
|
+
}
|
|
31
|
+
if (!Array.isArray(processors)) {
|
|
32
|
+
throw new ResolverError(`${keyword} requires an array of processors`);
|
|
33
|
+
}
|
|
34
|
+
const spec = {[keyword]: processors.map(a => a.spec)};
|
|
35
|
+
const descriptions = processors.map(c => c.description).filter((d) => d !== undefined);
|
|
36
|
+
const description = descriptions.length > 1
|
|
37
|
+
? descriptions.map(d => d.includes('&') ? `(${d})` : d).join(joiner)
|
|
38
|
+
: descriptions[0]
|
|
39
|
+
|
|
40
|
+
return builder(processors, spec, description);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* ## $or
|
|
47
|
+
*
|
|
48
|
+
* A constraint that checks whether any of the provided processors return a truthy value.
|
|
49
|
+
*
|
|
50
|
+
* Returns the first truthy value from the processors, or throws if none are truthy.
|
|
51
|
+
* Be careful to not use this in a situation where the provided processors may require late-resolved values!
|
|
52
|
+
* This works best in finalizers, validators, or in opaque schema transformers.
|
|
53
|
+
*
|
|
54
|
+
* See `$any` if you want to check for success (defined value) instead of truthiness
|
|
55
|
+
*
|
|
56
|
+
* ### Parameters
|
|
57
|
+
* - `processors` (`Array<ProcessorSpec>`, required): Array of processor specifications, at least one of which must return a truthy value.
|
|
58
|
+
*
|
|
59
|
+
* ### Example
|
|
60
|
+
* ```js
|
|
61
|
+
* // Accept either a valid hostname or a valid IPv4 address
|
|
62
|
+
* new Schema('string').validator({$or: ['$hostname', '$ipv4']})
|
|
63
|
+
*
|
|
64
|
+
* // Accept a port number OR the string 'auto'
|
|
65
|
+
* new Schema('any').validator({
|
|
66
|
+
* $or: [
|
|
67
|
+
* {$range: {min: 1, max: 65535}},
|
|
68
|
+
* {$eq: 'auto'},
|
|
69
|
+
* ]
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @type {ValueProcessorDefinition}
|
|
74
|
+
*/
|
|
75
|
+
export const OR_CONSTRAINT = {
|
|
76
|
+
keyword: 'or',
|
|
77
|
+
build: generateBuilderFunction('$or', ' | ',
|
|
78
|
+
(processors, spec, description) => (
|
|
79
|
+
new ComposedValueProcessor(
|
|
80
|
+
new ConditionalExecutor(
|
|
81
|
+
new SequenceExecutor(processors, [
|
|
82
|
+
SequenceExecutor.TRUTHY_CHECK,
|
|
83
|
+
SequenceExecutor.ANY_CRITERIA,
|
|
84
|
+
SequenceExecutor.RESULT_RETURN,
|
|
85
|
+
SequenceExecutor.CAPTURE_ERRORS
|
|
86
|
+
]),
|
|
87
|
+
{
|
|
88
|
+
failure: (value) => {
|
|
89
|
+
throw new ConstraintError(`None of the $or conditions ${formatValue(description)} matched`,{value});
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
[ConditionalExecutor.CHECK_TRUTHY]
|
|
93
|
+
), spec, description)
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* ## $and
|
|
100
|
+
*
|
|
101
|
+
* A constraint that checks whether all the provided processors return a truthy value.
|
|
102
|
+
*
|
|
103
|
+
* Returns the last truthy value from the processors, or throws if any are falsey.
|
|
104
|
+
* Be careful to not use this in a situation where the provided processors may require late-resolved values!
|
|
105
|
+
* This works best in finalizers, validators, or in opaque schema transformers.
|
|
106
|
+
*
|
|
107
|
+
* See `$all` if you want to check for success (defined value) instead of truthiness
|
|
108
|
+
*
|
|
109
|
+
* ### Parameters
|
|
110
|
+
* - `processors` (`Array<ProcessorSpec>`, required): Array of processor specifications, all of which must return a truthy value.
|
|
111
|
+
*
|
|
112
|
+
* ### Example
|
|
113
|
+
* ```js
|
|
114
|
+
* // Require a string to be both non-empty and a valid email
|
|
115
|
+
* new Schema('string').validator({$and: ['$non-empty', '$email']})
|
|
116
|
+
*
|
|
117
|
+
* // Require a number to be positive and within range
|
|
118
|
+
* new Schema('number').validator({
|
|
119
|
+
* $and: ['$positive', {$range: {max: 1000}}]
|
|
120
|
+
* })
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* @type {ValueProcessorDefinition}
|
|
124
|
+
*/
|
|
125
|
+
export const AND_CONSTRAINT = {
|
|
126
|
+
keyword: 'and',
|
|
127
|
+
build: generateBuilderFunction('$and', ' & ',
|
|
128
|
+
(processors, spec, description) => (
|
|
129
|
+
new ComposedValueProcessor(
|
|
130
|
+
new ConditionalExecutor(
|
|
131
|
+
new SequenceExecutor(processors, [
|
|
132
|
+
SequenceExecutor.TRUTHY_CHECK,
|
|
133
|
+
SequenceExecutor.ALL_CRITERIA,
|
|
134
|
+
SequenceExecutor.RESULT_RETURN,
|
|
135
|
+
SequenceExecutor.CAPTURE_ERRORS
|
|
136
|
+
]),
|
|
137
|
+
{
|
|
138
|
+
failure: (value) => {
|
|
139
|
+
throw new ConstraintError(`Not all $and conditions ${formatValue(description)} matched`, {value});
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
[ConditionalExecutor.CHECK_TRUTHY]
|
|
143
|
+
), spec, description)
|
|
144
|
+
)
|
|
145
|
+
)
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* ## $any
|
|
150
|
+
*
|
|
151
|
+
* A constraint that checks whether any of the provided processors return a defined value.
|
|
152
|
+
* (Not to be confused with the unrelated "any" schema!)
|
|
153
|
+
*
|
|
154
|
+
* Returns the first defined value from the processors, or throws if none returned a defined value.
|
|
155
|
+
* Be careful to not use this in a situation where the provided processors may require late-resolved values!
|
|
156
|
+
* This works best in finalizers, validators, or in opaque schema transformers.
|
|
157
|
+
*
|
|
158
|
+
* See `$or` if you want to check for truthiness instead of a defined value.
|
|
159
|
+
*
|
|
160
|
+
* ### Parameters
|
|
161
|
+
* - `processors` (`Array<ProcessorSpec>`, required): Array of processor specifications, at least one of which must return a defined value.
|
|
162
|
+
*
|
|
163
|
+
* ### Example
|
|
164
|
+
* ```js
|
|
165
|
+
* // Accept a value that matches any of several pattern-based normalizations
|
|
166
|
+
* new Schema('string').normalizer({
|
|
167
|
+
* $any: [
|
|
168
|
+
* {$match: /^\d+$/},
|
|
169
|
+
* {$match: /^[a-f0-9]+$/i},
|
|
170
|
+
* ]
|
|
171
|
+
* })
|
|
172
|
+
*
|
|
173
|
+
* // Require a value that can be processed by at least one schema
|
|
174
|
+
* new Schema('any').validator({$any: ['$numeric', '$boolean', '$date']})
|
|
175
|
+
* ```
|
|
176
|
+
*
|
|
177
|
+
* @type {ValueProcessorDefinition}
|
|
178
|
+
*/
|
|
179
|
+
export const ANY_CONSTRAINT = {
|
|
180
|
+
keyword: 'any',
|
|
181
|
+
build: generateBuilderFunction('$any', ' ∧ ',
|
|
182
|
+
(processors, spec, description) => (
|
|
183
|
+
new ComposedValueProcessor(
|
|
184
|
+
new ConditionalExecutor(
|
|
185
|
+
new SequenceExecutor(processors, [
|
|
186
|
+
SequenceExecutor.DEFINED_CHECK,
|
|
187
|
+
SequenceExecutor.ANY_CRITERIA,
|
|
188
|
+
SequenceExecutor.RESULT_RETURN,
|
|
189
|
+
SequenceExecutor.CAPTURE_ERRORS
|
|
190
|
+
]),
|
|
191
|
+
{
|
|
192
|
+
failure: (value) => {
|
|
193
|
+
throw new ConstraintError(`None of the $any conditions ${formatValue(description)} succeeded`, {value});
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
[ConditionalExecutor.CHECK_DEFINED]
|
|
197
|
+
), spec, description)
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* ## $all
|
|
204
|
+
*
|
|
205
|
+
* A constraint that checks whether all the provided processors return a defined value.
|
|
206
|
+
*
|
|
207
|
+
* Returns the last defined value returned from the processors, or throws if any returned undefined or threw an error.
|
|
208
|
+
* Be careful to not use this in a situation where the provided processors may require late-resolved values!
|
|
209
|
+
* This works best in finalizers, validators, or in opaque schema transformers.
|
|
210
|
+
*
|
|
211
|
+
* See `$and` if you want to check for truthiness instead of defined values.
|
|
212
|
+
*
|
|
213
|
+
* ### Parameters
|
|
214
|
+
* - `processors` (`Array<ProcessorSpec>`, required): Array of processor specifications, all of which must return a defined value.
|
|
215
|
+
*
|
|
216
|
+
* ### Example
|
|
217
|
+
* ```js
|
|
218
|
+
* // Validate that all normalizations succeed for a value that must satisfy multiple constraints
|
|
219
|
+
* new Schema('string').validator({
|
|
220
|
+
* $all: ['$non-empty', '$email', {$matches: /\.com$/}]
|
|
221
|
+
* })
|
|
222
|
+
*
|
|
223
|
+
* // Ensure a value passes both a type check and a range constraint
|
|
224
|
+
* new Schema('any').validator({$all: ['$numeric', {$range: {min: 0, max: 100}}]})
|
|
225
|
+
* ```
|
|
226
|
+
*
|
|
227
|
+
* @type {ValueProcessorDefinition}
|
|
228
|
+
*/
|
|
229
|
+
export const ALL_CONSTRAINT = {
|
|
230
|
+
keyword: 'all',
|
|
231
|
+
build: generateBuilderFunction('$all', ' · ',
|
|
232
|
+
(processors, spec, description) => (
|
|
233
|
+
new ComposedValueProcessor(
|
|
234
|
+
new ConditionalExecutor(
|
|
235
|
+
new SequenceExecutor(processors, [
|
|
236
|
+
SequenceExecutor.DEFINED_CHECK,
|
|
237
|
+
SequenceExecutor.ALL_CRITERIA,
|
|
238
|
+
SequenceExecutor.RESULT_RETURN,
|
|
239
|
+
SequenceExecutor.CAPTURE_ERRORS
|
|
240
|
+
]),
|
|
241
|
+
{
|
|
242
|
+
failure: (value) => {
|
|
243
|
+
throw new ConstraintError(`Not all $all conditions ${formatValue(description)} succeeded`, {value})
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
[ConditionalExecutor.CHECK_DEFINED]
|
|
247
|
+
), spec, description)
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* ## $exclusive
|
|
256
|
+
*
|
|
257
|
+
* A constraint that checks whether exactly one of the provided processors returns a truthy value.
|
|
258
|
+
*
|
|
259
|
+
* Returns the single truthy value, or throws if zero or more than one are truthy.
|
|
260
|
+
* Be careful to not use this in a situation where the provided processors may require late-resolved values!
|
|
261
|
+
* This works best in finalizers, validators, or in opaque schema transformers.
|
|
262
|
+
*
|
|
263
|
+
* See `$one` if you want to check for success (defined value) instead of truthiness.
|
|
264
|
+
*
|
|
265
|
+
* ### Parameters
|
|
266
|
+
* - `processors` (`Array<ProcessorSpec>`, required): Array of processor specifications, exactly one of which must return a truthy value.
|
|
267
|
+
*
|
|
268
|
+
* ### Example
|
|
269
|
+
* ```js
|
|
270
|
+
* // A form field must have either an email or a phone number, but not both
|
|
271
|
+
* new Schema('object').validator({
|
|
272
|
+
* $exclusive: [
|
|
273
|
+
* {$property: 'email'},
|
|
274
|
+
* {$property: 'phone'},
|
|
275
|
+
* ]
|
|
276
|
+
* })
|
|
277
|
+
* ```
|
|
278
|
+
*
|
|
279
|
+
* @type {ValueProcessorDefinition}
|
|
280
|
+
*/
|
|
281
|
+
export const EXCLUSIVE_CONSTRAINT = {
|
|
282
|
+
keyword: 'exclusive',
|
|
283
|
+
build: generateBuilderFunction('$exclusive', ' ⊕ ',
|
|
284
|
+
(processors, spec, description) => (
|
|
285
|
+
new ComposedValueProcessor(
|
|
286
|
+
new ConditionalExecutor(
|
|
287
|
+
new SequenceExecutor(processors, [
|
|
288
|
+
SequenceExecutor.TRUTHY_CHECK,
|
|
289
|
+
SequenceExecutor.EXCLUSIVE_CRITERIA,
|
|
290
|
+
SequenceExecutor.RESULT_RETURN,
|
|
291
|
+
SequenceExecutor.CAPTURE_ERRORS
|
|
292
|
+
]),
|
|
293
|
+
{
|
|
294
|
+
failure: (value) => {
|
|
295
|
+
throw new ConstraintError(`Exactly one of the $exclusive conditions ${formatValue(description)} must match`, {value});
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
[ConditionalExecutor.CHECK_TRUTHY]
|
|
299
|
+
), spec, description)
|
|
300
|
+
)
|
|
301
|
+
)
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* ## $one
|
|
306
|
+
*
|
|
307
|
+
* A constraint that checks whether exactly one of the provided processors returns a defined value.
|
|
308
|
+
*
|
|
309
|
+
* Returns the single defined value, or throws if zero or more than one succeed.
|
|
310
|
+
* Be careful to not use this in a situation where the provided processors may require late-resolved values!
|
|
311
|
+
* This works best in finalizers, validators, or in opaque schema transformers.
|
|
312
|
+
*
|
|
313
|
+
* See `$exclusive` if you want to check for truthiness instead of a defined value.
|
|
314
|
+
*
|
|
315
|
+
* ### Parameters
|
|
316
|
+
* - `processors` (`Array<ProcessorSpec>`, required): Array of processor specifications, exactly one of which must return a defined value.
|
|
317
|
+
*
|
|
318
|
+
* ### Example
|
|
319
|
+
* ```js
|
|
320
|
+
* // Exactly one authentication method must be configured
|
|
321
|
+
* new Schema('object').validator({
|
|
322
|
+
* $one: [
|
|
323
|
+
* {$property: 'apiKey'},
|
|
324
|
+
* {$property: 'oauth'},
|
|
325
|
+
* {$property: 'basicAuth'},
|
|
326
|
+
* ]
|
|
327
|
+
* })
|
|
328
|
+
* ```
|
|
329
|
+
*
|
|
330
|
+
* @type {ValueProcessorDefinition}
|
|
331
|
+
*/
|
|
332
|
+
export const ONE_CONSTRAINT = {
|
|
333
|
+
keyword: 'one',
|
|
334
|
+
build: generateBuilderFunction('$one', ' ⊕ ',
|
|
335
|
+
(processors, spec, description) => (
|
|
336
|
+
new ComposedValueProcessor(
|
|
337
|
+
new ConditionalExecutor(
|
|
338
|
+
new SequenceExecutor(processors, [
|
|
339
|
+
SequenceExecutor.DEFINED_CHECK,
|
|
340
|
+
SequenceExecutor.EXCLUSIVE_CRITERIA,
|
|
341
|
+
SequenceExecutor.RESULT_RETURN,
|
|
342
|
+
SequenceExecutor.CAPTURE_ERRORS
|
|
343
|
+
]),
|
|
344
|
+
{
|
|
345
|
+
failure: (value) => {
|
|
346
|
+
throw new ConstraintError(`Exactly one of the $one conditions ${formatValue(description)} must succeed`, {value});
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
[ConditionalExecutor.CHECK_DEFINED]
|
|
350
|
+
), spec, description)
|
|
351
|
+
)
|
|
352
|
+
)
|
|
353
|
+
};
|
|
354
|
+
/**
|
|
355
|
+
* ## $first
|
|
356
|
+
*
|
|
357
|
+
* An operator that returns the first defined value successfully returned from a sequence of processors.
|
|
358
|
+
*
|
|
359
|
+
* Unlike `$any`, no exception is thrown if there are no defined results, it simply returns `undefined`.
|
|
360
|
+
* Be careful to not use this in a situation where the provided processors may require late-resolved values!
|
|
361
|
+
* This works best in finalizers, validators, or in opaque schema transformers.
|
|
362
|
+
*
|
|
363
|
+
* There is no truthy variant of `$first`, as there generally isn't much value in differentiating which
|
|
364
|
+
* truthy value to return; use constructs like `{$if: {$or: [...]}}` to wrap truthy sequence constraints as operators.
|
|
365
|
+
* `$first` is basically an alias for `{$gate: {$any: [...]}}`.
|
|
366
|
+
*
|
|
367
|
+
* ### Parameters
|
|
368
|
+
* - `processors` (`Array<ProcessorSpec>`, required): Array of processor specifications to try in order.
|
|
369
|
+
*
|
|
370
|
+
* ### Example
|
|
371
|
+
* ```js
|
|
372
|
+
* // Try several environment variable names and return the first one that has a value
|
|
373
|
+
* new Schema('object').transformer({
|
|
374
|
+
* $first: [
|
|
375
|
+
* {$reference: 'DATABASE_URL'},
|
|
376
|
+
* {$reference: 'DB_URL'},
|
|
377
|
+
* {$reference: 'POSTGRES_URL'},
|
|
378
|
+
* ]
|
|
379
|
+
* })
|
|
380
|
+
*
|
|
381
|
+
* // Return the first successfully parsed format
|
|
382
|
+
* new Schema('string').normalizer({
|
|
383
|
+
* $first: ['$number', '$date', '$boolean']
|
|
384
|
+
* })
|
|
385
|
+
* ```
|
|
386
|
+
*
|
|
387
|
+
* @type {ValueProcessorDefinition}
|
|
388
|
+
*/
|
|
389
|
+
export const FIRST_OPERATOR = {
|
|
390
|
+
keyword: 'first',
|
|
391
|
+
build: generateBuilderFunction('$first', ' ?? ',
|
|
392
|
+
(processors, spec, description) => (
|
|
393
|
+
new ComposedValueProcessor(
|
|
394
|
+
new ConditionalExecutor(
|
|
395
|
+
new SequenceExecutor(processors, [
|
|
396
|
+
SequenceExecutor.DEFINED_CHECK,
|
|
397
|
+
SequenceExecutor.ANY_CRITERIA,
|
|
398
|
+
SequenceExecutor.RESULT_RETURN,
|
|
399
|
+
SequenceExecutor.CAPTURE_ERRORS
|
|
400
|
+
]),
|
|
401
|
+
{},
|
|
402
|
+
[ConditionalExecutor.CHECK_DEFINED, ConditionalExecutor.PASS_RESULT]
|
|
403
|
+
), spec, description)
|
|
404
|
+
)
|
|
405
|
+
)
|
|
406
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ConstraintError } from '../../errors.js';
|
|
2
|
+
import { formatValue } from '../../helpers/format.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ## $sort
|
|
6
|
+
*
|
|
7
|
+
* Returns a new sorted array. Non-mutating. Numbers are compared numerically;
|
|
8
|
+
* all other values are compared lexicographically as strings.
|
|
9
|
+
* Throws if the input is not an array.
|
|
10
|
+
*
|
|
11
|
+
* ### Parameters
|
|
12
|
+
* - `key` (string|null, optional, default `null`): Object property key to sort by.
|
|
13
|
+
* - `direction` (`'asc'`|`'desc'`, optional, default `'asc'`): Sort direction.
|
|
14
|
+
*
|
|
15
|
+
* ### Example
|
|
16
|
+
* ```js
|
|
17
|
+
* // Sort an array of numbers in ascending order
|
|
18
|
+
* new Schema('array').transformer('$sort')
|
|
19
|
+
* // [3, 1, 2] → [1, 2, 3]
|
|
20
|
+
*
|
|
21
|
+
* // Sort strings in descending order
|
|
22
|
+
* new Schema('array').transformer({$sort: {direction: 'desc'}})
|
|
23
|
+
*
|
|
24
|
+
* // Sort an array of objects by a property
|
|
25
|
+
* new Schema('array').transformer({$sort: {key: 'name'}})
|
|
26
|
+
* // [{name: 'Charlie'}, {name: 'Alice'}] → [{name: 'Alice'}, {name: 'Charlie'}]
|
|
27
|
+
*
|
|
28
|
+
* // Sort objects by a numeric property descending
|
|
29
|
+
* new Schema('array').transformer({$sort: {key: 'score', direction: 'desc'}})
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
33
|
+
*/
|
|
34
|
+
export const SORT_OPERATOR = {
|
|
35
|
+
keyword: 'sort',
|
|
36
|
+
parameters: [ { parameter: 'key', default: null }, { parameter: 'direction', default: 'asc' } ],
|
|
37
|
+
|
|
38
|
+
process: (value, _target, location, options) => {
|
|
39
|
+
if (!Array.isArray(value)) {
|
|
40
|
+
throw new ConstraintError(`$sort requires an array, got ${formatValue(value)}`, {location});
|
|
41
|
+
}
|
|
42
|
+
const key = options.args?.['key'] ?? null;
|
|
43
|
+
const direction = options.args?.['direction'] ?? 'asc';
|
|
44
|
+
|
|
45
|
+
const cmp = (a, b) => (typeof a === 'number' && typeof b === 'number')
|
|
46
|
+
? a - b
|
|
47
|
+
: String(a) < String(b) ? -1 : String(a) > String(b) ? 1 : 0;
|
|
48
|
+
|
|
49
|
+
const sorted = [...value].sort(key ? (a, b) => cmp(a[key], b[key]) : cmp);
|
|
50
|
+
return direction === 'desc' ? sorted.reverse() : sorted;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## $split
|
|
3
|
+
*
|
|
4
|
+
* Stringify the input and split on the provided separator, returning an array.
|
|
5
|
+
*
|
|
6
|
+
* ### Parameters
|
|
7
|
+
* - `separator` (string, optional, defaults to ","): The value to use for splitting
|
|
8
|
+
* - `limit` (integer, optional): The maximum number of elements to return.
|
|
9
|
+
*
|
|
10
|
+
* Note that RegExp separators must be wrapped in a `$literal` to prevent evaluation as constraints.
|
|
11
|
+
* Otherwise, follows the behavior of JavaScript's String.prototype.split.
|
|
12
|
+
*
|
|
13
|
+
* ### Example
|
|
14
|
+
* ```js
|
|
15
|
+
* // Split a comma-separated list into an array
|
|
16
|
+
* new Schema('string').transformer('$split')
|
|
17
|
+
* // 'a,b,c' → ['a', 'b', 'c']
|
|
18
|
+
*
|
|
19
|
+
* // Split on a custom separator
|
|
20
|
+
* new Schema('string').transformer({$split: {separator: ':'}})
|
|
21
|
+
* // 'host:port' → ['host', 'port']
|
|
22
|
+
*
|
|
23
|
+
* // Split then normalize each element
|
|
24
|
+
* new Schema('string').normalizer([{$split: {separator: ','}}, {$each: '$trim'}])
|
|
25
|
+
* // ' a , b , c ' → ['a', 'b', 'c']
|
|
26
|
+
*
|
|
27
|
+
* // Split a PATH-style variable, limiting to 5 segments
|
|
28
|
+
* new Schema('string').transformer({$split: {separator: '/', limit: 5}})
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}*
|
|
32
|
+
*/
|
|
33
|
+
export const SPLIT_OPERATOR = {
|
|
34
|
+
keyword: 'split',
|
|
35
|
+
parameters: [ { parameter: 'separator', default: ',' }, { parameter: 'limit', default: undefined } ],
|
|
36
|
+
|
|
37
|
+
process: (value, _target, _location, options) => {
|
|
38
|
+
const separator = options.args?.['separator'];
|
|
39
|
+
const limit = options.args?.['limit'];
|
|
40
|
+
|
|
41
|
+
return `${value}`.split(separator, limit);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
|
|
2
|
+
import { FunctionValueProcessor } from '../../value-processor/function-value-processor.js';
|
|
3
|
+
import { ConstraintError, SchemaError } from '../../errors.js';
|
|
4
|
+
import { formatValue } from '../../helpers/format.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ## $replace
|
|
8
|
+
*
|
|
9
|
+
* Replaces occurrences of a pattern in a string.
|
|
10
|
+
*
|
|
11
|
+
* - Pattern may be a string (replaced globally via `replaceAll`) or a RegExp (flags control global).
|
|
12
|
+
* - Replacement must be a string.
|
|
13
|
+
*
|
|
14
|
+
* ### Parameters
|
|
15
|
+
* - First positional: pattern (string or RegExp, required)
|
|
16
|
+
* - Second positional: replacement (string, required)
|
|
17
|
+
*
|
|
18
|
+
* ### Example
|
|
19
|
+
* ```js
|
|
20
|
+
* // Replace all underscores with hyphens
|
|
21
|
+
* new Schema('string').transformer({$replace: ['_', '-']})
|
|
22
|
+
* // 'hello_world' → 'hello-world'
|
|
23
|
+
*
|
|
24
|
+
* // Strip all non-digit characters using a RegExp
|
|
25
|
+
* new Schema('string').normalizer({$replace: [/\D+/g, '']})
|
|
26
|
+
* // '+1 (800) 555-1234' → '18005551234'
|
|
27
|
+
*
|
|
28
|
+
* // Redact sensitive patterns
|
|
29
|
+
* new Schema('string').transformer({$replace: [/\b\d{4}-\d{4}-\d{4}-\d{4}\b/g, '[REDACTED]']})
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
33
|
+
*/
|
|
34
|
+
export const REPLACE_OPERATOR = {
|
|
35
|
+
keyword: 'replace',
|
|
36
|
+
parameters: [{parameter: 'pattern', required: true}, {parameter: 'replacement', required: true, type: 'string'}],
|
|
37
|
+
process: (value, _target, location, options) => {
|
|
38
|
+
const {pattern, replacement} = options.args;
|
|
39
|
+
if (typeof pattern !== 'string' && !(pattern instanceof RegExp)) {
|
|
40
|
+
throw new SchemaError(`$replace pattern must be a string or RegExp, got ${formatValue(pattern)}`);
|
|
41
|
+
}
|
|
42
|
+
if (typeof replacement !== 'string') {
|
|
43
|
+
throw new SchemaError(`$replace replacement must be a string, got ${formatValue(replacement)}`);
|
|
44
|
+
}
|
|
45
|
+
if (typeof value !== 'string') {
|
|
46
|
+
throw new ConstraintError(`$replace requires a string input, got ${formatValue(value)}`, {location});
|
|
47
|
+
}
|
|
48
|
+
return typeof pattern === 'string'
|
|
49
|
+
? value.replaceAll(pattern, replacement)
|
|
50
|
+
: value.replace(pattern, replacement);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* ## $substring
|
|
56
|
+
*
|
|
57
|
+
* Extracts a portion of a string by start index and optional length.
|
|
58
|
+
*
|
|
59
|
+
* ### Parameters
|
|
60
|
+
* - `start` (number, required): Start index (0-based).
|
|
61
|
+
* - `length` (number, optional): Number of characters to extract. If omitted, extracts to end of string.
|
|
62
|
+
*
|
|
63
|
+
* ### Example
|
|
64
|
+
* ```js
|
|
65
|
+
* // Extract the first 8 characters of a hash
|
|
66
|
+
* new Schema('string').transformer({$substring: {start: 0, length: 8}})
|
|
67
|
+
* // 'abcdef1234567890' → 'abcdef12'
|
|
68
|
+
*
|
|
69
|
+
* // Strip a known prefix (e.g. 'Bearer ')
|
|
70
|
+
* new Schema('string').transformer({$substring: {start: 7}})
|
|
71
|
+
*
|
|
72
|
+
* // Extract a fixed-position field from a formatted string
|
|
73
|
+
* new Schema('string').transformer({$substring: {start: 4, length: 2}})
|
|
74
|
+
* // '2026-03-21' → '03' (month)
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
78
|
+
*/
|
|
79
|
+
export const SUBSTRING_OPERATOR = {
|
|
80
|
+
keyword: 'substring',
|
|
81
|
+
parameters: [ { parameter: 'start', required: true, type: 'number' }, { parameter: 'length', type: 'number', default: undefined } ],
|
|
82
|
+
|
|
83
|
+
process: (value, _target, location, options) => {
|
|
84
|
+
if (typeof value !== 'string') {
|
|
85
|
+
throw new ConstraintError(`$substring requires a string input, got ${formatValue(value)}`, {location});
|
|
86
|
+
}
|
|
87
|
+
const start = options.args['start'];
|
|
88
|
+
const length = options.args['length'];
|
|
89
|
+
return length !== undefined
|
|
90
|
+
? value.substring(start, start + length)
|
|
91
|
+
: value.substring(start);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* ## $pad
|
|
97
|
+
*
|
|
98
|
+
* Pads a string to a minimum width.
|
|
99
|
+
*
|
|
100
|
+
* ### Parameters
|
|
101
|
+
* - `width` (number, required): Target minimum length.
|
|
102
|
+
* - `char` (string, optional): Pad character. Defaults to `' '`.
|
|
103
|
+
* - `side` (`'left'`|`'right'`, optional): Which side to pad. Defaults to `'left'`.
|
|
104
|
+
*
|
|
105
|
+
* ### Example
|
|
106
|
+
* ```js
|
|
107
|
+
* // Zero-pad a numeric string to 6 digits
|
|
108
|
+
* new Schema('string').transformer({$pad: {width: 6, char: '0'}})
|
|
109
|
+
* // '42' → '000042'
|
|
110
|
+
*
|
|
111
|
+
* // Right-pad a string to fill a fixed-width column
|
|
112
|
+
* new Schema('string').transformer({$pad: {width: 20, side: 'right'}})
|
|
113
|
+
* // 'Alice' → 'Alice '
|
|
114
|
+
*
|
|
115
|
+
* // Pad a month/day to 2 digits
|
|
116
|
+
* new Schema('number').transformer(['$string', {$pad: {width: 2, char: '0'}}])
|
|
117
|
+
* // 3 → '03'
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
121
|
+
*/
|
|
122
|
+
export const PAD_OPERATOR = {
|
|
123
|
+
keyword: 'pad',
|
|
124
|
+
parameters: [
|
|
125
|
+
{ parameter: 'width', required: true },
|
|
126
|
+
{ parameter: 'char', default: ' ' },
|
|
127
|
+
{ parameter: 'side', default: 'left' }
|
|
128
|
+
],
|
|
129
|
+
|
|
130
|
+
process: (value, _target, location, options) => {
|
|
131
|
+
if (typeof value !== 'string') {
|
|
132
|
+
throw new ConstraintError(`$pad requires a string input, got ${formatValue(value)}`, {location});
|
|
133
|
+
}
|
|
134
|
+
const width = options.args['width'];
|
|
135
|
+
const char = options.args['char'];
|
|
136
|
+
const side = options.args['side'];
|
|
137
|
+
return side === 'right'
|
|
138
|
+
? value.padEnd(width, char)
|
|
139
|
+
: value.padStart(width, char);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { stringify } from '../../helpers/stringify.js';
|
|
2
|
+
import { EMPTY } from '../../constants.js';
|
|
3
|
+
import { ConstraintError } from '../../errors.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ## $string
|
|
7
|
+
*
|
|
8
|
+
* Ensures value is a string, stringifying as necessary. Everything other than null and undefined can be converted.
|
|
9
|
+
*
|
|
10
|
+
* See `$is-string` for strict string validation.
|
|
11
|
+
*
|
|
12
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
13
|
+
*/
|
|
14
|
+
export const STRING_OPERATOR = {
|
|
15
|
+
keyword: 'string',
|
|
16
|
+
process: (value) => {
|
|
17
|
+
if (typeof value === 'string') {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
else if (value === null || value === undefined) {
|
|
21
|
+
throw new ConstraintError(`Invalid string`, {value})
|
|
22
|
+
}
|
|
23
|
+
else if (value === EMPTY) {
|
|
24
|
+
return '';
|
|
25
|
+
}
|
|
26
|
+
else if (typeof value === 'object') {
|
|
27
|
+
if (value instanceof Date) return value.toISOString();
|
|
28
|
+
return stringify(value);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return String(value)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|