@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,206 @@
|
|
|
1
|
+
import { Executor, toExecutor } from './executor.js';
|
|
2
|
+
import { isTruthy } from '../helpers/truthy.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Call a sequence of executors on the input until one returns a truthy value. Exceptions/rejections are caught and
|
|
6
|
+
* interpreted as a falsey value. Return the first successful truthy result, or undefined on failure.
|
|
7
|
+
*
|
|
8
|
+
* @template T
|
|
9
|
+
* @augments {Executor<T>}
|
|
10
|
+
*/
|
|
11
|
+
export class SequenceExecutor extends Executor {
|
|
12
|
+
#executors;
|
|
13
|
+
|
|
14
|
+
#criteriaBehavior;
|
|
15
|
+
#checkBehavior;
|
|
16
|
+
#returnBehavior;
|
|
17
|
+
#errorBehavior;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {Array<any>|any} [executors]
|
|
21
|
+
* @param {symbol[]} [flags]
|
|
22
|
+
*/
|
|
23
|
+
constructor(executors = [], flags = []) {
|
|
24
|
+
if (!Array.isArray(executors)) {
|
|
25
|
+
executors = [executors];
|
|
26
|
+
}
|
|
27
|
+
super();
|
|
28
|
+
this.#executors = executors.map((/** @type {any} */ item) => toExecutor(item));
|
|
29
|
+
|
|
30
|
+
for (const flag of flags) {
|
|
31
|
+
if (flag === SequenceExecutor.ALL_CRITERIA) {
|
|
32
|
+
this.#criteriaBehavior = flag;
|
|
33
|
+
}
|
|
34
|
+
else if (flag === SequenceExecutor.ANY_CRITERIA) {
|
|
35
|
+
this.#criteriaBehavior = flag;
|
|
36
|
+
}
|
|
37
|
+
else if (flag === SequenceExecutor.EXCLUSIVE_CRITERIA) {
|
|
38
|
+
this.#criteriaBehavior = flag;
|
|
39
|
+
}
|
|
40
|
+
else if (flag === SequenceExecutor.SUCCESS_CHECK) {
|
|
41
|
+
this.#checkBehavior = flag;
|
|
42
|
+
}
|
|
43
|
+
else if (flag === SequenceExecutor.DEFINED_CHECK) {
|
|
44
|
+
this.#checkBehavior = flag;
|
|
45
|
+
}
|
|
46
|
+
else if (flag === SequenceExecutor.TRUTHY_CHECK) {
|
|
47
|
+
this.#checkBehavior = flag;
|
|
48
|
+
}
|
|
49
|
+
else if (flag === SequenceExecutor.INPUT_RETURN) {
|
|
50
|
+
this.#returnBehavior = flag;
|
|
51
|
+
}
|
|
52
|
+
else if (flag === SequenceExecutor.RESULT_RETURN) {
|
|
53
|
+
this.#returnBehavior = flag;
|
|
54
|
+
}
|
|
55
|
+
else if (flag === SequenceExecutor.RETHROW_ERRORS) {
|
|
56
|
+
this.#errorBehavior = flag;
|
|
57
|
+
}
|
|
58
|
+
else if (flag === SequenceExecutor.CAPTURE_ERRORS) {
|
|
59
|
+
this.#errorBehavior = flag;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
throw new Error(`Unknown flag`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.#criteriaBehavior ??= SequenceExecutor.ALL_CRITERIA;
|
|
67
|
+
this.#checkBehavior ??= SequenceExecutor.SUCCESS_CHECK;
|
|
68
|
+
this.#returnBehavior ??= SequenceExecutor.INPUT_RETURN;
|
|
69
|
+
this.#errorBehavior ??= SequenceExecutor.RETHROW_ERRORS;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* @param {any} input
|
|
73
|
+
* @param {...any} extra
|
|
74
|
+
* @returns {T|null|undefined|Promise<T|null|undefined>}
|
|
75
|
+
*/
|
|
76
|
+
execute(input, ...extra) {
|
|
77
|
+
let lastResult = undefined;
|
|
78
|
+
let successCount = 0;
|
|
79
|
+
let failureCount = 0;
|
|
80
|
+
let current = 0;
|
|
81
|
+
|
|
82
|
+
const criteriaSatisfied = () => {
|
|
83
|
+
switch(this.#criteriaBehavior) {
|
|
84
|
+
case SequenceExecutor.ANY_CRITERIA: return successCount > 0;
|
|
85
|
+
case SequenceExecutor.EXCLUSIVE_CRITERIA: return successCount === 1 && current === this.#executors.length;
|
|
86
|
+
case SequenceExecutor.ALL_CRITERIA: return successCount === this.#executors.length;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const criteriaFailed = () => {
|
|
92
|
+
switch (this.#criteriaBehavior) {
|
|
93
|
+
case SequenceExecutor.ANY_CRITERIA: return successCount === 0 && current === this.#executors.length;
|
|
94
|
+
case SequenceExecutor.EXCLUSIVE_CRITERIA: return successCount > 1;
|
|
95
|
+
case SequenceExecutor.ALL_CRITERIA: return failureCount > 0;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* @returns {Promise<any>}
|
|
101
|
+
*/
|
|
102
|
+
const resume = async () => {
|
|
103
|
+
while (current < this.#executors.length) {
|
|
104
|
+
if (criteriaFailed() || criteriaSatisfied()) {
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const result = await this.#executors[current++].execute(input, ...extra);
|
|
109
|
+
handleResult(result);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (this.#checkBehavior === SequenceExecutor.SUCCESS_CHECK) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
handleFailure(error);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return finalResult();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
/** @param {any} result */
|
|
123
|
+
const handleResult = (result) => {
|
|
124
|
+
const success = this.#checkBehavior === SequenceExecutor.TRUTHY_CHECK
|
|
125
|
+
? isTruthy(result)
|
|
126
|
+
: this.#checkBehavior === SequenceExecutor.DEFINED_CHECK
|
|
127
|
+
? result !== undefined
|
|
128
|
+
: true;
|
|
129
|
+
|
|
130
|
+
if (success) {
|
|
131
|
+
successCount++;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
failureCount++;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!criteriaFailed()) {
|
|
138
|
+
lastResult = result;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** @param {Error} error */
|
|
142
|
+
const handleFailure = (error) => {
|
|
143
|
+
if (this.#errorBehavior === SequenceExecutor.RETHROW_ERRORS) {
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
// an exception/rejection fails all three check types.
|
|
147
|
+
failureCount++;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const finalResult = () => {
|
|
151
|
+
if (criteriaSatisfied()) {
|
|
152
|
+
return this.#returnBehavior === SequenceExecutor.RESULT_RETURN ? lastResult : input;
|
|
153
|
+
}
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const executors = this.#executors;
|
|
158
|
+
|
|
159
|
+
while (current < executors.length) {
|
|
160
|
+
let result;
|
|
161
|
+
try {
|
|
162
|
+
result = executors[current++].execute(input, ...extra);
|
|
163
|
+
if (result instanceof Promise) {
|
|
164
|
+
return result.then(
|
|
165
|
+
resolved => {
|
|
166
|
+
handleResult(resolved);
|
|
167
|
+
return resume();
|
|
168
|
+
},
|
|
169
|
+
rejected => {
|
|
170
|
+
handleFailure(rejected);
|
|
171
|
+
return resume();
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
handleResult(result);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
handleFailure(error);
|
|
178
|
+
if (this.#checkBehavior === SequenceExecutor.SUCCESS_CHECK) {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (criteriaFailed() || criteriaSatisfied()) {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return finalResult();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
static ANY_CRITERIA = Symbol('ANY-CRITERIA');
|
|
192
|
+
static ALL_CRITERIA = Symbol('ALL-CRITERIA');
|
|
193
|
+
static EXCLUSIVE_CRITERIA = Symbol('EXCLUSIVE-CRITERIA');
|
|
194
|
+
|
|
195
|
+
static TRUTHY_CHECK = Symbol('TRUTHY-CHECK');
|
|
196
|
+
static DEFINED_CHECK = Symbol('DEFINED-CHECK');
|
|
197
|
+
static SUCCESS_CHECK = Symbol('SUCCESS-CHECK');
|
|
198
|
+
|
|
199
|
+
static RESULT_RETURN = Symbol('RESULT-RETURN');
|
|
200
|
+
static INPUT_RETURN = Symbol('INPUT-RETURN');
|
|
201
|
+
|
|
202
|
+
// static THROW_ERRORS = Symbol('THROW-ERRORS'); // todo - consider throwing on undefined in handleResult?
|
|
203
|
+
static RETHROW_ERRORS = Symbol('RETHROW-ERRORS');
|
|
204
|
+
static CAPTURE_ERRORS = Symbol('CAPTURE-ERRORS');
|
|
205
|
+
|
|
206
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SequenceExecutor } from './sequence-executor.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Executes a fixed sequence of executors serially, passing each same input value and variadic arguments.
|
|
5
|
+
* and returning the original input value on success. This executor is intended for side-effect-style composition;
|
|
6
|
+
* for chained processing, see `PipelineExecutor` or `StepExecutor`. See `SequenceExecutor` to allow fine
|
|
7
|
+
* tuning of sequence execution behavior.
|
|
8
|
+
*
|
|
9
|
+
* @template T
|
|
10
|
+
* @augments {SequenceExecutor<T>}
|
|
11
|
+
*/
|
|
12
|
+
export class SerialExecutor extends SequenceExecutor {
|
|
13
|
+
/**
|
|
14
|
+
* @param {any[]|any} [serial]
|
|
15
|
+
*/
|
|
16
|
+
constructor(serial = []) {
|
|
17
|
+
if (!Array.isArray(serial)) {
|
|
18
|
+
serial = [serial];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
super(serial)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Executor, toExecutor } from './executor.js';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* StepExecutor is basically like PipelineExecutor, except that null or undefined step results are returned immediately.
|
|
6
|
+
*
|
|
7
|
+
* @template T
|
|
8
|
+
* @augments {Executor<T>}
|
|
9
|
+
*/
|
|
10
|
+
export class StepExecutor extends Executor {
|
|
11
|
+
|
|
12
|
+
#steps;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {Array<any>|any} steps - executors/functions/values to execute as a pipeline
|
|
16
|
+
*/
|
|
17
|
+
constructor(steps = []) {
|
|
18
|
+
if (!Array.isArray(steps)) {
|
|
19
|
+
steps = [steps]
|
|
20
|
+
}
|
|
21
|
+
super();
|
|
22
|
+
this.#steps = steps.map((/** @type {any} */ item) => toExecutor(item));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {T|null|undefined} value
|
|
27
|
+
* @param {...any} variadic
|
|
28
|
+
* @returns {T|null|undefined|Promise<T|null|undefined>}
|
|
29
|
+
*/
|
|
30
|
+
execute(value, ...variadic) {
|
|
31
|
+
if (value === null || value === undefined) {
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
let current = 0;
|
|
35
|
+
|
|
36
|
+
const steps = this.#steps;
|
|
37
|
+
|
|
38
|
+
while (current < steps.length) {
|
|
39
|
+
value = steps[current++].execute(value, ...variadic);
|
|
40
|
+
|
|
41
|
+
if (value === null || value === undefined) {
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (value instanceof Promise) {
|
|
46
|
+
return value.then(resolved => this.#resume(resolved, variadic, current));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {T|null|undefined} value
|
|
54
|
+
* @param {any[]} variadic
|
|
55
|
+
* @param {number} resumeIndex
|
|
56
|
+
* @returns {Promise<T|null|undefined>}
|
|
57
|
+
*/
|
|
58
|
+
async #resume(value, variadic, resumeIndex) {
|
|
59
|
+
while (resumeIndex < this.#steps.length) {
|
|
60
|
+
if (value === null || value === undefined) {
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
value = await this.#steps[resumeIndex++].execute(value, ...variadic);
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} str
|
|
3
|
+
* @returns {string[]}
|
|
4
|
+
*/
|
|
5
|
+
function normalizeToWords(str) {
|
|
6
|
+
// Handle empty or non-string input
|
|
7
|
+
if (!str || typeof str !== 'string') {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Split on common delimiters and word boundaries
|
|
12
|
+
return str
|
|
13
|
+
// Split on non-alphanumeric characters (handles kebab-case, snake_case, etc.)
|
|
14
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
15
|
+
// Split on lowercase-to-uppercase transitions (but not uppercase-to-uppercase)
|
|
16
|
+
.flatMap(part => part.split(/(?<=[a-z])(?=[A-Z])/))
|
|
17
|
+
.flatMap(part => part.split(/(?<=[0-9])(?=[A-Za-z])/))
|
|
18
|
+
// Filter out empty strings and convert to lowercase
|
|
19
|
+
.filter(word => word.length > 0)
|
|
20
|
+
.map(word => word.toLowerCase());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Convert normalized words array to camelCase
|
|
24
|
+
function wordsToCamelCase(words) {
|
|
25
|
+
if (words.length === 0) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
return words[0] + words.slice(1).map(word =>
|
|
29
|
+
word.charAt(0).toUpperCase() + word.slice(1)
|
|
30
|
+
).join('');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Convert normalized words array to camelCase
|
|
34
|
+
function wordsToPascalCase(words) {
|
|
35
|
+
if (words.length === 0) {
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
return words.map(word =>
|
|
39
|
+
word.charAt(0).toUpperCase() + word.slice(1)
|
|
40
|
+
).join('');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function wordsToCapitalize(words) {
|
|
44
|
+
if (words.length === 0) {
|
|
45
|
+
return '';
|
|
46
|
+
}
|
|
47
|
+
return words.map(word =>
|
|
48
|
+
word.charAt(0).toUpperCase() + word.slice(1)
|
|
49
|
+
).join(' ');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const TITLE_CASE_LOWERCASE = new Set([
|
|
53
|
+
'a', 'an', 'the', // articles
|
|
54
|
+
'and', 'but', 'or', 'nor', 'for', 'so', 'yet', // coordinating conjunctions
|
|
55
|
+
'at', 'by', 'in', 'of', 'on', 'to', 'up', 'as', 'via' // short prepositions
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
// Convert normalized words array to CONSTANT_CASE
|
|
59
|
+
function wordsToConstantCase(words) {
|
|
60
|
+
return words.map(word => word.toUpperCase()).join('_');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Convert normalized words array to kebab-case
|
|
64
|
+
function wordsToKebabCase(words) {
|
|
65
|
+
return words.map(word => word.toLowerCase()).join('-');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {string} str
|
|
70
|
+
* @returns {string}
|
|
71
|
+
*/
|
|
72
|
+
export function toCamelCase(str) {
|
|
73
|
+
return wordsToCamelCase(normalizeToWords(str));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {string} str
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
export function toPascalCase(str) {
|
|
81
|
+
return wordsToPascalCase(normalizeToWords(str));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {string} str
|
|
86
|
+
* @returns {string}
|
|
87
|
+
*/
|
|
88
|
+
export function toConstantCase(str) {
|
|
89
|
+
return wordsToConstantCase(normalizeToWords(str));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {string} str
|
|
94
|
+
* @returns {string}
|
|
95
|
+
*/
|
|
96
|
+
export function toKebabCase(str) {
|
|
97
|
+
return wordsToKebabCase(normalizeToWords(str));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param {string} str
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
export function toCapitalize(str) {
|
|
105
|
+
return wordsToCapitalize(normalizeToWords(str));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @param {string} str
|
|
110
|
+
* @returns {string}
|
|
111
|
+
*/
|
|
112
|
+
export function toTitleCase(str) {
|
|
113
|
+
if (!str || typeof str !== 'string') return '';
|
|
114
|
+
const trimmed = str.trim().replace(/\s+/g, ' ');
|
|
115
|
+
let wordIndex = 0;
|
|
116
|
+
const lastWordStart = trimmed.search(/\b\w(?=[^]*$)/);
|
|
117
|
+
return trimmed.replace(/\b(\w)(\w*)\b/g, (match, first, rest, offset) => {
|
|
118
|
+
const i = wordIndex++;
|
|
119
|
+
if (i !== 0 && offset !== lastWordStart && TITLE_CASE_LOWERCASE.has(match.toLowerCase())) {
|
|
120
|
+
return match.toLowerCase();
|
|
121
|
+
}
|
|
122
|
+
return first.toUpperCase() + rest.toLowerCase();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { SchemaError } from '../errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* IEC (binary) units: 1 KiB = 1024 bytes.
|
|
5
|
+
* @type {[string, number][]}
|
|
6
|
+
*/
|
|
7
|
+
const IEC_UNITS = [
|
|
8
|
+
['B', 1],
|
|
9
|
+
['KiB', 1024],
|
|
10
|
+
['MiB', 1024 ** 2],
|
|
11
|
+
['GiB', 1024 ** 3],
|
|
12
|
+
['TiB', 1024 ** 4],
|
|
13
|
+
['PiB', 1024 ** 5],
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* SI (decimal) units: 1 KB = 1000 bytes.
|
|
18
|
+
* @type {[string, number][]}
|
|
19
|
+
*/
|
|
20
|
+
const SI_UNITS = [
|
|
21
|
+
['B', 1],
|
|
22
|
+
['KB', 1000],
|
|
23
|
+
['MB', 1000 ** 2],
|
|
24
|
+
['GB', 1000 ** 3],
|
|
25
|
+
['TB', 1000 ** 4],
|
|
26
|
+
['PB', 1000 ** 5],
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Suffix-to-multiplier lookup.
|
|
31
|
+
* When standard is unspecified, both IEC and SI suffixes are accepted.
|
|
32
|
+
* IEC suffixes (KiB, MiB, ...) always resolve to binary multipliers.
|
|
33
|
+
* SI suffixes (KB, MB, ...) always resolve to decimal multipliers.
|
|
34
|
+
* The bare "B" suffix is unambiguous (1 byte in both standards).
|
|
35
|
+
* @type {Map<string, number>}
|
|
36
|
+
*/
|
|
37
|
+
const SUFFIX_MAP = new Map();
|
|
38
|
+
for (const [unit, mult] of IEC_UNITS) SUFFIX_MAP.set(unit.toLowerCase(), mult);
|
|
39
|
+
for (const [unit, mult] of SI_UNITS) SUFFIX_MAP.set(unit.toLowerCase(), mult);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* IEC-only suffix set for strict mode.
|
|
43
|
+
* @type {Set<string>}
|
|
44
|
+
*/
|
|
45
|
+
const IEC_SUFFIXES = new Set(IEC_UNITS.map(([u]) => u.toLowerCase()));
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* SI-only suffix set for strict mode.
|
|
49
|
+
* @type {Set<string>}
|
|
50
|
+
*/
|
|
51
|
+
const SI_SUFFIXES = new Set(SI_UNITS.map(([u]) => u.toLowerCase()));
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Parse pattern: digits with optional decimal, optional whitespace, optional unit suffix.
|
|
55
|
+
* Captures: [1] = number, [2] = unit suffix (may be empty for bare numbers).
|
|
56
|
+
*/
|
|
57
|
+
const PARSE_RE = /^\s*(\d+(?:\.\d+)?)\s*([a-z]*)\s*$/i;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Parse a data-size string into a byte count.
|
|
61
|
+
*
|
|
62
|
+
* Accepts numeric values (treated as bytes), or strings like `'20KiB'`, `'1.5 MB'`, `'512'`.
|
|
63
|
+
* When `standard` is omitted, both IEC and SI suffixes are accepted.
|
|
64
|
+
* When `standard` is `'iec'` or `'si'`, only that standard's suffixes are accepted.
|
|
65
|
+
*
|
|
66
|
+
* @package
|
|
67
|
+
* @param {string|number} value
|
|
68
|
+
* @param {string} [standard] - `'iec'` or `'si'`; omit to accept either
|
|
69
|
+
* @returns {number} byte count
|
|
70
|
+
*/
|
|
71
|
+
export function parseDataSize(value, standard) {
|
|
72
|
+
if (typeof value === 'number') {
|
|
73
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
74
|
+
throw new SchemaError(`Invalid data size: ${value}`);
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof value !== 'string') {
|
|
80
|
+
throw new SchemaError(`Invalid data size: expected string or number, got ${typeof value}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const match = value.match(PARSE_RE);
|
|
84
|
+
if (!match) {
|
|
85
|
+
throw new SchemaError(`Invalid data size: "${value}"`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const [, numStr, suffix] = match;
|
|
89
|
+
const num = parseFloat(numStr);
|
|
90
|
+
|
|
91
|
+
// bare number — treat as bytes
|
|
92
|
+
if (!suffix) return num;
|
|
93
|
+
|
|
94
|
+
const key = suffix.toLowerCase();
|
|
95
|
+
const multiplier = SUFFIX_MAP.get(key);
|
|
96
|
+
|
|
97
|
+
if (multiplier === undefined) {
|
|
98
|
+
throw new SchemaError(`Unknown data size unit: "${suffix}"`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// strict standard enforcement
|
|
102
|
+
if (standard) {
|
|
103
|
+
const std = standard.toLowerCase();
|
|
104
|
+
if (std === 'iec' && !IEC_SUFFIXES.has(key)) {
|
|
105
|
+
throw new SchemaError(`Unit "${suffix}" is not an IEC unit (expected B, KiB, MiB, GiB, TiB, PiB)`);
|
|
106
|
+
}
|
|
107
|
+
if (std === 'si' && !SI_SUFFIXES.has(key)) {
|
|
108
|
+
throw new SchemaError(`Unit "${suffix}" is not an SI unit (expected B, KB, MB, GB, TB, PB)`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return num * multiplier;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Format a byte count into a human-readable data-size string.
|
|
118
|
+
*
|
|
119
|
+
* Selects the largest unit where the value is >= 1 and formats with up to
|
|
120
|
+
* two decimal places (trailing zeros stripped).
|
|
121
|
+
*
|
|
122
|
+
* @package
|
|
123
|
+
* @param {number} bytes
|
|
124
|
+
* @param {string} [standard='iec'] - `'iec'` or `'si'`
|
|
125
|
+
* @returns {string|undefined}
|
|
126
|
+
*/
|
|
127
|
+
export function formatDataSize(bytes, standard = 'iec') {
|
|
128
|
+
if (!Number.isFinite(bytes) || bytes < 0) {
|
|
129
|
+
throw new SchemaError(`Invalid byte count: ${bytes}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const units = standard.toLowerCase() === 'si' ? SI_UNITS : IEC_UNITS;
|
|
133
|
+
|
|
134
|
+
// walk from largest to smallest
|
|
135
|
+
for (let i = units.length - 1; i >= 0; i--) {
|
|
136
|
+
const [unit, mult] = units[i];
|
|
137
|
+
if (bytes >= mult || i === 0) {
|
|
138
|
+
const val = bytes / mult;
|
|
139
|
+
const formatted = val % 1 === 0 ? String(val) : parseFloat(val.toFixed(2)).toString();
|
|
140
|
+
return `${formatted} ${unit}`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
const DEBUG_SINK = Symbol.for('@versionzero/debug-sink');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A hook for compatible loggers (e.g., `@versionzero/logger`) to automatically capture debug messages.
|
|
6
|
+
* (Left in for new code hacking; debug calls were removed for performance reasons after the library was stabilized.)
|
|
7
|
+
*
|
|
8
|
+
* @param {...any} args
|
|
9
|
+
* @package
|
|
10
|
+
* @deprecated
|
|
11
|
+
*/
|
|
12
|
+
export function debug(...args) {
|
|
13
|
+
const sink = (globalThis)[DEBUG_SINK] ?? console.log;
|
|
14
|
+
sink?.(...args);
|
|
15
|
+
}
|