@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,280 @@
|
|
|
1
|
+
|
|
2
|
+
import { isObject, isPlainObject } from './object.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {object} target
|
|
6
|
+
* @param {...object} sources
|
|
7
|
+
* @returns {object}
|
|
8
|
+
*/
|
|
9
|
+
export function deepMerge(target, ...sources) {
|
|
10
|
+
if (!sources.length) {
|
|
11
|
+
return target;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const source = sources.shift();
|
|
15
|
+
|
|
16
|
+
if (isObject(target) && isObject(source)) {
|
|
17
|
+
for (const key in source) {
|
|
18
|
+
if (isPlainObject(source[key])) {
|
|
19
|
+
if (!target[key]) {
|
|
20
|
+
Object.assign(target, {[key]: {}});
|
|
21
|
+
}
|
|
22
|
+
deepMerge(target[key], source[key]);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
Object.assign(target, {[key]: source[key]});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return deepMerge(target, ...sources);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* deep comparison
|
|
35
|
+
* @param {any} a
|
|
36
|
+
* @param {any} b
|
|
37
|
+
* @returns {boolean}
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export function deepEquals(a, b) {
|
|
41
|
+
if (a === b) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
if (a == null || b == null) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (typeof a !== typeof b) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
52
|
+
if (a.length !== b.length) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
for (let i = 0; i < a.length; ++i) {
|
|
56
|
+
if (!deepEquals(a[i], b[i])) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
64
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const keys = Object.keys(a);
|
|
68
|
+
if (keys.length !== Object.keys(b).length) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
for (const k of keys) {
|
|
72
|
+
if (!b.hasOwnProperty(k) || !deepEquals(a[k], b[k])) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @param {object|undefined}target
|
|
84
|
+
* @param {string} path
|
|
85
|
+
* @param {any} value
|
|
86
|
+
* @returns {object}
|
|
87
|
+
*/
|
|
88
|
+
export function deepAssign(target, path, value) {
|
|
89
|
+
if (path === '' && target) {
|
|
90
|
+
throw new Error('Top level path but target is already set');
|
|
91
|
+
}
|
|
92
|
+
if (path === '') {
|
|
93
|
+
if (Array.isArray(value)) {
|
|
94
|
+
return [...value];
|
|
95
|
+
}
|
|
96
|
+
else if (isPlainObject(value)) {
|
|
97
|
+
return {...value};
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
// Handle edge cases
|
|
102
|
+
if (!path || typeof path !== 'string') {
|
|
103
|
+
throw new Error('Path must be a non-empty string');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Split the path by dots and filter out empty segments
|
|
107
|
+
const segments = path.split('.').filter(segment => segment !== '');
|
|
108
|
+
|
|
109
|
+
if (segments.length === 0) {
|
|
110
|
+
throw new Error('Path must contain at least one valid segment');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (target !== null && target !== undefined && typeof target !== 'object') {
|
|
114
|
+
throw new Error('Target must be an object, an array, or null/undefined');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Auto-synthesize target if null
|
|
118
|
+
if (target === null || target === undefined) {
|
|
119
|
+
const firstSegment = segments[0];
|
|
120
|
+
const isFirstArrayIndex = /^\d+$/.test(firstSegment);
|
|
121
|
+
target = isFirstArrayIndex ? [] : {};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let current = target;
|
|
125
|
+
|
|
126
|
+
// Navigate to the parent of the target property
|
|
127
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
128
|
+
const segment = segments[i];
|
|
129
|
+
const nextSegment = segments[i + 1];
|
|
130
|
+
|
|
131
|
+
// Check if current segment is an array index
|
|
132
|
+
const isArrayIndex = /^\d+$/.test(segment);
|
|
133
|
+
const nextIsArrayIndex = /^\d+$/.test(nextSegment);
|
|
134
|
+
|
|
135
|
+
if (isArrayIndex) {
|
|
136
|
+
const index = parseInt(segment, 10);
|
|
137
|
+
|
|
138
|
+
// Ensure current is an array
|
|
139
|
+
if (!Array.isArray(current)) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`Expected array at path segment '${segments.slice(0, i).join('.')}', but found ${typeof current}`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Extend array if necessary
|
|
145
|
+
while (current.length <= index) {
|
|
146
|
+
current.push(undefined);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Create the next level if it doesn't exist
|
|
150
|
+
if (current[index] === undefined || current[index] === null) {
|
|
151
|
+
current[index] = nextIsArrayIndex ? [] : {};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
current = current[index];
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Handle object property
|
|
158
|
+
if (current[segment] === undefined || current[segment] === null) {
|
|
159
|
+
current[segment] = nextIsArrayIndex ? [] : {};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
current = current[segment];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Set the final value
|
|
167
|
+
const finalSegment = segments[segments.length - 1];
|
|
168
|
+
const isFinalArrayIndex = /^\d+$/.test(finalSegment);
|
|
169
|
+
|
|
170
|
+
if (isFinalArrayIndex) {
|
|
171
|
+
const index = parseInt(finalSegment, 10);
|
|
172
|
+
|
|
173
|
+
// Ensure current is an array
|
|
174
|
+
if (!Array.isArray(current)) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Expected array at path segment '${segments.slice(0, -1).join('.')}', but found ${typeof current}`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Extend array if necessary
|
|
180
|
+
while (current.length <= index) {
|
|
181
|
+
current.push(undefined);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
current[index] = value;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
current[finalSegment] = value;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return target;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
*
|
|
195
|
+
* @param {object} object
|
|
196
|
+
* @param {string} path
|
|
197
|
+
* @returns {undefined|any}
|
|
198
|
+
*/
|
|
199
|
+
export function deepValue(object, path) {
|
|
200
|
+
if (path === '') {
|
|
201
|
+
return object;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Handle null/undefined object
|
|
205
|
+
if (!object || typeof object !== 'object') {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
// Handle empty or invalid path
|
|
211
|
+
if (typeof path !== 'string') {
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Split the path and filter out empty strings
|
|
216
|
+
const keys = path.split('.').filter(key => key.length > 0);
|
|
217
|
+
|
|
218
|
+
// If no valid keys, return undefined
|
|
219
|
+
if (keys.length === 0) {
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Traverse the object following the path
|
|
224
|
+
let current = object;
|
|
225
|
+
for (const key of keys) {
|
|
226
|
+
// Check if current is null/undefined or not an object
|
|
227
|
+
if (!current || typeof current !== 'object') {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Move to the next level
|
|
232
|
+
if (/^\d+$/.test(key)) {
|
|
233
|
+
current = current[Number(key)]
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
current = current[key];
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return current;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @param {any} value
|
|
245
|
+
* @returns {any}
|
|
246
|
+
*/
|
|
247
|
+
export function deepPrune(value) {
|
|
248
|
+
if (value === null || value === undefined) {
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
if (isPlainObject(value)) {
|
|
252
|
+
for (const key of Object.keys(value)) {
|
|
253
|
+
if (deepPrune(value[key]) === undefined) {
|
|
254
|
+
delete value[key];
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return Object.keys(value).length ? value : undefined;
|
|
258
|
+
}
|
|
259
|
+
else if (Array.isArray(value)) {
|
|
260
|
+
for (let i = value.length - 1; i >= 0; i--) {
|
|
261
|
+
const v = deepPrune(value[i]);
|
|
262
|
+
if (v === undefined) {
|
|
263
|
+
if (i === value.length - 1) {
|
|
264
|
+
value.pop();
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
delete value[i];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else if (v !== value[i]) {
|
|
271
|
+
// avoid reassigning unless actually changed (e.g. proxy)
|
|
272
|
+
value[i] = v;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return value.length ? value : undefined;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
return value;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { CompiledSchema } from "../compiled-schema.js";
|
|
2
|
+
import { stringify } from './stringify.js';
|
|
3
|
+
import { isPlainObject } from './object.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {CompiledSchema} schema
|
|
8
|
+
* @returns {string}
|
|
9
|
+
* @package
|
|
10
|
+
*/
|
|
11
|
+
export function formatArgumentType(schema) {
|
|
12
|
+
|
|
13
|
+
if (schema.metadata.valueDescription) {
|
|
14
|
+
return schema.metadata.valueDescription;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let argumentTypeString;
|
|
18
|
+
if (schema.isArray && schema.hasChildren) {
|
|
19
|
+
const props = Array.from(schema.propertyEntries)
|
|
20
|
+
.sort((a, b) => {
|
|
21
|
+
if (a[0] === '*') return 1;
|
|
22
|
+
if (b[0] === '*') return -1;
|
|
23
|
+
return a[0].localeCompare(b[0], undefined, {numeric: true});
|
|
24
|
+
})
|
|
25
|
+
.map(e => e[1]);
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
argumentTypeString = props.map(s =>
|
|
29
|
+
{
|
|
30
|
+
let propFormat = formatArgumentType(s)
|
|
31
|
+
if (!s.required && (propFormat.length > 2) && propFormat.charAt(0) === '[' && propFormat.charAt(propFormat.length - 1) === ']') {
|
|
32
|
+
propFormat = propFormat.slice(1, propFormat.length - 1);
|
|
33
|
+
}
|
|
34
|
+
return propFormat;
|
|
35
|
+
}).join(', ')
|
|
36
|
+
|
|
37
|
+
if (schema.hasWildcard) {
|
|
38
|
+
argumentTypeString += '...';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (schema.metadata.validatorDescription) {
|
|
42
|
+
if (argumentTypeString && !argumentTypeString.includes(schema.metadata.validatorDescription)) {
|
|
43
|
+
argumentTypeString += ` {${schema.metadata.validatorDescription}}`;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
if (Array.isArray(schema.options.values) && schema.options.values.length > 0) {
|
|
49
|
+
argumentTypeString = schema.options.values.map(v => `${typeof v === 'string'? `"${v}"` : stringify(v)}`)
|
|
50
|
+
.sort((a, b) => a.localeCompare(b, undefined, {numeric: true})).join('|');
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
argumentTypeString = schema.metadata.valueName ?? (schema.isArray? '' : schema.options.type);
|
|
54
|
+
|
|
55
|
+
if (schema.metadata.validatorDescription) {
|
|
56
|
+
if (!argumentTypeString || (argumentTypeString === schema.options.type)) {
|
|
57
|
+
argumentTypeString = schema.metadata.validatorDescription; // overwrite basic "type names"
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
argumentTypeString = `${argumentTypeString} {${schema.metadata.validatorDescription}}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (argumentTypeString === undefined) {
|
|
65
|
+
argumentTypeString = 'value';
|
|
66
|
+
}
|
|
67
|
+
if (schema.isArray && !argumentTypeString.includes('...')) {
|
|
68
|
+
argumentTypeString += '...';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return argumentTypeString;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const DELIMITED = /^[^A-Za-z0-9_].+[^A-Za-z0-9_]$/;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {any} value
|
|
78
|
+
* @param {object} [options]
|
|
79
|
+
* @returns {string}
|
|
80
|
+
*/
|
|
81
|
+
export function formatValue(value, options = {}) {
|
|
82
|
+
const {delimiterOpen = '«', delimiterClose = '»', maxLength = 40} = options;
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
if (value === null) {
|
|
86
|
+
return `${delimiterOpen}null${delimiterClose}`;
|
|
87
|
+
}
|
|
88
|
+
else if (value === undefined) {
|
|
89
|
+
return `${delimiterOpen}undefined${delimiterClose}`;
|
|
90
|
+
}
|
|
91
|
+
let valueString;
|
|
92
|
+
if (typeof value === 'function' && value.name) {
|
|
93
|
+
valueString = `${delimiterOpen}${value.name}()${delimiterClose}`;
|
|
94
|
+
}
|
|
95
|
+
else if (typeof value === 'object' && !isPlainObject(value) && value.constructor?.name) {
|
|
96
|
+
valueString = `${delimiterOpen}${value.constructor.name}${delimiterClose}`;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// get our stringified json of the value
|
|
100
|
+
valueString = stringify(value, {delimiterOpen, delimiterClose});
|
|
101
|
+
}
|
|
102
|
+
if (typeof value !== 'string'
|
|
103
|
+
&& ((valueString.startsWith('"') && valueString.endsWith('"'))
|
|
104
|
+
|| (valueString.startsWith("'") && valueString.endsWith("'")))) {
|
|
105
|
+
// if what we got back has quotes but the original wasn't a string, remove them.
|
|
106
|
+
valueString = valueString.slice(1, -1);
|
|
107
|
+
}
|
|
108
|
+
if (!DELIMITED.test(valueString)) {
|
|
109
|
+
valueString = `${delimiterOpen}${valueString}${delimiterClose}`;
|
|
110
|
+
}
|
|
111
|
+
if (valueString.length > 40) {
|
|
112
|
+
// everything should be delimited here. grab the final char so we can reattach it.
|
|
113
|
+
const finalChar = valueString.charAt(valueString.length - 1);
|
|
114
|
+
valueString = valueString.slice(0, 40) + `...${finalChar}`;
|
|
115
|
+
}
|
|
116
|
+
return valueString;
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
return '�'
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CompiledSchema } from "../compiled-schema.js";
|
|
2
|
+
|
|
3
|
+
const IMPLIES_ARRAY = /^[\d*]/
|
|
4
|
+
/**
|
|
5
|
+
* @param {import("../types.js").ISchema} schema
|
|
6
|
+
* @returns {boolean}
|
|
7
|
+
*/
|
|
8
|
+
export function hasStringProperties(schema) {
|
|
9
|
+
|
|
10
|
+
const propertyEntries = (schema instanceof CompiledSchema)? schema.propertyEntries : Object.entries(schema.properties ?? {});
|
|
11
|
+
|
|
12
|
+
for (const [k] of propertyEntries) {
|
|
13
|
+
if (!IMPLIES_ARRAY.test(k)) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const unionSchemaEntries = (schema instanceof CompiledSchema)? schema.unionSchemaEntries : Object.entries(schema.unionSchemas ?? {});
|
|
19
|
+
|
|
20
|
+
for (const [_uk,us] of unionSchemaEntries) {
|
|
21
|
+
if (hasStringProperties(us)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright 2026 Version Zero | github.com/argh
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export { toCamelCase, toPascalCase, toConstantCase, toKebabCase, toCapitalize, toTitleCase } from './case.js';
|
|
5
|
+
export { debug } from './debug-sink.js';
|
|
6
|
+
export { deepMerge, deepEquals, deepAssign, deepValue, deepPrune } from './deep.js';
|
|
7
|
+
export { formatArgumentType, formatValue } from './format.js';
|
|
8
|
+
export { hasStringProperties } from './has-string-properties.js';
|
|
9
|
+
export { isPlainObject, isObject, isEmpty, isPrimitive, isConstructor, isConstructible, isNativeClass, map } from './object.js';
|
|
10
|
+
export { parseDate } from './parse-date.js';
|
|
11
|
+
export { behead, propertyName } from './path.js';
|
|
12
|
+
export { parseRegExp } from './regex.js';
|
|
13
|
+
export { stringify, parse } from './stringify.js';
|
|
14
|
+
export { toData } from './to-data.js';
|
|
15
|
+
export { isTruthyKeyword, isFalseyKeyword, isTruthy, isFalsey } from './truthy.js';
|
|
16
|
+
export { parseDataSize, formatDataSize } from './data-size.js';
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {any} obj
|
|
3
|
+
* @returns {boolean}
|
|
4
|
+
*/
|
|
5
|
+
export function isPlainObject(obj) {
|
|
6
|
+
if (obj == null || typeof obj !== 'object') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const proto = Object.getPrototypeOf(obj);
|
|
11
|
+
return proto === Object.prototype || proto === null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {any} item
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
18
|
+
export function isObject(item) {
|
|
19
|
+
// todo - should we allow 'function'?
|
|
20
|
+
return item && typeof item === 'object' && !Array.isArray(item);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {any} value
|
|
25
|
+
* @returns {boolean}
|
|
26
|
+
*/
|
|
27
|
+
export function isEmpty(value) {
|
|
28
|
+
return value === undefined || value === null
|
|
29
|
+
|| (Array.isArray(value) && value.length === 0)
|
|
30
|
+
|| (isPlainObject(value) && Object.keys(value).length === 0)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {any} item
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
export function isPrimitive(item) {
|
|
38
|
+
if (item === undefined || item === null) {
|
|
39
|
+
return false; // these values have special meaning for this library and are thus not assignable primitives!
|
|
40
|
+
}
|
|
41
|
+
const type = typeof item;
|
|
42
|
+
return type !== 'object' && type !== 'function';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {any} f
|
|
47
|
+
* @returns {boolean}
|
|
48
|
+
* @deprecated - usually want isConstructible instead
|
|
49
|
+
*/
|
|
50
|
+
export function isConstructor(f) {
|
|
51
|
+
if (typeof f !== 'function') {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (f.prototype?.constructor === f) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
class test
|
|
59
|
+
extends f {} // oops, turns out that simple functions can be extended (!)
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {any} f
|
|
69
|
+
* @returns {boolean}
|
|
70
|
+
*/
|
|
71
|
+
export function isConstructible(f) {
|
|
72
|
+
if (typeof f !== 'function') {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
Reflect.construct(Function, [], f);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns true for ES class syntax (`class Foo {}`) and native builtin
|
|
87
|
+
* constructors (`Map`, `Set`, `Error`, etc.) — i.e. functions that are
|
|
88
|
+
* meant to be used with `new` and should not be invoked as plain callbacks.
|
|
89
|
+
* @param {any} f
|
|
90
|
+
* @returns {boolean}
|
|
91
|
+
*/
|
|
92
|
+
export function isNativeClass(f) {
|
|
93
|
+
if (typeof f !== 'function') return false;
|
|
94
|
+
const str = Function.prototype.toString.call(f);
|
|
95
|
+
return /^class\s/.test(str) ||
|
|
96
|
+
(/\[native code\]/.test(str) && f.prototype?.constructor === f);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
* @param {object|any[]|any} collection
|
|
102
|
+
* @param {(value:any) => any} callback
|
|
103
|
+
* @returns {object|any[]}
|
|
104
|
+
*/
|
|
105
|
+
export function map(collection, callback) {
|
|
106
|
+
if (Array.isArray(collection)) {
|
|
107
|
+
return collection.map(callback);
|
|
108
|
+
}
|
|
109
|
+
else if (isPlainObject(collection)) {
|
|
110
|
+
return Object.fromEntries(Object.entries(collection).map(([k, v]) => [k, callback(v)]))
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
return [callback(collection)];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { TransformError } from '../errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @package
|
|
5
|
+
* @param {string|number|Date} value
|
|
6
|
+
* @returns {Date}
|
|
7
|
+
*/
|
|
8
|
+
export function parseDate(value) {
|
|
9
|
+
if (value === 'now') {
|
|
10
|
+
return new Date();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (typeof value === 'string') {
|
|
14
|
+
// Handle relative time deltas: +24h, -1d, etc.
|
|
15
|
+
const deltaMatch = value.match(/^([+-])(\d+(?:\.\d+)?)(ms|s|m|h|d|w)$/);
|
|
16
|
+
if (deltaMatch) {
|
|
17
|
+
const [, sign, amount, unit] = deltaMatch;
|
|
18
|
+
const multiplier = sign === '+' ? 1 : -1;
|
|
19
|
+
const num = parseFloat(amount) * multiplier;
|
|
20
|
+
|
|
21
|
+
const unitMs = {
|
|
22
|
+
ms: 1,
|
|
23
|
+
s: 1000,
|
|
24
|
+
m: 60 * 1000,
|
|
25
|
+
h: 60 * 60 * 1000,
|
|
26
|
+
d: 24 * 60 * 60 * 1000,
|
|
27
|
+
w: 7 * 24 * 60 * 60 * 1000
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return new Date(Date.now() + (num * unitMs[unit]));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Check if it's a numeric string (timestamp)
|
|
34
|
+
const numericValue = parseFloat(value);
|
|
35
|
+
if (!isNaN(numericValue) && isFinite(numericValue) && /^\d+(\.\d+)?$/.test(value.trim())) {
|
|
36
|
+
// Treat as numeric timestamp, apply same seconds/milliseconds logic
|
|
37
|
+
let timestamp = numericValue;
|
|
38
|
+
if (numericValue > 0 && numericValue < 2524608000 && numericValue < 1000000000000) {
|
|
39
|
+
timestamp = numericValue * 1000;
|
|
40
|
+
}
|
|
41
|
+
const date = new Date(timestamp);
|
|
42
|
+
if (isNaN(date.getTime())) {
|
|
43
|
+
throw new TransformError(`Invalid date: ${value}`);
|
|
44
|
+
}
|
|
45
|
+
return date;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Fall back to standard Date parsing for ISO strings, etc.
|
|
49
|
+
const date = new Date(value);
|
|
50
|
+
if (isNaN(date.getTime())) {
|
|
51
|
+
throw new TransformError(`Invalid date: ${value}`);
|
|
52
|
+
}
|
|
53
|
+
return date;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (typeof value === 'number') {
|
|
57
|
+
// Auto-detect seconds vs. milliseconds for reasonable ranges
|
|
58
|
+
// (If it's close to the epoch when interpreted as milliseconds, it's probably seconds.)
|
|
59
|
+
const date = new Date(Math.abs(value) < 200000000 ? value * 1000 : value)
|
|
60
|
+
|
|
61
|
+
if (isNaN(date.getTime())) {
|
|
62
|
+
throw new TransformError(`Invalid date: ${value}`);
|
|
63
|
+
}
|
|
64
|
+
return date;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (value instanceof Date) {
|
|
68
|
+
if (isNaN(value.getTime())) {
|
|
69
|
+
throw new TransformError(`Invalid date: ${value}`);
|
|
70
|
+
}
|
|
71
|
+
return new Date(value.getTime()); // defensive copy
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
throw new TransformError(`Invalid date: ${value} (${typeof value})`);
|
|
75
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split off the first section of a path
|
|
3
|
+
*
|
|
4
|
+
* @param {string} path
|
|
5
|
+
* @returns {[string,string|undefined]}
|
|
6
|
+
*/
|
|
7
|
+
export function behead(path) {
|
|
8
|
+
if (path === '') {
|
|
9
|
+
return ['', undefined];
|
|
10
|
+
}
|
|
11
|
+
const dot = path.indexOf('.');
|
|
12
|
+
|
|
13
|
+
return (dot === -1) ? [path, ''] : [path.slice(0, dot), path.slice(dot + 1)];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Extract the last part of the path
|
|
18
|
+
* @param {string} path
|
|
19
|
+
* @returns {string}
|
|
20
|
+
*/
|
|
21
|
+
export function propertyName(path) {
|
|
22
|
+
const dot = path.lastIndexOf('.');
|
|
23
|
+
|
|
24
|
+
if (dot === -1) {
|
|
25
|
+
return path;
|
|
26
|
+
}
|
|
27
|
+
return path.slice(dot + 1);
|
|
28
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SchemaError } from '../errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parse delimited regexp strings
|
|
5
|
+
*
|
|
6
|
+
* @param {string|RegExp} rx
|
|
7
|
+
* @returns {RegExp|undefined}
|
|
8
|
+
*/
|
|
9
|
+
export function parseRegExp(rx) {
|
|
10
|
+
if (rx instanceof RegExp) {
|
|
11
|
+
return rx;
|
|
12
|
+
}
|
|
13
|
+
if (typeof rx === 'string' && rx.startsWith('/') && rx.lastIndexOf('/') > 0) {
|
|
14
|
+
const lastSlash = rx.lastIndexOf('/');
|
|
15
|
+
return new RegExp(rx.slice(1, lastSlash), rx.slice(lastSlash + 1));
|
|
16
|
+
}
|
|
17
|
+
throw new SchemaError('Unable to parse RegExp', {value: rx})
|
|
18
|
+
}
|