@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,809 @@
|
|
|
1
|
+
import { CompiledSchema } from '../compiled-schema.js';
|
|
2
|
+
import { SchemaLocation } from '../schema-location.js';
|
|
3
|
+
import { TraversalContext } from './traversal-context.js';
|
|
4
|
+
import { Executor } from "../executor/executor.js";
|
|
5
|
+
import { SchemaError } from '../errors.js';
|
|
6
|
+
import { EMPTY } from '../constants.js';
|
|
7
|
+
import { deepEquals } from '../helpers/deep.js';
|
|
8
|
+
import { isEmpty, isObject, isPlainObject, isPrimitive } from '../helpers/object.js';
|
|
9
|
+
|
|
10
|
+
export class TraversalState
|
|
11
|
+
{
|
|
12
|
+
/** @type {TraversalContext} */
|
|
13
|
+
#context;
|
|
14
|
+
|
|
15
|
+
/** @type {string} */
|
|
16
|
+
#path;
|
|
17
|
+
|
|
18
|
+
/** @type {string} */
|
|
19
|
+
#name;
|
|
20
|
+
|
|
21
|
+
/** @type {string|number} */
|
|
22
|
+
#key;
|
|
23
|
+
|
|
24
|
+
/** @type {SchemaLocation|undefined} */
|
|
25
|
+
#location;
|
|
26
|
+
|
|
27
|
+
/** @type {TraversalState | undefined } */
|
|
28
|
+
#parent;
|
|
29
|
+
|
|
30
|
+
/** @type {Map<string,TraversalState>} */
|
|
31
|
+
#children = new Map();
|
|
32
|
+
|
|
33
|
+
// state values
|
|
34
|
+
/** @type {any} */
|
|
35
|
+
#assignedInput;
|
|
36
|
+
|
|
37
|
+
/** @type {any} */
|
|
38
|
+
#input = undefined; // most recent input
|
|
39
|
+
|
|
40
|
+
/** @type {Set<any,any>} */
|
|
41
|
+
#inputs = new Set(); // full set of all inputs converted to values
|
|
42
|
+
|
|
43
|
+
/** @type {any} */
|
|
44
|
+
#pending = undefined; // intermediate value
|
|
45
|
+
|
|
46
|
+
/** @type {any} */
|
|
47
|
+
#value = undefined; // final value
|
|
48
|
+
|
|
49
|
+
/** @type {boolean|undefined} */
|
|
50
|
+
#condition;
|
|
51
|
+
|
|
52
|
+
// explicit state flags
|
|
53
|
+
/** @type {boolean} - are we done with final value? */
|
|
54
|
+
#processed = false;
|
|
55
|
+
|
|
56
|
+
/** @type {boolean} - cached completion status of this state and its children */
|
|
57
|
+
#completed = false;
|
|
58
|
+
|
|
59
|
+
/** @type {boolean|undefined} - cached required status of this state and its children */
|
|
60
|
+
#required = undefined;
|
|
61
|
+
|
|
62
|
+
/** @type {boolean} */
|
|
63
|
+
#mandatory = false; // was the input explicit or implicit?
|
|
64
|
+
// implicit state flags
|
|
65
|
+
|
|
66
|
+
/** @type {string[]|undefined} */
|
|
67
|
+
#unionKeys = undefined;
|
|
68
|
+
|
|
69
|
+
/** @type {object|undefined} - cached options to provide to processors */
|
|
70
|
+
#options;
|
|
71
|
+
|
|
72
|
+
/** @type {{[key:string]:Executor}} */
|
|
73
|
+
executorCache = {};
|
|
74
|
+
/**
|
|
75
|
+
* @param {TraversalContext} context
|
|
76
|
+
* @param {string} path
|
|
77
|
+
*/
|
|
78
|
+
constructor(context, path) {
|
|
79
|
+
this.#context = context;
|
|
80
|
+
this.#path = path;
|
|
81
|
+
this.#location = context.root.absolute(path);
|
|
82
|
+
|
|
83
|
+
if (this.#path === '') {
|
|
84
|
+
this.#name = '';
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const dot = this.#path.lastIndexOf('.');
|
|
88
|
+
const parentPath = (dot === -1) ? '' : this.#path.slice(0, dot);
|
|
89
|
+
this.#parent = this.#context.getState(parentPath);
|
|
90
|
+
this.#name = (dot === -1) ? this.#path : this.#path.slice(dot + 1);
|
|
91
|
+
|
|
92
|
+
this.#parent.#children.set(this.#name, this);
|
|
93
|
+
}
|
|
94
|
+
this.#key = /^\d+$/.test(this.#name) ? Number(this.#name) : this.#name;
|
|
95
|
+
|
|
96
|
+
if (this.#location?.schema !== undefined && !this.#location.schema.hasConditions) {
|
|
97
|
+
this.#condition = true;
|
|
98
|
+
}
|
|
99
|
+
this.completed = false; // ensure that any parent is now also marked incomplete
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get context() {
|
|
103
|
+
return this.#context;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get parent() {
|
|
107
|
+
return this.#parent;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get path() {
|
|
111
|
+
return this.#path;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get name() {
|
|
115
|
+
return this.#name;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get key() {
|
|
119
|
+
return this.#key;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** @type {SchemaLocation|undefined} */
|
|
123
|
+
get location() {
|
|
124
|
+
if (this.#location === undefined) {
|
|
125
|
+
this.#location = this.context.root.absolute(this.path);
|
|
126
|
+
}
|
|
127
|
+
return this.#location;
|
|
128
|
+
}
|
|
129
|
+
set location(location) {
|
|
130
|
+
this.#location = location;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** @type {CompiledSchema|undefined} */
|
|
134
|
+
get schema() {
|
|
135
|
+
return this.location?.schema;
|
|
136
|
+
}
|
|
137
|
+
set schema(schema) {
|
|
138
|
+
if (this.location === undefined || schema === undefined) {
|
|
139
|
+
// todo - This probably would indicate a library coding error.
|
|
140
|
+
// If user code triggers this exception, file a bug!
|
|
141
|
+
throw new SchemaError('Inconsistent traversal state', {location: this.location});
|
|
142
|
+
}
|
|
143
|
+
const currentSchema = this.schema;
|
|
144
|
+
if (currentSchema && currentSchema !== schema) {
|
|
145
|
+
if (currentSchema.isUnion) {
|
|
146
|
+
this.unionKey = currentSchema.findUnionKey(schema);
|
|
147
|
+
if (!this.unionKey) {
|
|
148
|
+
throw new SchemaError('Union resolved to an unknown schema');
|
|
149
|
+
}
|
|
150
|
+
this.executorCache = {}; // previously held old discriminator!
|
|
151
|
+
this.location.schema = schema;
|
|
152
|
+
this.invalidate();
|
|
153
|
+
this.invalidateChildren(); // yuck, but necessary...
|
|
154
|
+
}
|
|
155
|
+
this.context.update();
|
|
156
|
+
}
|
|
157
|
+
this.location.schema = schema;
|
|
158
|
+
|
|
159
|
+
if (!schema.hasConditions) {
|
|
160
|
+
this.#condition = true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** @type {boolean|undefined} */
|
|
165
|
+
get condition() {
|
|
166
|
+
return this.#condition;
|
|
167
|
+
}
|
|
168
|
+
set condition(condition) {
|
|
169
|
+
if (this.#condition !== condition) {
|
|
170
|
+
if (condition === false && this.#condition === true) {
|
|
171
|
+
return; // currently disallowing changing a positive condition; todo - think about this
|
|
172
|
+
}
|
|
173
|
+
this.context.update();
|
|
174
|
+
}
|
|
175
|
+
this.#condition = condition;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** @type {string|undefined} */
|
|
179
|
+
get unionKey() {
|
|
180
|
+
return this.#unionKeys? this.#unionKeys[0] : undefined;
|
|
181
|
+
}
|
|
182
|
+
set unionKey(key) {
|
|
183
|
+
if (key === undefined) {
|
|
184
|
+
this.#unionKeys = undefined;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
this.#unionKeys ??= [];
|
|
188
|
+
this.#unionKeys.unshift(key);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @param {string} propertyName
|
|
195
|
+
* @returns {TraversalState}
|
|
196
|
+
*/
|
|
197
|
+
getChildState(propertyName) {
|
|
198
|
+
if (propertyName === '') {
|
|
199
|
+
return this;
|
|
200
|
+
}
|
|
201
|
+
return this.#children.get(propertyName)
|
|
202
|
+
?? this.context.getState(this.path ? `${this.path}.${propertyName}` : `${propertyName}`)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
getRelativeState(path) {
|
|
206
|
+
const location = this.location?.relative(path);
|
|
207
|
+
return location? this.context.getState(location) : undefined;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
get assignedInput() {
|
|
211
|
+
return this.#assignedInput;
|
|
212
|
+
}
|
|
213
|
+
set assignedInput(assignedInput) {
|
|
214
|
+
if (assignedInput === null) {
|
|
215
|
+
this.value = null; // value pruned! todo - consider a schema option to allow it to be an input?
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (deepEquals(assignedInput, this.#assignedInput)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
// todo - check hasProcessedInput to avoid flapping?
|
|
222
|
+
this.context.update();
|
|
223
|
+
this.processed = false
|
|
224
|
+
this.completed = false;
|
|
225
|
+
|
|
226
|
+
this.#assignedInput = assignedInput;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
get input() {
|
|
230
|
+
return this.#input;
|
|
231
|
+
}
|
|
232
|
+
set input(input) {
|
|
233
|
+
if (input === null) {
|
|
234
|
+
this.value = null; // value pruned! todo - consider a schema option to allow it to be an input?
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (deepEquals(input, this.#input)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.context.update();
|
|
241
|
+
this.processed = false;
|
|
242
|
+
this.completed = false;
|
|
243
|
+
|
|
244
|
+
this.#input = input;
|
|
245
|
+
|
|
246
|
+
if (this.schema === undefined) {
|
|
247
|
+
// todo - what about unresolved union assignments?
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (!this.schema?.hasChildren && input !== undefined) {
|
|
251
|
+
this.mandatory = true;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (this.schema.hasChildren) {
|
|
255
|
+
if (isPlainObject(input) || (typeof input === 'object' && this.isIncremental)) {
|
|
256
|
+
for (const [k,v] of Object.entries(input)) {
|
|
257
|
+
if (v !== undefined && v !== null) {
|
|
258
|
+
const propertyState = this.getChildState(k);
|
|
259
|
+
propertyState.assignedInput = v;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else if (Array.isArray(input)) {
|
|
264
|
+
for (let i = 0; i < input.length; ++i) {
|
|
265
|
+
const v = input[i];
|
|
266
|
+
if (v !== undefined && v !== null) {
|
|
267
|
+
const propertyState = this.getChildState(`${i}`);
|
|
268
|
+
propertyState.assignedInput = v;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (this.schema?.hasChildren && !this.schema.isUnion) {
|
|
275
|
+
if (input !== EMPTY && (!isEmpty(input) || this.schema.options.allowEmpty)) {
|
|
276
|
+
this.mandatory = true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
get pending() {
|
|
283
|
+
return this.#pending;
|
|
284
|
+
}
|
|
285
|
+
set pending(pending) {
|
|
286
|
+
if (pending === null) {
|
|
287
|
+
this.value = null;
|
|
288
|
+
this.#pending = undefined;
|
|
289
|
+
}
|
|
290
|
+
this.#pending = pending;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
get value() {
|
|
294
|
+
return this.#value;
|
|
295
|
+
}
|
|
296
|
+
set value(value) {
|
|
297
|
+
// use invalidate() to deliberately set value to undefined!
|
|
298
|
+
if (this.#value !== undefined && value === undefined) {
|
|
299
|
+
throw new SchemaError('Cannot unset value', {location: this.location});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (this.#value === value) {
|
|
303
|
+
// todo - deepEquals?
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (this.isPruned) {
|
|
307
|
+
// todo - This likely indicates a library coding error.
|
|
308
|
+
// If user code triggers this exception, file a bug!
|
|
309
|
+
throw new SchemaError(`Cannot set value at ${this.path} - node is pruned`);
|
|
310
|
+
}
|
|
311
|
+
if (isPrimitive(value) && this.schema?.hasChildren && !this.schema?.isImplicit && !this.schema?.isOpaque) {
|
|
312
|
+
throw new SchemaError('Container processing resulted in unexpected primitive', {value, location: this.location});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
this.#value = value;
|
|
316
|
+
this.context.update();
|
|
317
|
+
|
|
318
|
+
if (value === undefined) {
|
|
319
|
+
// this.isComplete = false;
|
|
320
|
+
this.completed = false;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (this.path === '') {
|
|
324
|
+
this.processed = true;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (value !== undefined) {
|
|
328
|
+
this.#inputs.add(this.assignedInput);
|
|
329
|
+
}
|
|
330
|
+
if (value === null && !this.processed) {
|
|
331
|
+
this.processed = true;
|
|
332
|
+
// this.isComplete = true;
|
|
333
|
+
this.completed = true;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Sometimes transformers get called with a populated pending object. If the transformed object isn't opaque,
|
|
339
|
+
* we can do a selective shallow copy over to the transformed object.
|
|
340
|
+
* @param {any} pending
|
|
341
|
+
* @param {any} value
|
|
342
|
+
* @package
|
|
343
|
+
*/
|
|
344
|
+
copyPendingChildValues(pending, value) {
|
|
345
|
+
if (value !== undefined && !this.isOpaque && this.hasChildren && value !== pending && isObject(value) && isObject(pending)) {
|
|
346
|
+
// we're not opaque, so that means we will ensure it has everything copied into it that it needs.
|
|
347
|
+
|
|
348
|
+
for (const [pendingKey, pendingValue] of Object.entries(pending)) {
|
|
349
|
+
if (pendingValue === undefined) {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
const child = this.#children.get(pendingKey);
|
|
353
|
+
|
|
354
|
+
if (child?.schema && !child.schema.isImplicit) {
|
|
355
|
+
if (child.isPruned) {
|
|
356
|
+
if (value[pendingKey] !== undefined) {
|
|
357
|
+
delete value[pendingKey];
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
if (value[pendingKey] !== pendingValue) {
|
|
362
|
+
value[pendingKey] = pendingValue;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
invalidate() {
|
|
374
|
+
// todo - do we really want to clear the condition?
|
|
375
|
+
this.#condition = (this.location?.schema && !this.location.schema.hasConditions) ? true : undefined;
|
|
376
|
+
this.#value = undefined;
|
|
377
|
+
this.#processed = false;
|
|
378
|
+
this.#options = undefined;
|
|
379
|
+
this.#required = undefined;
|
|
380
|
+
this.context.update();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
// If the input came from the user (e.g. not synthesized as a mid-path container) it must be processed
|
|
385
|
+
get mandatory() {
|
|
386
|
+
return this.#mandatory;
|
|
387
|
+
}
|
|
388
|
+
set mandatory(value) {
|
|
389
|
+
this.#mandatory = Boolean(value);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
get processed() {
|
|
394
|
+
return this.#processed;
|
|
395
|
+
}
|
|
396
|
+
set processed(value) {
|
|
397
|
+
this.#processed = Boolean(value);
|
|
398
|
+
|
|
399
|
+
if (this.#processed && !this.hasChildren) {
|
|
400
|
+
// this.isComplete = true; // short-circuit completion when we know its safe
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
get isRequired() {
|
|
406
|
+
if (this.#required !== undefined) {
|
|
407
|
+
return this.#required;
|
|
408
|
+
}
|
|
409
|
+
if (this.schema?.required) {
|
|
410
|
+
this.#required = true;
|
|
411
|
+
}
|
|
412
|
+
else if (!this.hasChildren) {
|
|
413
|
+
this.#required = false;
|
|
414
|
+
}
|
|
415
|
+
else if (this.isDeep) {
|
|
416
|
+
for (const child of this.#children.values()) {
|
|
417
|
+
if (child.isRequired) {
|
|
418
|
+
this.#required = true;
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return this.#required ?? false;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// TODO - check this weird case:
|
|
427
|
+
// 1. create an opaque schema with members {x,y,z}. z is conditional on {x,y} being defined.
|
|
428
|
+
// 2. assign {x,y,z}; {x,y} will likely get finalized into the object
|
|
429
|
+
// 3. the z assignment wakes up; is there a way to absorb it? or does it turn into a new {z} object?
|
|
430
|
+
|
|
431
|
+
// todo - flip how this works; any new child assignment should mark parent incomplete
|
|
432
|
+
|
|
433
|
+
/** @type {boolean} */
|
|
434
|
+
get isComplete() {
|
|
435
|
+
|
|
436
|
+
if (this.completed) {
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (this.isPruned) {
|
|
441
|
+
// this.isComplete = true;
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
if (!this.condition && this.context.final) {
|
|
445
|
+
return true; // doesn't look like this is needed
|
|
446
|
+
}
|
|
447
|
+
if (this.value === undefined) {
|
|
448
|
+
// We are definitely not complete if we have no value and required/default settings imply more work to do
|
|
449
|
+
if (this.isRequired) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
if (this.schema?.default !== undefined && (typeof this.schema.default !== 'function' || this.schema.options.dynamic === false)) {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
if (this.hasIncompleteDescendents) {
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
if (this.hasWorkInProgress) {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
if (this.isUnion) { // NEW CHECK, WDYT?
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
if (this.processed) {
|
|
466
|
+
// Normally, processed would not be enough to imply isComplete; a container that allows incremental
|
|
467
|
+
// assignment may be processed before its children. However, we've already checked hasWorkInProgress,
|
|
468
|
+
// which recursively checks for incomplete children!
|
|
469
|
+
|
|
470
|
+
// this.isComplete = true;
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
473
|
+
// NEW CHECK:
|
|
474
|
+
if (this.schema?.isImplicit) {
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
if (this.value !== undefined) {
|
|
478
|
+
return true; // value is set and no child work above!
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (this.schema?.isReference && !this.context.final) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (this.mandatory) {
|
|
486
|
+
// processing is mandatory!
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
if (typeof this.assignedInput === 'function' && this.schema?.options.dynamic !== false && this.input === undefined) {
|
|
490
|
+
// we have a dynamic input (default?), but it hasn't returned a value; this is ok when final
|
|
491
|
+
|
|
492
|
+
return this.context.final;
|
|
493
|
+
}
|
|
494
|
+
else if (this.assignedInput !== undefined && !this.#inputs.has(this.assignedInput)) {
|
|
495
|
+
// the input does not seem to have been fully processed (nor discarded).
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// todo - this is an experiment; is it safe to formalize checking traversals?
|
|
500
|
+
if (this.assignedInput === undefined && this.context.traversals > 0) {
|
|
501
|
+
// this.isComplete = true;
|
|
502
|
+
return true;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// if we don't have an assignment and are on the final pass, we're complete.
|
|
506
|
+
return Boolean(this.assignedInput === undefined && this.context.final);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
get completed() {
|
|
510
|
+
return this.#completed;
|
|
511
|
+
}
|
|
512
|
+
set completed(value) {
|
|
513
|
+
this.#completed = Boolean(value);
|
|
514
|
+
|
|
515
|
+
if (!this.#completed && this.parent?.completed) {
|
|
516
|
+
this.parent.completed = false;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
get hasProcessedInput() {
|
|
521
|
+
// return this.value !== undefined && this.assignedInput !== undefined && this.#inputs.has(this.assignedInput);
|
|
522
|
+
return this.value !== undefined && this.assignedInput !== undefined && this.input !== undefined && this.#inputs.has(this.assignedInput);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
get isPlaceholder() {
|
|
526
|
+
if (this.schema?.default !== undefined) {
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
return !this.mandatory && /*this.#path !== '' &&*/ this.value === undefined;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
get hasChildren() {
|
|
533
|
+
return this.schema?.hasChildren ?? false;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
get isContainer() {
|
|
537
|
+
return this.schema?.isContainer ?? false;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
get isPruned() {
|
|
541
|
+
return this.#value === null || Boolean(this.#parent?.isPruned);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
get isDeep() {
|
|
545
|
+
return this.schema?.deep ?? this.context.deep;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
get isOpaque() {
|
|
549
|
+
if (this.schema === undefined) {
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
return !this.hasChildren || this.schema.isOpaque;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
get isIncremental() {
|
|
556
|
+
if (this.schema === undefined) {
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
559
|
+
return this.hasChildren && !this.schema.isOpaque;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
get isStrict() {
|
|
563
|
+
if (this.schema === undefined) {
|
|
564
|
+
return this.parent?.isStrict ?? this.context.strict;
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
return this.schema.strict ?? this.context.strict;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
get allowUnknown() {
|
|
572
|
+
return !this.isStrict;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
get isUnion() {
|
|
576
|
+
return this.schema?.isUnion ?? false;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
get isUnresolved() {
|
|
580
|
+
return this.schema === undefined || this.schema.isUnion;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
get treatAsExplicit() {
|
|
584
|
+
if (this.schema === undefined) {
|
|
585
|
+
return true; // force processing so that we know about errors
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (this.schema.isImplicit) {
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return !(this.hasChildren && this.isIncremental);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
get hasDescendentStates() {
|
|
596
|
+
if (!this.hasChildren) {
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
return this.#children.size > 0;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
get hasDescendentsToTraverse() {
|
|
603
|
+
if (!this.hasChildren) {
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Check for properties in input
|
|
608
|
+
const hasInputProperties = typeof this.#input === 'object' && !isEmpty(this.#input);
|
|
609
|
+
|
|
610
|
+
// const hasDefaults = Object.values(this._schema?.properties).some(childSchema => childSchema.default !== undefined);
|
|
611
|
+
|
|
612
|
+
return this.hasDescendentStates || hasInputProperties;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
get hasIncompleteDescendents() {
|
|
616
|
+
if (!this.hasChildren) {
|
|
617
|
+
return false;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// return [...this.#children.values()].some(childState => !childState.isComplete);
|
|
621
|
+
return [...this.#children.values()].some(childState => !childState.completed);
|
|
622
|
+
}
|
|
623
|
+
get incompleteDescendents() {
|
|
624
|
+
if (!this.hasChildren) {
|
|
625
|
+
return [];
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const childPrefix = this.path ? `${this.path}.` : '';
|
|
629
|
+
return Array.from(this.#context.stateMap.values())
|
|
630
|
+
.filter(childState =>
|
|
631
|
+
childState.path !== this.path &&
|
|
632
|
+
childState.path.startsWith(childPrefix) &&
|
|
633
|
+
!childState.isComplete
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
findIncompleteChildNames(incomplete = new Set()) {
|
|
638
|
+
for (const childState of this.#children.values()) {
|
|
639
|
+
// if (!childState.isComplete) {
|
|
640
|
+
if (!childState.completed) {
|
|
641
|
+
incomplete.add(childState.name);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return incomplete;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
listIncompleteChildren() {
|
|
648
|
+
return [...this.#children.values()].filter(childState => !childState.isComplete).map(childState => childState.name);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
listPendingChildren() {
|
|
652
|
+
|
|
653
|
+
return [...this.#children.values()].filter(childState => childState.hasWorkInProgress || childState.needsInputProcessing).map(childState => childState.name);
|
|
654
|
+
/*
|
|
655
|
+
const childPrefix = this.path ? `${this.path}.` : '';
|
|
656
|
+
|
|
657
|
+
const pending = new Set([...this.context.stateMap]
|
|
658
|
+
.filter(([path, state]) => (path !== this.path && path.startsWith(
|
|
659
|
+
childPrefix) && (state.hasWorkInProgress || state.needsInputProcessing)))
|
|
660
|
+
.map(([path]) => {
|
|
661
|
+
return path.slice(childPrefix.length).split('.')[0]
|
|
662
|
+
}));
|
|
663
|
+
|
|
664
|
+
return [...pending];
|
|
665
|
+
|
|
666
|
+
*/
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
invalidateChildren() {
|
|
670
|
+
// this is called after union resolution!
|
|
671
|
+
|
|
672
|
+
for (const childState of this.#children.values()) {
|
|
673
|
+
if (childState.value !== null) {
|
|
674
|
+
childState.invalidate();
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
get isEmptyPlaceholder() {
|
|
680
|
+
if (!this.schema?.hasChildren) {
|
|
681
|
+
// concrete schemas are never placeholders
|
|
682
|
+
return false;
|
|
683
|
+
}
|
|
684
|
+
if (!this.isPlaceholder) {
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
return !this.hasDescendentsToTraverse;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
get needsInputProcessing() {
|
|
692
|
+
if (this.value !== undefined) {
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
695
|
+
return (typeof this.assignedInput !== undefined && (this.input === undefined || this.pending === undefined));
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
get hasWorkInProgress() {
|
|
699
|
+
if (this.isPruned) {
|
|
700
|
+
return false;
|
|
701
|
+
}
|
|
702
|
+
// if (this.hasIncompleteDescendents) {
|
|
703
|
+
// return true;
|
|
704
|
+
// }
|
|
705
|
+
if (this.pending === undefined) {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
if (this.schema?.isImplicit) {
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
if (!this.hasChildren) {
|
|
712
|
+
return true;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if (isEmpty(this.pending)) {
|
|
716
|
+
if (this.schema?.options.allowEmpty) {
|
|
717
|
+
return true;
|
|
718
|
+
}
|
|
719
|
+
// The WIP is an empty array or object; if we have a processed value, that's all that matters.
|
|
720
|
+
if (this.processed) {
|
|
721
|
+
return false;
|
|
722
|
+
}
|
|
723
|
+
if (this.mandatory) {
|
|
724
|
+
return true;
|
|
725
|
+
}
|
|
726
|
+
return false; /// fixme ????
|
|
727
|
+
}
|
|
728
|
+
return true;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Retrieve all incomplete child property states
|
|
734
|
+
*
|
|
735
|
+
* @type {Array<TraversalState>}
|
|
736
|
+
*/
|
|
737
|
+
get activePropertyStates() {
|
|
738
|
+
if (this.completed) {
|
|
739
|
+
return [];
|
|
740
|
+
}
|
|
741
|
+
if (this.schema === undefined) {
|
|
742
|
+
return [];
|
|
743
|
+
}
|
|
744
|
+
if (this.isOpaque && this.processed) {
|
|
745
|
+
return [];
|
|
746
|
+
}
|
|
747
|
+
if (!this.condition) {
|
|
748
|
+
return [];
|
|
749
|
+
}
|
|
750
|
+
if (this.pending === undefined && this.value === undefined && !this.schema.options.allowUndefined && !this.schema.options.deep) {
|
|
751
|
+
return [];
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
if (!this.schema.hasChildren) {
|
|
755
|
+
return [];
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
const propertyKeys = new Set();
|
|
760
|
+
const input = this.input// ?? this.assignedInput;
|
|
761
|
+
|
|
762
|
+
if (isPlainObject(input) || Array.isArray(input) || (input && this.isIncremental)) {
|
|
763
|
+
Object.keys(input).forEach(key => {
|
|
764
|
+
propertyKeys.add(key)
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
this.findIncompleteChildNames(propertyKeys);
|
|
769
|
+
|
|
770
|
+
if (this.isIncremental || this.value === undefined) {
|
|
771
|
+
// If it is opaque and already has a value, it's too late to check the schema's properties
|
|
772
|
+
for (const [propertyKey, propertySchema] of this.schema.propertyEntries) {
|
|
773
|
+
if (propertyKey === '*') {
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
if (this.context.final || this.isDeep || propertySchema.required || propertySchema.default !== undefined || propertySchema.isReference) {
|
|
777
|
+
propertyKeys.add(propertyKey);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const container = this.pending ?? (this.isIncremental? this.value : undefined);
|
|
783
|
+
|
|
784
|
+
const existingProperties = (Array.isArray(container) && container.length) || (isPlainObject(container) && Object.keys(container).length);
|
|
785
|
+
if (!existingProperties && !this.mandatory && this.input === undefined && !this.isDeep && !this.hasIncompleteDescendents) {
|
|
786
|
+
return [];
|
|
787
|
+
}
|
|
788
|
+
if (existingProperties && this.context.final) {
|
|
789
|
+
Object.keys(container).forEach(key => {
|
|
790
|
+
if (this.isStrict || this.schema?.getPropertySchema(key)) {
|
|
791
|
+
propertyKeys.add(key)
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
//return [...propertyKeys].map(propertyKey => this.relative(propertyKey)).filter(s => s?.isComplete === false);
|
|
796
|
+
return [...propertyKeys].map(propertyKey => this.getChildState(propertyKey));
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
get target() {
|
|
800
|
+
return this.context.getValue();
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
get options() {
|
|
804
|
+
if (this.#options === undefined) {
|
|
805
|
+
this.#options = { ...this.context.options, deep: this.isDeep, strict: this.isStrict, state: this, context: this.context }
|
|
806
|
+
}
|
|
807
|
+
return this.#options;
|
|
808
|
+
}
|
|
809
|
+
}
|