@versionzero/schema 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +177 -0
- package/README.md +246 -0
- package/package.json +84 -0
- package/src/compilation/handler-compilation.js +28 -0
- package/src/compilation/metadata-compilation.js +35 -0
- package/src/compilation/schema-compilation.js +142 -0
- package/src/compilation/selection-compilation.js +84 -0
- package/src/compilation/union-compilation.js +510 -0
- package/src/compilation/values-compilation.js +35 -0
- package/src/compiled-schema.js +1709 -0
- package/src/constants.js +1 -0
- package/src/core-library/index.js +32 -0
- package/src/core-library/processors/aggregation-operators.js +75 -0
- package/src/core-library/processors/alpha-constraint.js +20 -0
- package/src/core-library/processors/alphanum-constraint.js +20 -0
- package/src/core-library/processors/array-operator.js +51 -0
- package/src/core-library/processors/assert-constraint.js +75 -0
- package/src/core-library/processors/base64-constraint.js +26 -0
- package/src/core-library/processors/camel-case-operator.js +24 -0
- package/src/core-library/processors/capitalize-operator.js +16 -0
- package/src/core-library/processors/cardnum-constraint.js +193 -0
- package/src/core-library/processors/ceil-operator.js +44 -0
- package/src/core-library/processors/collapse-operator.js +29 -0
- package/src/core-library/processors/compact-operator.js +34 -0
- package/src/core-library/processors/compile-operator.js +65 -0
- package/src/core-library/processors/concat-operator.js +51 -0
- package/src/core-library/processors/conditional-operators.js +301 -0
- package/src/core-library/processors/constant-case-operator.js +16 -0
- package/src/core-library/processors/data-size-operator.js +86 -0
- package/src/core-library/processors/date-object-operator.js +54 -0
- package/src/core-library/processors/date-operator.js +67 -0
- package/src/core-library/processors/date-range-constraint.js +76 -0
- package/src/core-library/processors/defined-constraint.js +30 -0
- package/src/core-library/processors/each-operator.js +57 -0
- package/src/core-library/processors/email-constraint.js +112 -0
- package/src/core-library/processors/entries-operator.js +25 -0
- package/src/core-library/processors/eq-constraint.js +37 -0
- package/src/core-library/processors/filter-operator.js +74 -0
- package/src/core-library/processors/find-schema-operator.js +45 -0
- package/src/core-library/processors/flatten-operator.js +40 -0
- package/src/core-library/processors/floor-operator.js +47 -0
- package/src/core-library/processors/get-operator.js +44 -0
- package/src/core-library/processors/group-by-operator.js +84 -0
- package/src/core-library/processors/has-prefix-constraint.js +37 -0
- package/src/core-library/processors/has-suffix-constraint.js +35 -0
- package/src/core-library/processors/hex-constraint.js +20 -0
- package/src/core-library/processors/hostname-constraint.js +22 -0
- package/src/core-library/processors/http-url-constraint.js +27 -0
- package/src/core-library/processors/in-constraint.js +66 -0
- package/src/core-library/processors/index-by-operator.js +98 -0
- package/src/core-library/processors/index.js +131 -0
- package/src/core-library/processors/input-operator.js +23 -0
- package/src/core-library/processors/instanceof-constraint.js +38 -0
- package/src/core-library/processors/integer-constraint.js +22 -0
- package/src/core-library/processors/invoke-operator.js +33 -0
- package/src/core-library/processors/ipv4-constraint.js +188 -0
- package/src/core-library/processors/ipv6-constraint.js +205 -0
- package/src/core-library/processors/is-array-constraint.js +21 -0
- package/src/core-library/processors/is-date-constraint.js +22 -0
- package/src/core-library/processors/is-number-constraint.js +21 -0
- package/src/core-library/processors/is-object-constraint.js +21 -0
- package/src/core-library/processors/is-string-constraint.js +21 -0
- package/src/core-library/processors/join-operator.js +41 -0
- package/src/core-library/processors/json-constraint.js +22 -0
- package/src/core-library/processors/json-decode-operator.js +25 -0
- package/src/core-library/processors/json-encode-operator.js +35 -0
- package/src/core-library/processors/kebab-case-operator.js +23 -0
- package/src/core-library/processors/keys-operator.js +20 -0
- package/src/core-library/processors/length-constraint.js +85 -0
- package/src/core-library/processors/lookup-operator.js +84 -0
- package/src/core-library/processors/lowercase-operator.js +14 -0
- package/src/core-library/processors/map-operator.js +84 -0
- package/src/core-library/processors/match-operator.js +64 -0
- package/src/core-library/processors/matches-constraint.js +54 -0
- package/src/core-library/processors/math-operators.js +151 -0
- package/src/core-library/processors/merge-deep-operator.js +61 -0
- package/src/core-library/processors/merge-operator.js +54 -0
- package/src/core-library/processors/metadata-operator.js +100 -0
- package/src/core-library/processors/negative-constraint.js +23 -0
- package/src/core-library/processors/never-constraint.js +69 -0
- package/src/core-library/processors/non-empty-constraint.js +59 -0
- package/src/core-library/processors/not-constraint.js +71 -0
- package/src/core-library/processors/number-operator.js +24 -0
- package/src/core-library/processors/numeric-constraint.js +22 -0
- package/src/core-library/processors/object-operator.js +38 -0
- package/src/core-library/processors/omit-operator.js +57 -0
- package/src/core-library/processors/parallel-operator.js +64 -0
- package/src/core-library/processors/pascal-case-operator.js +16 -0
- package/src/core-library/processors/phone-constraint.js +235 -0
- package/src/core-library/processors/pick-operator.js +62 -0
- package/src/core-library/processors/pipeline-operator.js +63 -0
- package/src/core-library/processors/port-constraint.js +22 -0
- package/src/core-library/processors/positive-constraint.js +23 -0
- package/src/core-library/processors/process-operator.js +55 -0
- package/src/core-library/processors/property-operator.js +49 -0
- package/src/core-library/processors/range-constraint.js +72 -0
- package/src/core-library/processors/reference-operator.js +79 -0
- package/src/core-library/processors/require-constraint.js +74 -0
- package/src/core-library/processors/reverse-operator.js +20 -0
- package/src/core-library/processors/round-operator.js +53 -0
- package/src/core-library/processors/schema-handler-operators.js +54 -0
- package/src/core-library/processors/semver-constraint.js +282 -0
- package/src/core-library/processors/sequence-processors.js +406 -0
- package/src/core-library/processors/sort-operator.js +52 -0
- package/src/core-library/processors/split-operator.js +43 -0
- package/src/core-library/processors/string-extra-operators.js +141 -0
- package/src/core-library/processors/string-operator.js +34 -0
- package/src/core-library/processors/target-operator.js +30 -0
- package/src/core-library/processors/template-operator.js +60 -0
- package/src/core-library/processors/title-case-operator.js +17 -0
- package/src/core-library/processors/trim-operator.js +14 -0
- package/src/core-library/processors/truthy-constraint.js +35 -0
- package/src/core-library/processors/type-operator.js +24 -0
- package/src/core-library/processors/unique-operator.js +21 -0
- package/src/core-library/processors/uppercase-operator.js +14 -0
- package/src/core-library/processors/url-constraint.js +31 -0
- package/src/core-library/processors/url-decode-operator.js +50 -0
- package/src/core-library/processors/url-encode-operator.js +44 -0
- package/src/core-library/processors/uuid-constraint.js +31 -0
- package/src/core-library/processors/values-operator.js +20 -0
- package/src/core-library/schemas/any-schema.js +23 -0
- package/src/core-library/schemas/array-schema.js +8 -0
- package/src/core-library/schemas/boolean-schema.js +10 -0
- package/src/core-library/schemas/date-schema.js +12 -0
- package/src/core-library/schemas/function-schema.js +40 -0
- package/src/core-library/schemas/number-schema.js +9 -0
- package/src/core-library/schemas/object-schema.js +10 -0
- package/src/core-library/schemas/root-schema.js +21 -0
- package/src/core-library/schemas/string-schema.js +9 -0
- package/src/core-library-node/index.js +47 -0
- package/src/core-library-node/processors/base64-decode-operator.js +20 -0
- package/src/core-library-node/processors/base64-encode-operator.js +20 -0
- package/src/core-library-node/processors/buffer-operator.js +39 -0
- package/src/core-library-node/processors/directory-constraint.js +35 -0
- package/src/core-library-node/processors/executable-constraint.js +34 -0
- package/src/core-library-node/processors/file-constraint.js +34 -0
- package/src/core-library-node/processors/file-size-constraint.js +94 -0
- package/src/core-library-node/processors/is-buffer-constraint.js +21 -0
- package/src/core-library-node/processors/reachable-constraint.js +28 -0
- package/src/core-library-node/processors/readable-constraint.js +34 -0
- package/src/core-library-node/processors/writable-constraint.js +59 -0
- package/src/core-library-node/schemas/buffer-schema.js +10 -0
- package/src/errors.js +209 -0
- package/src/executor/array-executor.js +78 -0
- package/src/executor/conditional-executor.js +134 -0
- package/src/executor/each-executor.js +68 -0
- package/src/executor/executor.js +123 -0
- package/src/executor/object-executor.js +98 -0
- package/src/executor/parallel-executor.js +43 -0
- package/src/executor/pipeline-executor.js +65 -0
- package/src/executor/sequence-executor.js +206 -0
- package/src/executor/serial-executor.js +24 -0
- package/src/executor/step-executor.js +68 -0
- package/src/helpers/case.js +124 -0
- package/src/helpers/data-size.js +144 -0
- package/src/helpers/debug-sink.js +15 -0
- package/src/helpers/deep.js +280 -0
- package/src/helpers/format.js +121 -0
- package/src/helpers/has-string-properties.js +30 -0
- package/src/helpers/index.js +16 -0
- package/src/helpers/object.js +115 -0
- package/src/helpers/parse-date.js +75 -0
- package/src/helpers/path.js +28 -0
- package/src/helpers/regex.js +18 -0
- package/src/helpers/stringify.js +309 -0
- package/src/helpers/to-data.js +64 -0
- package/src/helpers/truthy.js +55 -0
- package/src/index.js +29 -0
- package/src/schema-compiler.js +531 -0
- package/src/schema-location.js +200 -0
- package/src/schema-resolver.js +546 -0
- package/src/schema.js +1182 -0
- package/src/traversal/executors/check-condition.js +42 -0
- package/src/traversal/executors/check-input.js +27 -0
- package/src/traversal/executors/check-required.js +19 -0
- package/src/traversal/executors/check-schema.js +45 -0
- package/src/traversal/executors/defaults.js +21 -0
- package/src/traversal/executors/enter-existing.js +25 -0
- package/src/traversal/executors/enter-input.js +25 -0
- package/src/traversal/executors/enter.js +37 -0
- package/src/traversal/executors/exit.js +74 -0
- package/src/traversal/executors/finalize.js +64 -0
- package/src/traversal/executors/index.js +42 -0
- package/src/traversal/executors/normalize.js +38 -0
- package/src/traversal/executors/prepare-existing.js +27 -0
- package/src/traversal/executors/prepare-pending.js +54 -0
- package/src/traversal/executors/resolve-union.js +50 -0
- package/src/traversal/executors/serialize.js +48 -0
- package/src/traversal/executors/transform-early.js +51 -0
- package/src/traversal/executors/transform.js +68 -0
- package/src/traversal/executors/traversal-state-executor.js +46 -0
- package/src/traversal/executors/validate.js +63 -0
- package/src/traversal/traversal-context.js +231 -0
- package/src/traversal/traversal-state.js +809 -0
- package/src/types.js +102 -0
- package/src/value-processor/composed-value-processor.js +43 -0
- package/src/value-processor/defined-value-processor.js +72 -0
- package/src/value-processor/function-value-processor.js +68 -0
- package/src/value-processor/parameterized-value-processor.js +45 -0
- package/src/value-processor/parameters-value-processor.js +178 -0
- package/src/value-processor/spec.js +89 -0
- package/src/value-processor/value-processor.js +105 -0
- package/types/compilation/handler-compilation.d.ts +13 -0
- package/types/compilation/metadata-compilation.d.ts +6 -0
- package/types/compilation/schema-compilation.d.ts +32 -0
- package/types/compilation/selection-compilation.d.ts +9 -0
- package/types/compilation/union-compilation.d.ts +42 -0
- package/types/compilation/values-compilation.d.ts +12 -0
- package/types/compiled-schema.d.ts +883 -0
- package/types/constants.d.ts +1 -0
- package/types/core-library/index.d.ts +7 -0
- package/types/core-library/processors/aggregation-operators.d.ts +24 -0
- package/types/core-library/processors/alpha-constraint.d.ts +9 -0
- package/types/core-library/processors/alphanum-constraint.d.ts +9 -0
- package/types/core-library/processors/array-operator.d.ts +12 -0
- package/types/core-library/processors/assert-constraint.d.ts +30 -0
- package/types/core-library/processors/base64-constraint.d.ts +11 -0
- package/types/core-library/processors/camel-case-operator.d.ts +17 -0
- package/types/core-library/processors/capitalize-operator.d.ts +11 -0
- package/types/core-library/processors/cardnum-constraint.d.ts +51 -0
- package/types/core-library/processors/ceil-operator.d.ts +30 -0
- package/types/core-library/processors/collapse-operator.d.ts +24 -0
- package/types/core-library/processors/compact-operator.d.ts +29 -0
- package/types/core-library/processors/compile-operator.d.ts +34 -0
- package/types/core-library/processors/concat-operator.d.ts +23 -0
- package/types/core-library/processors/conditional-operators.d.ts +219 -0
- package/types/core-library/processors/constant-case-operator.d.ts +9 -0
- package/types/core-library/processors/data-size-operator.d.ts +31 -0
- package/types/core-library/processors/date-object-operator.d.ts +16 -0
- package/types/core-library/processors/date-operator.d.ts +21 -0
- package/types/core-library/processors/date-range-constraint.d.ts +26 -0
- package/types/core-library/processors/defined-constraint.d.ts +20 -0
- package/types/core-library/processors/each-operator.d.ts +34 -0
- package/types/core-library/processors/email-constraint.d.ts +54 -0
- package/types/core-library/processors/entries-operator.d.ts +13 -0
- package/types/core-library/processors/eq-constraint.d.ts +20 -0
- package/types/core-library/processors/filter-operator.d.ts +35 -0
- package/types/core-library/processors/find-schema-operator.d.ts +28 -0
- package/types/core-library/processors/flatten-operator.d.ts +26 -0
- package/types/core-library/processors/floor-operator.d.ts +33 -0
- package/types/core-library/processors/get-operator.d.ts +31 -0
- package/types/core-library/processors/group-by-operator.d.ts +36 -0
- package/types/core-library/processors/has-prefix-constraint.d.ts +22 -0
- package/types/core-library/processors/has-suffix-constraint.d.ts +20 -0
- package/types/core-library/processors/hex-constraint.d.ts +9 -0
- package/types/core-library/processors/hostname-constraint.d.ts +11 -0
- package/types/core-library/processors/http-url-constraint.d.ts +9 -0
- package/types/core-library/processors/in-constraint.d.ts +27 -0
- package/types/core-library/processors/index-by-operator.d.ts +26 -0
- package/types/core-library/processors/index.d.ts +8 -0
- package/types/core-library/processors/input-operator.d.ts +20 -0
- package/types/core-library/processors/instanceof-constraint.d.ts +23 -0
- package/types/core-library/processors/integer-constraint.d.ts +9 -0
- package/types/core-library/processors/invoke-operator.d.ts +12 -0
- package/types/core-library/processors/ipv4-constraint.d.ts +37 -0
- package/types/core-library/processors/ipv6-constraint.d.ts +34 -0
- package/types/core-library/processors/is-array-constraint.d.ts +10 -0
- package/types/core-library/processors/is-date-constraint.d.ts +10 -0
- package/types/core-library/processors/is-number-constraint.d.ts +10 -0
- package/types/core-library/processors/is-object-constraint.d.ts +10 -0
- package/types/core-library/processors/is-string-constraint.d.ts +10 -0
- package/types/core-library/processors/join-operator.d.ts +29 -0
- package/types/core-library/processors/json-constraint.d.ts +10 -0
- package/types/core-library/processors/json-decode-operator.d.ts +9 -0
- package/types/core-library/processors/json-encode-operator.d.ts +27 -0
- package/types/core-library/processors/kebab-case-operator.d.ts +16 -0
- package/types/core-library/processors/keys-operator.d.ts +9 -0
- package/types/core-library/processors/length-constraint.d.ts +34 -0
- package/types/core-library/processors/lookup-operator.d.ts +36 -0
- package/types/core-library/processors/lowercase-operator.d.ts +9 -0
- package/types/core-library/processors/map-operator.d.ts +38 -0
- package/types/core-library/processors/match-operator.d.ts +34 -0
- package/types/core-library/processors/matches-constraint.d.ts +29 -0
- package/types/core-library/processors/math-operators.d.ts +91 -0
- package/types/core-library/processors/merge-deep-operator.d.ts +32 -0
- package/types/core-library/processors/merge-operator.d.ts +26 -0
- package/types/core-library/processors/metadata-operator.d.ts +56 -0
- package/types/core-library/processors/negative-constraint.d.ts +13 -0
- package/types/core-library/processors/never-constraint.d.ts +26 -0
- package/types/core-library/processors/non-empty-constraint.d.ts +28 -0
- package/types/core-library/processors/not-constraint.d.ts +28 -0
- package/types/core-library/processors/number-operator.d.ts +9 -0
- package/types/core-library/processors/numeric-constraint.d.ts +10 -0
- package/types/core-library/processors/object-operator.d.ts +10 -0
- package/types/core-library/processors/omit-operator.d.ts +24 -0
- package/types/core-library/processors/parallel-operator.d.ts +41 -0
- package/types/core-library/processors/pascal-case-operator.d.ts +9 -0
- package/types/core-library/processors/phone-constraint.d.ts +65 -0
- package/types/core-library/processors/pick-operator.d.ts +27 -0
- package/types/core-library/processors/pipeline-operator.d.ts +40 -0
- package/types/core-library/processors/port-constraint.d.ts +11 -0
- package/types/core-library/processors/positive-constraint.d.ts +13 -0
- package/types/core-library/processors/process-operator.d.ts +37 -0
- package/types/core-library/processors/property-operator.d.ts +34 -0
- package/types/core-library/processors/range-constraint.d.ts +30 -0
- package/types/core-library/processors/reference-operator.d.ts +38 -0
- package/types/core-library/processors/require-constraint.d.ts +29 -0
- package/types/core-library/processors/reverse-operator.d.ts +9 -0
- package/types/core-library/processors/round-operator.d.ts +34 -0
- package/types/core-library/processors/schema-handler-operators.d.ts +28 -0
- package/types/core-library/processors/semver-constraint.d.ts +43 -0
- package/types/core-library/processors/sequence-processors.d.ts +213 -0
- package/types/core-library/processors/sort-operator.d.ts +31 -0
- package/types/core-library/processors/split-operator.d.ts +33 -0
- package/types/core-library/processors/string-extra-operators.d.ts +83 -0
- package/types/core-library/processors/string-operator.d.ts +10 -0
- package/types/core-library/processors/target-operator.d.ts +27 -0
- package/types/core-library/processors/template-operator.d.ts +31 -0
- package/types/core-library/processors/title-case-operator.d.ts +12 -0
- package/types/core-library/processors/trim-operator.d.ts +9 -0
- package/types/core-library/processors/truthy-constraint.d.ts +23 -0
- package/types/core-library/processors/type-operator.d.ts +11 -0
- package/types/core-library/processors/unique-operator.d.ts +10 -0
- package/types/core-library/processors/uppercase-operator.d.ts +9 -0
- package/types/core-library/processors/url-constraint.d.ts +20 -0
- package/types/core-library/processors/url-decode-operator.d.ts +31 -0
- package/types/core-library/processors/url-encode-operator.d.ts +36 -0
- package/types/core-library/processors/uuid-constraint.d.ts +20 -0
- package/types/core-library/processors/values-operator.d.ts +9 -0
- package/types/core-library/schemas/any-schema.d.ts +2 -0
- package/types/core-library/schemas/array-schema.d.ts +2 -0
- package/types/core-library/schemas/boolean-schema.d.ts +2 -0
- package/types/core-library/schemas/date-schema.d.ts +2 -0
- package/types/core-library/schemas/function-schema.d.ts +2 -0
- package/types/core-library/schemas/number-schema.d.ts +2 -0
- package/types/core-library/schemas/object-schema.d.ts +2 -0
- package/types/core-library/schemas/root-schema.d.ts +2 -0
- package/types/core-library/schemas/string-schema.d.ts +2 -0
- package/types/core-library-node/index.d.ts +12 -0
- package/types/core-library-node/processors/base64-decode-operator.d.ts +9 -0
- package/types/core-library-node/processors/base64-encode-operator.d.ts +9 -0
- package/types/core-library-node/processors/buffer-operator.d.ts +15 -0
- package/types/core-library-node/processors/directory-constraint.d.ts +14 -0
- package/types/core-library-node/processors/executable-constraint.d.ts +17 -0
- package/types/core-library-node/processors/file-constraint.d.ts +13 -0
- package/types/core-library-node/processors/file-size-constraint.d.ts +43 -0
- package/types/core-library-node/processors/is-buffer-constraint.d.ts +10 -0
- package/types/core-library-node/processors/reachable-constraint.d.ts +13 -0
- package/types/core-library-node/processors/readable-constraint.d.ts +17 -0
- package/types/core-library-node/processors/writable-constraint.d.ts +18 -0
- package/types/core-library-node/schemas/buffer-schema.d.ts +2 -0
- package/types/errors.d.ts +58 -0
- package/types/executor/array-executor.d.ts +17 -0
- package/types/executor/conditional-executor.d.ts +45 -0
- package/types/executor/each-executor.d.ts +15 -0
- package/types/executor/executor.d.ts +84 -0
- package/types/executor/object-executor.d.ts +14 -0
- package/types/executor/parallel-executor.d.ts +27 -0
- package/types/executor/pipeline-executor.d.ts +11 -0
- package/types/executor/sequence-executor.d.ts +32 -0
- package/types/executor/serial-executor.d.ts +16 -0
- package/types/executor/step-executor.d.ts +14 -0
- package/types/helpers/case.d.ts +30 -0
- package/types/helpers/data-size.d.ts +25 -0
- package/types/helpers/debug-sink.d.ts +9 -0
- package/types/helpers/deep.d.ts +33 -0
- package/types/helpers/format.d.ts +14 -0
- package/types/helpers/has-string-properties.d.ts +5 -0
- package/types/helpers/index.d.ts +13 -0
- package/types/helpers/object.d.ts +46 -0
- package/types/helpers/parse-date.d.ts +6 -0
- package/types/helpers/path.d.ts +13 -0
- package/types/helpers/regex.d.ts +7 -0
- package/types/helpers/stringify.d.ts +33 -0
- package/types/helpers/to-data.d.ts +13 -0
- package/types/helpers/truthy.d.ts +26 -0
- package/types/index.d.ts +6 -0
- package/types/schema-compiler.d.ts +49 -0
- package/types/schema-location.d.ts +64 -0
- package/types/schema-resolver.d.ts +145 -0
- package/types/schema.d.ts +586 -0
- package/types/traversal/executors/check-condition.d.ts +8 -0
- package/types/traversal/executors/check-input.d.ts +6 -0
- package/types/traversal/executors/check-required.d.ts +6 -0
- package/types/traversal/executors/check-schema.d.ts +7 -0
- package/types/traversal/executors/defaults.d.ts +8 -0
- package/types/traversal/executors/enter-existing.d.ts +6 -0
- package/types/traversal/executors/enter-input.d.ts +8 -0
- package/types/traversal/executors/enter.d.ts +7 -0
- package/types/traversal/executors/exit.d.ts +6 -0
- package/types/traversal/executors/finalize.d.ts +6 -0
- package/types/traversal/executors/index.d.ts +15 -0
- package/types/traversal/executors/normalize.d.ts +7 -0
- package/types/traversal/executors/prepare-existing.d.ts +6 -0
- package/types/traversal/executors/prepare-pending.d.ts +6 -0
- package/types/traversal/executors/resolve-union.d.ts +6 -0
- package/types/traversal/executors/serialize.d.ts +11 -0
- package/types/traversal/executors/transform-early.d.ts +6 -0
- package/types/traversal/executors/transform.d.ts +6 -0
- package/types/traversal/executors/traversal-state-executor.d.ts +19 -0
- package/types/traversal/executors/validate.d.ts +6 -0
- package/types/traversal/traversal-context.d.ts +67 -0
- package/types/traversal/traversal-state.d.ts +97 -0
- package/types/types.d.ts +218 -0
- package/types/value-processor/composed-value-processor.d.ts +17 -0
- package/types/value-processor/defined-value-processor.d.ts +16 -0
- package/types/value-processor/function-value-processor.d.ts +15 -0
- package/types/value-processor/parameterized-value-processor.d.ts +14 -0
- package/types/value-processor/parameters-value-processor.d.ts +28 -0
- package/types/value-processor/spec.d.ts +22 -0
- package/types/value-processor/value-processor.d.ts +92 -0
package/src/constants.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const EMPTY = Symbol('EMPTY');
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ANY_SCHEMA } from './schemas/any-schema.js';
|
|
2
|
+
import { STRING_SCHEMA } from './schemas/string-schema.js';
|
|
3
|
+
import { NUMBER_SCHEMA } from './schemas/number-schema.js';
|
|
4
|
+
import { BOOLEAN_SCHEMA } from './schemas/boolean-schema.js';
|
|
5
|
+
import { OBJECT_SCHEMA } from './schemas/object-schema.js';
|
|
6
|
+
import { ARRAY_SCHEMA } from './schemas/array-schema.js';
|
|
7
|
+
import { DATE_SCHEMA } from './schemas/date-schema.js';
|
|
8
|
+
import { FUNCTION_SCHEMA } from './schemas/function-schema.js';
|
|
9
|
+
import { ROOT_SCHEMA } from './schemas/root-schema.js';
|
|
10
|
+
import { getBuiltinProcessors } from './processors/index.js';
|
|
11
|
+
|
|
12
|
+
/** @import { SchemaResolver } from '../schema-resolver.js' */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {SchemaResolver} resolver
|
|
16
|
+
* @param {object} options
|
|
17
|
+
*/
|
|
18
|
+
export default function coreLibrary(resolver, options) {
|
|
19
|
+
resolver.registerSchema('root-schema', ROOT_SCHEMA);
|
|
20
|
+
resolver.registerSchema('any', ANY_SCHEMA);
|
|
21
|
+
resolver.registerSchema('string', STRING_SCHEMA);
|
|
22
|
+
resolver.registerSchema('number', NUMBER_SCHEMA);
|
|
23
|
+
resolver.registerSchema('boolean', BOOLEAN_SCHEMA);
|
|
24
|
+
resolver.registerSchema('object', OBJECT_SCHEMA);
|
|
25
|
+
resolver.registerSchema('array', ARRAY_SCHEMA);
|
|
26
|
+
resolver.registerSchema('date', DATE_SCHEMA);
|
|
27
|
+
resolver.registerSchema('function', FUNCTION_SCHEMA);
|
|
28
|
+
|
|
29
|
+
for (const definition of getBuiltinProcessors()) {
|
|
30
|
+
resolver.registerValueProcessorDefinition(definition);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ConstraintError } from '../../errors.js';
|
|
2
|
+
import { formatValue } from '../../helpers/format.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ## $sum
|
|
6
|
+
*
|
|
7
|
+
* Returns the sum of an array of numbers. Returns `0` for an empty array.
|
|
8
|
+
*
|
|
9
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
10
|
+
*/
|
|
11
|
+
export const SUM_OPERATOR = {
|
|
12
|
+
keyword: 'sum',
|
|
13
|
+
|
|
14
|
+
process: (value, _target, location) => {
|
|
15
|
+
if (!Array.isArray(value)) {
|
|
16
|
+
throw new ConstraintError(`$sum requires an array, got ${formatValue(value)}`, {location});
|
|
17
|
+
}
|
|
18
|
+
let sum = 0;
|
|
19
|
+
for (let i = 0; i < value.length; i++) {
|
|
20
|
+
if (typeof value[i] !== 'number' || !Number.isFinite(value[i])) {
|
|
21
|
+
throw new ConstraintError(`$sum requires an array of finite numbers, got ${formatValue(value[i])} at index ${i}`, {location});
|
|
22
|
+
}
|
|
23
|
+
sum += value[i];
|
|
24
|
+
}
|
|
25
|
+
return sum;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* ## $min
|
|
31
|
+
*
|
|
32
|
+
* Returns the minimum value from an array of numbers. Returns `undefined` for an empty array.
|
|
33
|
+
*
|
|
34
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
35
|
+
*/
|
|
36
|
+
export const MIN_OPERATOR = {
|
|
37
|
+
keyword: 'min',
|
|
38
|
+
|
|
39
|
+
process: (value, _target, location) => {
|
|
40
|
+
if (!Array.isArray(value)) {
|
|
41
|
+
throw new ConstraintError(`$min requires an array, got ${formatValue(value)}`, {location});
|
|
42
|
+
}
|
|
43
|
+
if (value.length === 0) return undefined;
|
|
44
|
+
for (let i = 0; i < value.length; i++) {
|
|
45
|
+
if (typeof value[i] !== 'number' || !Number.isFinite(value[i])) {
|
|
46
|
+
throw new ConstraintError(`$min requires an array of finite numbers, got ${formatValue(value[i])} at index ${i}`, {location});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return Math.min(...value);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* ## $max
|
|
55
|
+
*
|
|
56
|
+
* Returns the maximum value from an array of numbers. Returns `undefined` for an empty array.
|
|
57
|
+
*
|
|
58
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
59
|
+
*/
|
|
60
|
+
export const MAX_OPERATOR = {
|
|
61
|
+
keyword: 'max',
|
|
62
|
+
|
|
63
|
+
process: (value, _target, location) => {
|
|
64
|
+
if (!Array.isArray(value)) {
|
|
65
|
+
throw new ConstraintError(`$max requires an array, got ${formatValue(value)}`, {location});
|
|
66
|
+
}
|
|
67
|
+
if (value.length === 0) return undefined;
|
|
68
|
+
for (let i = 0; i < value.length; i++) {
|
|
69
|
+
if (typeof value[i] !== 'number' || !Number.isFinite(value[i])) {
|
|
70
|
+
throw new ConstraintError(`$max requires an array of finite numbers, got ${formatValue(value[i])} at index ${i}`, {location});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return Math.max(...value);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ConstraintError } from '../../errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ## $alpha
|
|
5
|
+
*
|
|
6
|
+
* Validates that a string contains only alphabetic characters (a-z, A-Z).
|
|
7
|
+
* No spaces, numbers, punctuation, or special characters are allowed.
|
|
8
|
+
*
|
|
9
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
10
|
+
*/
|
|
11
|
+
export const ALPHA_CONSTRAINT = {
|
|
12
|
+
keyword: 'alpha',
|
|
13
|
+
process: (value) => {
|
|
14
|
+
const alphaRegex = /^[a-zA-Z]+$/;
|
|
15
|
+
if (!alphaRegex.test(value)) {
|
|
16
|
+
throw new ConstraintError('Must contain only letters');
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ConstraintError } from '../../errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ## $alphanum
|
|
5
|
+
*
|
|
6
|
+
* Validates that a string contains only alphanumeric characters (A-Z, a-z, 0-9).
|
|
7
|
+
* No spaces, punctuation, or special characters are allowed.
|
|
8
|
+
*
|
|
9
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
10
|
+
*/
|
|
11
|
+
export const ALPHANUM_CONSTRAINT = {
|
|
12
|
+
keyword: 'alphanum',
|
|
13
|
+
process: (value) => {
|
|
14
|
+
const alphanumRegex = /^[a-zA-Z0-9]+$/;
|
|
15
|
+
if (!alphanumRegex.test(value)) {
|
|
16
|
+
throw new ConstraintError('Must contain only alphanumeric characters');
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { parse } from '../../helpers/stringify.js';
|
|
2
|
+
import { EMPTY } from '../../constants.js';
|
|
3
|
+
import { ConstraintError } from '../../errors.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ## $array
|
|
7
|
+
*
|
|
8
|
+
* Attempt to normalize the input value as an array.
|
|
9
|
+
*
|
|
10
|
+
* If the input value is "*", the array will expand to the "values" option defined in the current schema.
|
|
11
|
+
*
|
|
12
|
+
* See `$is-array` for strict array validation.
|
|
13
|
+
*
|
|
14
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
15
|
+
*/
|
|
16
|
+
export const ARRAY_OPERATOR = {
|
|
17
|
+
keyword: 'array',
|
|
18
|
+
|
|
19
|
+
process: (value, _, location) => {
|
|
20
|
+
if (value === EMPTY) {
|
|
21
|
+
value = [];
|
|
22
|
+
}
|
|
23
|
+
else if (value === '*') {
|
|
24
|
+
const values = location?.schema.getPropertySchema('*')?.values;
|
|
25
|
+
if (values !== undefined) {
|
|
26
|
+
value = [...values];
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
throw new ConstraintError('Schema must define values in order to expand wildcard array');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (typeof value === 'string') {
|
|
33
|
+
value = value.trim();
|
|
34
|
+
if (value.length > 0 && value[0] === '[' && value[value.length - 1] === ']') {
|
|
35
|
+
try {
|
|
36
|
+
value = parse(value);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new ConstraintError(`Invalid input string for array: ${value}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
value = value.split(',').map(s => s.trim()).filter(s => s.length > 0);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
throw new ConstraintError(`Invalid input for array: ${value}`)
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
|
|
2
|
+
import { ValueProcessor } from "../../value-processor/value-processor.js";
|
|
3
|
+
import { ComposedValueProcessor } from '../../value-processor/composed-value-processor.js';
|
|
4
|
+
import { ConditionalExecutor } from '../../executor/conditional-executor.js';
|
|
5
|
+
import { Executor } from '../../executor/executor.js';
|
|
6
|
+
import { ConstraintError, SchemaError } from '../../errors.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* ## $assert
|
|
10
|
+
*
|
|
11
|
+
* Require that the provided processor returns a truthy value; return original input.
|
|
12
|
+
* Throws a constraint exception if not truthy.
|
|
13
|
+
*
|
|
14
|
+
* May be used inline in a pipeline without parameters, or can have a single processor argument.
|
|
15
|
+
*
|
|
16
|
+
* ### Parameters
|
|
17
|
+
* - `processor` (ProcessorSpec, optional): Processor specification to check for truthiness.
|
|
18
|
+
* If omitted, the input value itself is checked.
|
|
19
|
+
*
|
|
20
|
+
* ### Example
|
|
21
|
+
* ```js
|
|
22
|
+
* // Require the input value itself to be truthy
|
|
23
|
+
* new Schema('any').validator('$assert')
|
|
24
|
+
*
|
|
25
|
+
* // Assert that a referenced sibling field has a truthy value
|
|
26
|
+
* new Schema('object', {
|
|
27
|
+
* enabled: new Schema('boolean'),
|
|
28
|
+
* config: new Schema('object').validator({$assert: {$reference: 'enabled'}}),
|
|
29
|
+
* })
|
|
30
|
+
*
|
|
31
|
+
* // Assert that a custom function returns true
|
|
32
|
+
* new Schema('string').validator({$assert: (value) => value.startsWith('https://')})
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
36
|
+
*/
|
|
37
|
+
export const ASSERT_CONSTRAINT = {
|
|
38
|
+
keyword: 'assert',
|
|
39
|
+
build: (args) => {
|
|
40
|
+
|
|
41
|
+
/** @type {ValueProcessor|undefined} */
|
|
42
|
+
let processor;
|
|
43
|
+
if (Array.isArray(args)) {
|
|
44
|
+
if (args.length === 1) {
|
|
45
|
+
processor = args[0];
|
|
46
|
+
}
|
|
47
|
+
else if (args.length === 0) {
|
|
48
|
+
processor = new ComposedValueProcessor(new Executor(), []);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw new SchemaError('$assert requires a single processor argument');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (typeof args === 'object') {
|
|
55
|
+
processor = args.processor;
|
|
56
|
+
}
|
|
57
|
+
if (!(processor instanceof ValueProcessor)) {
|
|
58
|
+
throw new SchemaError('$assert requires a processor argument');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const spec = args.length === 0? '$assert' : {'$assert': processor.spec};
|
|
62
|
+
const description = processor.description;
|
|
63
|
+
|
|
64
|
+
return new ComposedValueProcessor(
|
|
65
|
+
new ConditionalExecutor(processor,
|
|
66
|
+
{ failure: (error) => {
|
|
67
|
+
if (error instanceof ConstraintError) {
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
throw new ConstraintError('Processed value was not truthy', {cause: error}); } },
|
|
71
|
+
[ConditionalExecutor.CHECK_TRUTHY, ConditionalExecutor.PASS_ERROR]
|
|
72
|
+
),
|
|
73
|
+
spec, description);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ConstraintError } from '../../errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ## $base64
|
|
5
|
+
*
|
|
6
|
+
* Validates that a string is properly formatted Base64 encoded data.
|
|
7
|
+
* Checks for valid Base64 character set (A-Z, a-z, 0-9, +, /) and proper
|
|
8
|
+
* padding with equals signs. If padding is present, the total length must
|
|
9
|
+
* be a multiple of 4.
|
|
10
|
+
*
|
|
11
|
+
* @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
|
|
12
|
+
*/
|
|
13
|
+
export const BASE64_CONSTRAINT = {
|
|
14
|
+
keyword: 'base64',
|
|
15
|
+
process: (value) => {
|
|
16
|
+
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
17
|
+
if (!base64Regex.test(value)) {
|
|
18
|
+
throw new ConstraintError('Invalid base64 format');
|
|
19
|
+
}
|
|
20
|
+
// If there's padding, length must be multiple of 4
|
|
21
|
+
if (value.includes('=') && value.length % 4 !== 0) {
|
|
22
|
+
throw new ConstraintError('Invalid base64 format');
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { toCamelCase } from '../../helpers/case.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ## $camel-case
|
|
5
|
+
*
|
|
6
|
+
* Converts a string value to camelCase format. Words are identified by spaces,
|
|
7
|
+
* hyphens, underscores, or case changes. The first letter is lowercased, and
|
|
8
|
+
* subsequent words are capitalized with no separators.
|
|
9
|
+
* Safe to use in normalize phase (non-throwing).
|
|
10
|
+
*
|
|
11
|
+
* **Input examples**:
|
|
12
|
+
* - `"hello world"` → **Output**: `"helloWorld"`
|
|
13
|
+
* - `"foo-bar-baz"` → **Output**: `"fooBarBaz"`
|
|
14
|
+
* - `"user_name_id"` → **Output**: `"userNameId"`
|
|
15
|
+
* - `"HTTPSConnection"` → **Output**: `"httpsConnection"`
|
|
16
|
+
*
|
|
17
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
18
|
+
*/
|
|
19
|
+
export const CAMEL_CASE_OPERATOR = {
|
|
20
|
+
keyword: 'camel-case',
|
|
21
|
+
process: (value) => {
|
|
22
|
+
return toCamelCase(String(value));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { toCapitalize } from '../../helpers/case.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ## $capitalize
|
|
5
|
+
*
|
|
6
|
+
* Capitalizes the first letter of each word, separated by spaces. Words are split on
|
|
7
|
+
* non-alphanumeric boundaries (spaces, hyphens, underscores, camelCase transitions, etc.).
|
|
8
|
+
* Every word is capitalized unconditionally — see `$title-case` for proper title casing
|
|
9
|
+
* that respects articles and conjunctions.
|
|
10
|
+
*
|
|
11
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
12
|
+
*/
|
|
13
|
+
export const CAPITALIZE_OPERATOR = {
|
|
14
|
+
keyword: 'capitalize',
|
|
15
|
+
process: (value) => toCapitalize(String(value))
|
|
16
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { ConstraintError } from '../../errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* IIN (Issuer Identification Number) network definitions.
|
|
5
|
+
* Used for output formatting only — detection does not affect validation.
|
|
6
|
+
* Ordered from most specific prefix to least specific to avoid false matches.
|
|
7
|
+
*/
|
|
8
|
+
const CARD_NETWORKS = [
|
|
9
|
+
{
|
|
10
|
+
name: 'amex',
|
|
11
|
+
match: (d) => d.startsWith('34') || d.startsWith('37'),
|
|
12
|
+
groups: [4, 6, 5],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'diners',
|
|
16
|
+
match: (d) => {
|
|
17
|
+
const p3 = +d.slice(0, 3);
|
|
18
|
+
return (p3 >= 300 && p3 <= 305) || d.startsWith('36') || d.startsWith('38');
|
|
19
|
+
},
|
|
20
|
+
groups: [4, 6, 4],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'jcb',
|
|
24
|
+
match: (d) => {
|
|
25
|
+
const p4 = +d.slice(0, 4);
|
|
26
|
+
return p4 >= 3528 && p4 <= 3589;
|
|
27
|
+
},
|
|
28
|
+
groups: [4, 4, 4, 4],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'discover',
|
|
32
|
+
match: (d) => {
|
|
33
|
+
const p3 = +d.slice(0, 3);
|
|
34
|
+
const p6 = +d.slice(0, 6);
|
|
35
|
+
return d.startsWith('6011') || d.startsWith('65')
|
|
36
|
+
|| (p3 >= 644 && p3 <= 649)
|
|
37
|
+
|| (p6 >= 622126 && p6 <= 622925);
|
|
38
|
+
},
|
|
39
|
+
groups: [4, 4, 4, 4],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'mastercard',
|
|
43
|
+
match: (d) => {
|
|
44
|
+
const p2 = +d.slice(0, 2);
|
|
45
|
+
const p4 = +d.slice(0, 4);
|
|
46
|
+
return (p2 >= 51 && p2 <= 55) || (p4 >= 2221 && p4 <= 2720);
|
|
47
|
+
},
|
|
48
|
+
groups: [4, 4, 4, 4],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'visa',
|
|
52
|
+
match: (d) => d.startsWith('4'),
|
|
53
|
+
groups: [4, 4, 4, 4],
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const DEFAULT_GROUPS = [4, 4, 4, 4];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Luhn checksum validation.
|
|
61
|
+
* @param {string} digits
|
|
62
|
+
* @returns {boolean}
|
|
63
|
+
*/
|
|
64
|
+
function luhnCheck(digits) {
|
|
65
|
+
let sum = 0;
|
|
66
|
+
let double = false;
|
|
67
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
68
|
+
let d = +digits[i];
|
|
69
|
+
if (double) {
|
|
70
|
+
d *= 2;
|
|
71
|
+
if (d > 9) d -= 9;
|
|
72
|
+
}
|
|
73
|
+
sum += d;
|
|
74
|
+
double = !double;
|
|
75
|
+
}
|
|
76
|
+
return sum % 10 === 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Format a character sequence using group sizes, with overflow in an extra group.
|
|
81
|
+
* @param {string} chars
|
|
82
|
+
* @param {number[]} groups
|
|
83
|
+
* @returns {string}
|
|
84
|
+
*/
|
|
85
|
+
function formatWithGroups(chars, groups) {
|
|
86
|
+
const parts = [];
|
|
87
|
+
let pos = 0;
|
|
88
|
+
for (const size of groups) {
|
|
89
|
+
if (pos >= chars.length) break;
|
|
90
|
+
parts.push(chars.slice(pos, pos + size));
|
|
91
|
+
pos += size;
|
|
92
|
+
}
|
|
93
|
+
if (pos < chars.length) {
|
|
94
|
+
parts.push(chars.slice(pos));
|
|
95
|
+
}
|
|
96
|
+
return parts.join(' ');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* ## $cardnum
|
|
101
|
+
*
|
|
102
|
+
* Validates a payment card number (PAN) using the Luhn algorithm and normalizes
|
|
103
|
+
* its formatting based on the detected card network.
|
|
104
|
+
*
|
|
105
|
+
* **Processing steps:**
|
|
106
|
+
* 1. Strip formatting characters (spaces, dashes, dots)
|
|
107
|
+
* 2. Validate: digits only, length 12–19 (ISO 7812), Luhn checksum
|
|
108
|
+
* 3. Detect card network from IIN (Issuer Identification Number) prefix
|
|
109
|
+
* 4. Format with network-appropriate digit grouping
|
|
110
|
+
*
|
|
111
|
+
* **Recognized networks and their grouping:**
|
|
112
|
+
* - **Amex** (34, 37): `#### ###### #####`
|
|
113
|
+
* - **Diners Club** (300–305, 36, 38): `#### ###### ####`
|
|
114
|
+
* - **JCB** (3528–3589): `#### #### #### ####`
|
|
115
|
+
* - **Discover** (6011, 65, 644–649, 622126–622925): `#### #### #### ####`
|
|
116
|
+
* - **Mastercard** (51–55, 2221–2720): `#### #### #### ####`
|
|
117
|
+
* - **Visa** (4): `#### #### #### ####`
|
|
118
|
+
* - **Unrecognized**: `#### #### #### ####` (default grouping)
|
|
119
|
+
*
|
|
120
|
+
* Network detection is best-effort and does not affect validation — any number
|
|
121
|
+
* that passes the Luhn check with a valid length is accepted. Unrecognized
|
|
122
|
+
* prefixes receive default 4-4-4-4 grouping.
|
|
123
|
+
*
|
|
124
|
+
* ### Parameters
|
|
125
|
+
* - `mask` (boolean or string, default `false`): When truthy, replaces leading
|
|
126
|
+
* digits with a mask character, revealing only the trailing digits.
|
|
127
|
+
* `true` uses `'•'`; a string value uses its first character.
|
|
128
|
+
* - `reveal` (number, default `4`): Number of trailing digits to leave visible
|
|
129
|
+
* when `mask` is enabled.
|
|
130
|
+
*
|
|
131
|
+
* ### Example
|
|
132
|
+
* ```js
|
|
133
|
+
* // Validate and format
|
|
134
|
+
* new Schema('string').validator('$cardnum')
|
|
135
|
+
* // '4111111111111111' → '4111 1111 1111 1111'
|
|
136
|
+
* // '378282246310005' → '3782 822463 10005'
|
|
137
|
+
*
|
|
138
|
+
* // Masked for output (serializer — masking is a lossy presentation transform)
|
|
139
|
+
* new Schema('string').serializer({'$cardnum': {mask: true}})
|
|
140
|
+
* // '4111111111111111' → '•••• •••• •••• 1111'
|
|
141
|
+
*
|
|
142
|
+
* // Custom mask character, reveal 6 digits
|
|
143
|
+
* new Schema('string').serializer({'$cardnum': {mask: '*', reveal: 6}})
|
|
144
|
+
* // '4111111111111111' → '**** **** **11 1111'
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
148
|
+
*/
|
|
149
|
+
export const CARDNUM_CONSTRAINT = {
|
|
150
|
+
keyword: 'cardnum',
|
|
151
|
+
parameters: [
|
|
152
|
+
{ parameter: 'mask', default: false },
|
|
153
|
+
{ parameter: 'reveal', default: 4 },
|
|
154
|
+
],
|
|
155
|
+
|
|
156
|
+
process: (value, _target, _location, options) => {
|
|
157
|
+
const { mask, reveal } = options.args;
|
|
158
|
+
|
|
159
|
+
// Strip formatting
|
|
160
|
+
const digits = value.replace(/[\s\-.]/g, '');
|
|
161
|
+
|
|
162
|
+
if (!/^\d+$/.test(digits)) {
|
|
163
|
+
throw new ConstraintError('Invalid card number format');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (digits.length < 12 || digits.length > 19) {
|
|
167
|
+
throw new ConstraintError('Invalid card number length');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!luhnCheck(digits)) {
|
|
171
|
+
throw new ConstraintError('Invalid card number (checksum failed)');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Detect network for formatting (best-effort, does not gate validation)
|
|
175
|
+
let groups = DEFAULT_GROUPS;
|
|
176
|
+
for (const network of CARD_NETWORKS) {
|
|
177
|
+
if (network.match(digits)) {
|
|
178
|
+
groups = network.groups;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Apply masking
|
|
184
|
+
if (mask) {
|
|
185
|
+
const maskChar = (typeof mask === 'string' ? mask[0] : null) || '\u2022';
|
|
186
|
+
const visible = Math.min(Math.max(0, reveal), digits.length);
|
|
187
|
+
const masked = maskChar.repeat(digits.length - visible) + digits.slice(digits.length - visible);
|
|
188
|
+
return formatWithGroups(masked, groups);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return formatWithGroups(digits, groups);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
/** @import {ValueProcessorDefinition} from '../../value-processor/value-processor.js' */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ## $ceil
|
|
6
|
+
*
|
|
7
|
+
* Rounds a numeric value up to the nearest integer or specified decimal precision.
|
|
8
|
+
* Non-numeric values are passed through unchanged. Safe to use in normalize phase (non-throwing).
|
|
9
|
+
*
|
|
10
|
+
* ### Parameters
|
|
11
|
+
* - `precision` (number, optional): Number of decimal places to preserve. Defaults to 0 (round to integer).
|
|
12
|
+
*
|
|
13
|
+
* ### Example
|
|
14
|
+
* ```js
|
|
15
|
+
* // Round up to the nearest integer
|
|
16
|
+
* new Schema('number').transformer('$ceil')
|
|
17
|
+
* // 3.14 → 4, 9.01 → 10
|
|
18
|
+
*
|
|
19
|
+
* // Round up to 2 decimal places
|
|
20
|
+
* new Schema('number').transformer({$ceil: {precision: 2}})
|
|
21
|
+
* // 3.14159 → 3.15
|
|
22
|
+
*
|
|
23
|
+
* // Round up memory usage to the nearest MB boundary
|
|
24
|
+
* new Schema('object', {
|
|
25
|
+
* memoryMB: new Schema('number').transformer({$ceil: {precision: 0}}),
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @type {ValueProcessorDefinition}
|
|
30
|
+
*/
|
|
31
|
+
export const CEIL_OPERATOR = {
|
|
32
|
+
keyword: 'ceil',
|
|
33
|
+
parameters: [ { parameter: 'precision', default: 0 } ],
|
|
34
|
+
|
|
35
|
+
process: (value, _target, _location, options) => {
|
|
36
|
+
const num = Number(value);
|
|
37
|
+
if (!Number.isFinite(num)) {
|
|
38
|
+
return value; // Pass through non-numeric values unchanged
|
|
39
|
+
}
|
|
40
|
+
const precision = options.args['precision'];
|
|
41
|
+
const multiplier = Math.pow(10, precision);
|
|
42
|
+
return Math.ceil(num * multiplier) / multiplier;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## $collapse
|
|
3
|
+
*
|
|
4
|
+
* Collapses runs of whitespace within a string to a single space, and trims
|
|
5
|
+
* leading and trailing whitespace. Useful for normalizing messy user input
|
|
6
|
+
* from forms, textareas, and configuration values.
|
|
7
|
+
*
|
|
8
|
+
* Compared to `$trim` (edges only) and `$compact` (removes all formatting),
|
|
9
|
+
* `$collapse` preserves word boundaries while normalizing irregular spacing.
|
|
10
|
+
*
|
|
11
|
+
* ### Example
|
|
12
|
+
* ```js
|
|
13
|
+
* // Clean up messy form input
|
|
14
|
+
* new Schema('string').normalizer('$collapse')
|
|
15
|
+
* // ' hello world\n' → 'hello world'
|
|
16
|
+
*
|
|
17
|
+
* // Normalize a multi-line address to single line
|
|
18
|
+
* new Schema('string').normalizer('$collapse')
|
|
19
|
+
* // '123 Main St\n Apt 4\n' → '123 Main St Apt 4'
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
23
|
+
*/
|
|
24
|
+
export const COLLAPSE_OPERATOR = {
|
|
25
|
+
keyword: 'collapse',
|
|
26
|
+
process: (value) => {
|
|
27
|
+
return String(value).replace(/\s+/g, ' ').trim();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ## $compact
|
|
3
|
+
*
|
|
4
|
+
* Strips common formatting characters from a string: whitespace, hyphens,
|
|
5
|
+
* dots, parentheses, and forward slashes. Useful for producing storage-ready
|
|
6
|
+
* representations of formatted values like phone numbers and card numbers.
|
|
7
|
+
*
|
|
8
|
+
* Characters removed: `\\s`, `-`, `.`, `(`, `)`, `/`
|
|
9
|
+
*
|
|
10
|
+
* Characters preserved: `+`, digits, letters, and all other characters.
|
|
11
|
+
*
|
|
12
|
+
* ### Example
|
|
13
|
+
* ```js
|
|
14
|
+
* // Compact a formatted phone number for storage
|
|
15
|
+
* new Schema('string').normalizer(['$phone', '$compact'])
|
|
16
|
+
* // '(212) 555-1234' → '2125551234'
|
|
17
|
+
*
|
|
18
|
+
* // Compact an international phone number (preserves +)
|
|
19
|
+
* new Schema('string').normalizer([{'$phone': {international: true}}, '$compact'])
|
|
20
|
+
* // '+1 212 555 1234' → '+12125551234'
|
|
21
|
+
*
|
|
22
|
+
* // Compact a card number for storage
|
|
23
|
+
* new Schema('string').normalizer(['$cardnum', '$compact'])
|
|
24
|
+
* // '4111 1111 1111 1111' → '4111111111111111'
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
|
|
28
|
+
*/
|
|
29
|
+
export const COMPACT_OPERATOR = {
|
|
30
|
+
keyword: 'compact',
|
|
31
|
+
process: (value) => {
|
|
32
|
+
return String(value).replace(/[\s()\-./]/g, '');
|
|
33
|
+
}
|
|
34
|
+
};
|