@clementine-solutions/jane-io 1.0.0 → 1.0.2
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/README.md +132 -1
- package/dist/core/analysis/diff.d.ts +35 -0
- package/dist/core/analysis/diff.js +88 -0
- package/dist/core/analysis/explain.d.ts +35 -0
- package/dist/core/analysis/explain.js +117 -0
- package/dist/core/analysis/index.d.ts +14 -0
- package/dist/core/analysis/index.js +26 -0
- package/dist/core/analysis/replay.d.ts +34 -0
- package/dist/core/analysis/replay.js +68 -0
- package/dist/core/analysis/telemetry.d.ts +28 -0
- package/dist/core/analysis/telemetry.js +123 -0
- package/dist/core/boundary-rules/at-most-one.d.ts +17 -0
- package/dist/core/boundary-rules/at-most-one.js +38 -0
- package/dist/core/boundary-rules/conditionally-required.d.ts +18 -0
- package/dist/core/boundary-rules/conditionally-required.js +44 -0
- package/dist/core/boundary-rules/date-range.d.ts +17 -0
- package/dist/core/boundary-rules/date-range.js +39 -0
- package/dist/core/boundary-rules/index.d.ts +18 -0
- package/dist/core/boundary-rules/index.js +21 -0
- package/dist/core/boundary-rules/mutually-exclusive.d.ts +16 -0
- package/dist/core/boundary-rules/mutually-exclusive.js +38 -0
- package/dist/core/boundary-rules/no-unknown-fields.d.ts +17 -0
- package/dist/core/boundary-rules/no-unknown-fields.js +39 -0
- package/dist/core/boundary-rules/require-all.d.ts +16 -0
- package/dist/core/boundary-rules/require-all.js +39 -0
- package/dist/core/boundary-rules/require-one.d.ts +17 -0
- package/dist/core/boundary-rules/require-one.js +41 -0
- package/dist/core/common/events.d.ts +37 -0
- package/dist/core/common/events.js +82 -0
- package/dist/core/common/fluent.d.ts +151 -0
- package/dist/core/common/fluent.js +429 -0
- package/dist/core/common/index.d.ts +16 -0
- package/dist/core/common/index.js +31 -0
- package/dist/core/common/policy.d.ts +170 -0
- package/dist/core/common/policy.js +550 -0
- package/dist/core/common/utilities.d.ts +59 -0
- package/dist/core/common/utilities.js +177 -0
- package/dist/core/common/wildcard.d.ts +27 -0
- package/dist/core/common/wildcard.js +63 -0
- package/dist/core/field-path/construct.d.ts +77 -0
- package/dist/core/field-path/construct.js +189 -0
- package/dist/core/field-path/format.d.ts +41 -0
- package/dist/core/field-path/format.js +154 -0
- package/dist/core/field-path/index.d.ts +14 -0
- package/dist/core/field-path/index.js +26 -0
- package/dist/core/field-path/utilities.d.ts +85 -0
- package/dist/core/field-path/utilities.js +138 -0
- package/dist/core/field-path/walk.d.ts +36 -0
- package/dist/core/field-path/walk.js +80 -0
- package/dist/core/fluent-registry.d.ts +138 -0
- package/dist/core/fluent-registry.js +151 -0
- package/dist/core/normalizers/array/compact-sparse-array.d.ts +22 -0
- package/dist/core/normalizers/array/compact-sparse-array.js +40 -0
- package/dist/core/normalizers/array/flatten-one-level.d.ts +17 -0
- package/dist/core/normalizers/array/flatten-one-level.js +45 -0
- package/dist/core/normalizers/array/remove-empty-string-items.d.ts +6 -0
- package/dist/core/normalizers/array/remove-empty-string-items.js +34 -0
- package/dist/core/normalizers/array/remove-null-items.d.ts +16 -0
- package/dist/core/normalizers/array/remove-null-items.js +34 -0
- package/dist/core/normalizers/array/remove-undefined-items.d.ts +16 -0
- package/dist/core/normalizers/array/remove-undefined-items.js +34 -0
- package/dist/core/normalizers/date/invalid-date-to-undefined.d.ts +17 -0
- package/dist/core/normalizers/date/invalid-date-to-undefined.js +35 -0
- package/dist/core/normalizers/index.d.ts +28 -0
- package/dist/core/normalizers/index.js +46 -0
- package/dist/core/normalizers/normalizer-register.d.ts +17 -0
- package/dist/core/normalizers/normalizer-register.js +41 -0
- package/dist/core/normalizers/number/infinity-to-undefined.d.ts +18 -0
- package/dist/core/normalizers/number/infinity-to-undefined.js +35 -0
- package/dist/core/normalizers/number/nan-to-undefined.d.ts +17 -0
- package/dist/core/normalizers/number/nan-to-undefined.js +34 -0
- package/dist/core/normalizers/number/normalize-negative-zero.d.ts +16 -0
- package/dist/core/normalizers/number/normalize-negative-zero.js +33 -0
- package/dist/core/normalizers/object/remove-empty-array-keys.d.ts +17 -0
- package/dist/core/normalizers/object/remove-empty-array-keys.js +38 -0
- package/dist/core/normalizers/object/remove-empty-object-keys.d.ts +16 -0
- package/dist/core/normalizers/object/remove-empty-object-keys.js +42 -0
- package/dist/core/normalizers/object/remove-empty-string-keys.d.ts +16 -0
- package/dist/core/normalizers/object/remove-empty-string-keys.js +37 -0
- package/dist/core/normalizers/object/remove-null-keys.d.ts +16 -0
- package/dist/core/normalizers/object/remove-null-keys.js +37 -0
- package/dist/core/normalizers/object/remove-undefined-keys.d.ts +16 -0
- package/dist/core/normalizers/object/remove-undefined-keys.js +37 -0
- package/dist/core/normalizers/string/collapse-whitespace.d.ts +17 -0
- package/dist/core/normalizers/string/collapse-whitespace.js +35 -0
- package/dist/core/normalizers/string/empty-to-undefined.d.ts +16 -0
- package/dist/core/normalizers/string/empty-to-undefined.js +33 -0
- package/dist/core/normalizers/string/trim.d.ts +16 -0
- package/dist/core/normalizers/string/trim.js +34 -0
- package/dist/core/parsers/index.d.ts +22 -0
- package/dist/core/parsers/index.js +43 -0
- package/dist/core/parsers/parse-array-string.d.ts +16 -0
- package/dist/core/parsers/parse-array-string.js +36 -0
- package/dist/core/parsers/parse-bigint-string.d.ts +16 -0
- package/dist/core/parsers/parse-bigint-string.js +33 -0
- package/dist/core/parsers/parse-binary-string.d.ts +16 -0
- package/dist/core/parsers/parse-binary-string.js +33 -0
- package/dist/core/parsers/parse-boolean-string.d.ts +16 -0
- package/dist/core/parsers/parse-boolean-string.js +27 -0
- package/dist/core/parsers/parse-date-string.d.ts +16 -0
- package/dist/core/parsers/parse-date-string.js +30 -0
- package/dist/core/parsers/parse-duration-string.d.ts +16 -0
- package/dist/core/parsers/parse-duration-string.js +37 -0
- package/dist/core/parsers/parse-hex-string.d.ts +16 -0
- package/dist/core/parsers/parse-hex-string.js +29 -0
- package/dist/core/parsers/parse-integer-string.d.ts +16 -0
- package/dist/core/parsers/parse-integer-string.js +30 -0
- package/dist/core/parsers/parse-json-string.d.ts +17 -0
- package/dist/core/parsers/parse-json-string.js +35 -0
- package/dist/core/parsers/parse-numeric-string.d.ts +16 -0
- package/dist/core/parsers/parse-numeric-string.js +29 -0
- package/dist/core/parsers/parse-object-string.d.ts +16 -0
- package/dist/core/parsers/parse-object-string.js +36 -0
- package/dist/core/parsers/parse-octal-string.d.ts +16 -0
- package/dist/core/parsers/parse-octal-string.js +33 -0
- package/dist/core/parsers/parse-scientific-notation-string.d.ts +16 -0
- package/dist/core/parsers/parse-scientific-notation-string.js +30 -0
- package/dist/core/parsers/parse-url-string.d.ts +16 -0
- package/dist/core/parsers/parse-url-string.js +36 -0
- package/dist/core/pipeline/boundary.d.ts +36 -0
- package/dist/core/pipeline/boundary.js +256 -0
- package/dist/core/pipeline/contain.d.ts +122 -0
- package/dist/core/pipeline/contain.js +339 -0
- package/dist/core/pipeline/index.d.ts +16 -0
- package/dist/core/pipeline/index.js +37 -0
- package/dist/core/pipeline/normalize.d.ts +34 -0
- package/dist/core/pipeline/normalize.js +76 -0
- package/dist/core/pipeline/parse.d.ts +40 -0
- package/dist/core/pipeline/parse.js +91 -0
- package/dist/core/pipeline/pipeline.d.ts +23 -0
- package/dist/core/pipeline/pipeline.js +418 -0
- package/dist/core/pipeline/scan.d.ts +46 -0
- package/dist/core/pipeline/scan.js +115 -0
- package/dist/core/pipeline/validate.d.ts +40 -0
- package/dist/core/pipeline/validate.js +74 -0
- package/dist/core/scanners/any/scan-for-sentinels.d.ts +19 -0
- package/dist/core/scanners/any/scan-for-sentinels.js +35 -0
- package/dist/core/scanners/array/array-is-deep.d.ts +19 -0
- package/dist/core/scanners/array/array-is-deep.js +38 -0
- package/dist/core/scanners/array/array-is-heterogenous.d.ts +18 -0
- package/dist/core/scanners/array/array-is-heterogenous.js +39 -0
- package/dist/core/scanners/array/array-is-large.d.ts +19 -0
- package/dist/core/scanners/array/array-is-large.js +32 -0
- package/dist/core/scanners/bigint/bigint-is-large.d.ts +20 -0
- package/dist/core/scanners/bigint/bigint-is-large.js +34 -0
- package/dist/core/scanners/bigint/bigint-not-safe.d.ts +20 -0
- package/dist/core/scanners/bigint/bigint-not-safe.js +34 -0
- package/dist/core/scanners/date/date-is-before-epoch.d.ts +19 -0
- package/dist/core/scanners/date/date-is-before-epoch.js +32 -0
- package/dist/core/scanners/date/date-is-far-future.d.ts +19 -0
- package/dist/core/scanners/date/date-is-far-future.js +32 -0
- package/dist/core/scanners/date/date-is-invalid.d.ts +19 -0
- package/dist/core/scanners/date/date-is-invalid.js +31 -0
- package/dist/core/scanners/index.d.ts +31 -0
- package/dist/core/scanners/index.js +58 -0
- package/dist/core/scanners/number/number-is-infinite.d.ts +19 -0
- package/dist/core/scanners/number/number-is-infinite.js +31 -0
- package/dist/core/scanners/number/number-is-nan.d.ts +19 -0
- package/dist/core/scanners/number/number-is-nan.js +31 -0
- package/dist/core/scanners/number/number-is-too-large.d.ts +20 -0
- package/dist/core/scanners/number/number-is-too-large.js +33 -0
- package/dist/core/scanners/number/number-is-unsafe-integer.d.ts +19 -0
- package/dist/core/scanners/number/number-is-unsafe-integer.js +31 -0
- package/dist/core/scanners/object/object-has-circular-references.d.ts +20 -0
- package/dist/core/scanners/object/object-has-circular-references.js +43 -0
- package/dist/core/scanners/object/object-has-many-keys.d.ts +19 -0
- package/dist/core/scanners/object/object-has-many-keys.js +33 -0
- package/dist/core/scanners/object/object-is-deep.d.ts +20 -0
- package/dist/core/scanners/object/object-is-deep.js +38 -0
- package/dist/core/scanners/scanner-registry.d.ts +19 -0
- package/dist/core/scanners/scanner-registry.js +36 -0
- package/dist/core/scanners/string/string-has-unsafe-unicode.d.ts +19 -0
- package/dist/core/scanners/string/string-has-unsafe-unicode.js +32 -0
- package/dist/core/scanners/string/string-has-whitespace-edges.d.ts +19 -0
- package/dist/core/scanners/string/string-has-whitespace-edges.js +31 -0
- package/dist/core/scanners/string/string-is-long.d.ts +19 -0
- package/dist/core/scanners/string/string-is-long.js +32 -0
- package/dist/core/scanners/unknown/unknown-not-scannable.d.ts +21 -0
- package/dist/core/scanners/unknown/unknown-not-scannable.js +34 -0
- package/dist/core/shapes/analysis.d.ts +239 -0
- package/dist/core/shapes/analysis.js +11 -0
- package/dist/core/shapes/boundary.d.ts +126 -0
- package/dist/core/shapes/boundary.js +11 -0
- package/dist/core/shapes/events.d.ts +83 -0
- package/dist/core/shapes/events.js +10 -0
- package/dist/core/shapes/field-path.d.ts +51 -0
- package/dist/core/shapes/field-path.js +10 -0
- package/dist/core/shapes/index.d.ts +21 -0
- package/dist/core/shapes/index.js +11 -0
- package/dist/core/shapes/normalize.d.ts +59 -0
- package/dist/core/shapes/normalize.js +11 -0
- package/dist/core/shapes/parse.d.ts +75 -0
- package/dist/core/shapes/parse.js +11 -0
- package/dist/core/shapes/pipeline.d.ts +149 -0
- package/dist/core/shapes/pipeline.js +11 -0
- package/dist/core/shapes/policy.d.ts +158 -0
- package/dist/core/shapes/policy.js +11 -0
- package/dist/core/shapes/public.d.ts +92 -0
- package/dist/core/shapes/public.js +10 -0
- package/dist/core/shapes/scan.d.ts +126 -0
- package/dist/core/shapes/scan.js +11 -0
- package/dist/core/shapes/validate.d.ts +65 -0
- package/dist/core/shapes/validate.js +11 -0
- package/dist/core/validators/array/array-max-items.d.ts +25 -0
- package/dist/core/validators/array/array-max-items.js +42 -0
- package/dist/core/validators/array/array-min-items.d.ts +25 -0
- package/dist/core/validators/array/array-min-items.js +42 -0
- package/dist/core/validators/array/array.d.ts +22 -0
- package/dist/core/validators/array/array.js +34 -0
- package/dist/core/validators/array/excludes.d.ts +25 -0
- package/dist/core/validators/array/excludes.js +47 -0
- package/dist/core/validators/array/has-unique-items.d.ts +24 -0
- package/dist/core/validators/array/has-unique-items.js +46 -0
- package/dist/core/validators/array/includes.d.ts +24 -0
- package/dist/core/validators/array/includes.js +46 -0
- package/dist/core/validators/array/items-equal.d.ts +25 -0
- package/dist/core/validators/array/items-equal.js +42 -0
- package/dist/core/validators/array/no-empty-string-items.d.ts +24 -0
- package/dist/core/validators/array/no-empty-string-items.js +46 -0
- package/dist/core/validators/array/no-null-items.d.ts +24 -0
- package/dist/core/validators/array/no-null-items.js +46 -0
- package/dist/core/validators/array/no-undefined-items.d.ts +24 -0
- package/dist/core/validators/array/no-undefined-items.js +45 -0
- package/dist/core/validators/array/non-empty-array.d.ts +24 -0
- package/dist/core/validators/array/non-empty-array.js +45 -0
- package/dist/core/validators/array/not-sparse.d.ts +25 -0
- package/dist/core/validators/array/not-sparse.js +44 -0
- package/dist/core/validators/bigint/bigint-equals.d.ts +24 -0
- package/dist/core/validators/bigint/bigint-equals.js +57 -0
- package/dist/core/validators/bigint/bigint-max.d.ts +25 -0
- package/dist/core/validators/bigint/bigint-max.js +63 -0
- package/dist/core/validators/bigint/bigint-min.d.ts +25 -0
- package/dist/core/validators/bigint/bigint-min.js +87 -0
- package/dist/core/validators/bigint/bigint-negative.d.ts +23 -0
- package/dist/core/validators/bigint/bigint-negative.js +73 -0
- package/dist/core/validators/bigint/bigint-non-negative.d.ts +24 -0
- package/dist/core/validators/bigint/bigint-non-negative.js +72 -0
- package/dist/core/validators/bigint/bigint-non-positive.d.ts +24 -0
- package/dist/core/validators/bigint/bigint-non-positive.js +72 -0
- package/dist/core/validators/bigint/bigint-positive.d.ts +24 -0
- package/dist/core/validators/bigint/bigint-positive.js +72 -0
- package/dist/core/validators/bigint/bigint-safe.d.ts +25 -0
- package/dist/core/validators/bigint/bigint-safe.js +75 -0
- package/dist/core/validators/bigint/bigint.d.ts +20 -0
- package/dist/core/validators/bigint/bigint.js +38 -0
- package/dist/core/validators/boolean/boolean.d.ts +21 -0
- package/dist/core/validators/boolean/boolean.js +39 -0
- package/dist/core/validators/boolean/is-false.d.ts +22 -0
- package/dist/core/validators/boolean/is-false.js +48 -0
- package/dist/core/validators/boolean/is-true.d.ts +22 -0
- package/dist/core/validators/boolean/is-true.js +48 -0
- package/dist/core/validators/common/is-country-code.d.ts +17 -0
- package/dist/core/validators/common/is-country-code.js +36 -0
- package/dist/core/validators/common/is-currency-code.d.ts +17 -0
- package/dist/core/validators/common/is-currency-code.js +36 -0
- package/dist/core/validators/common/is-email-strict.d.ts +17 -0
- package/dist/core/validators/common/is-email-strict.js +36 -0
- package/dist/core/validators/common/is-email.d.ts +17 -0
- package/dist/core/validators/common/is-email.js +36 -0
- package/dist/core/validators/common/is-ip.d.ts +17 -0
- package/dist/core/validators/common/is-ip.js +37 -0
- package/dist/core/validators/common/is-phone-strict.d.ts +17 -0
- package/dist/core/validators/common/is-phone-strict.js +36 -0
- package/dist/core/validators/common/is-phone.d.ts +17 -0
- package/dist/core/validators/common/is-phone.js +36 -0
- package/dist/core/validators/common/is-port.d.ts +17 -0
- package/dist/core/validators/common/is-port.js +35 -0
- package/dist/core/validators/common/is-postal-code.d.ts +17 -0
- package/dist/core/validators/common/is-postal-code.js +36 -0
- package/dist/core/validators/common/is-url.d.ts +17 -0
- package/dist/core/validators/common/is-url.js +38 -0
- package/dist/core/validators/common/is-uuid.d.ts +17 -0
- package/dist/core/validators/common/is-uuid.js +36 -0
- package/dist/core/validators/date/before-epoch.d.ts +28 -0
- package/dist/core/validators/date/before-epoch.js +56 -0
- package/dist/core/validators/date/date-now-required.d.ts +22 -0
- package/dist/core/validators/date/date-now-required.js +48 -0
- package/dist/core/validators/date/is-date.d.ts +21 -0
- package/dist/core/validators/date/is-date.js +47 -0
- package/dist/core/validators/date/is-far-future.d.ts +23 -0
- package/dist/core/validators/date/is-far-future.js +46 -0
- package/dist/core/validators/date/is-future.d.ts +24 -0
- package/dist/core/validators/date/is-future.js +59 -0
- package/dist/core/validators/date/is-past.d.ts +24 -0
- package/dist/core/validators/date/is-past.js +59 -0
- package/dist/core/validators/date/not-after.d.ts +25 -0
- package/dist/core/validators/date/not-after.js +66 -0
- package/dist/core/validators/date/not-before.d.ts +25 -0
- package/dist/core/validators/date/not-before.js +66 -0
- package/dist/core/validators/date/same-day.d.ts +25 -0
- package/dist/core/validators/date/same-day.js +60 -0
- package/dist/core/validators/date/same-month.d.ts +25 -0
- package/dist/core/validators/date/same-month.js +59 -0
- package/dist/core/validators/date/same-year.d.ts +24 -0
- package/dist/core/validators/date/same-year.js +56 -0
- package/dist/core/validators/date/too-early.d.ts +25 -0
- package/dist/core/validators/date/too-early.js +57 -0
- package/dist/core/validators/date/too-late.d.ts +25 -0
- package/dist/core/validators/date/too-late.js +57 -0
- package/dist/core/validators/date/weekday.d.ts +32 -0
- package/dist/core/validators/date/weekday.js +65 -0
- package/dist/core/validators/date/weekend.d.ts +27 -0
- package/dist/core/validators/date/weekend.js +56 -0
- package/dist/core/validators/index.d.ts +112 -0
- package/dist/core/validators/index.js +139 -0
- package/dist/core/validators/nullish/is-null-or-undefined.d.ts +22 -0
- package/dist/core/validators/nullish/is-null-or-undefined.js +40 -0
- package/dist/core/validators/nullish/is-null.d.ts +21 -0
- package/dist/core/validators/nullish/is-null.js +39 -0
- package/dist/core/validators/nullish/is-undefined.d.ts +21 -0
- package/dist/core/validators/nullish/is-undefined.js +39 -0
- package/dist/core/validators/number/finite.d.ts +22 -0
- package/dist/core/validators/number/finite.js +40 -0
- package/dist/core/validators/number/integer.d.ts +22 -0
- package/dist/core/validators/number/integer.js +40 -0
- package/dist/core/validators/number/less-than.d.ts +21 -0
- package/dist/core/validators/number/less-than.js +39 -0
- package/dist/core/validators/number/max.d.ts +21 -0
- package/dist/core/validators/number/max.js +39 -0
- package/dist/core/validators/number/min.d.ts +21 -0
- package/dist/core/validators/number/min.js +39 -0
- package/dist/core/validators/number/more-than.d.ts +21 -0
- package/dist/core/validators/number/more-than.js +39 -0
- package/dist/core/validators/number/negative.d.ts +20 -0
- package/dist/core/validators/number/negative.js +38 -0
- package/dist/core/validators/number/non-negative.d.ts +19 -0
- package/dist/core/validators/number/non-negative.js +37 -0
- package/dist/core/validators/number/non-positive.d.ts +19 -0
- package/dist/core/validators/number/non-positive.js +37 -0
- package/dist/core/validators/number/number.d.ts +19 -0
- package/dist/core/validators/number/number.js +31 -0
- package/dist/core/validators/number/positive.d.ts +20 -0
- package/dist/core/validators/number/positive.js +38 -0
- package/dist/core/validators/number/safe-integer.d.ts +19 -0
- package/dist/core/validators/number/safe-integer.js +42 -0
- package/dist/core/validators/object/deep-equals.d.ts +24 -0
- package/dist/core/validators/object/deep-equals.js +47 -0
- package/dist/core/validators/object/has-key.d.ts +23 -0
- package/dist/core/validators/object/has-key.js +42 -0
- package/dist/core/validators/object/has-value.d.ts +27 -0
- package/dist/core/validators/object/has-value.js +59 -0
- package/dist/core/validators/object/keys-equal.d.ts +26 -0
- package/dist/core/validators/object/keys-equal.js +47 -0
- package/dist/core/validators/object/max-keys.d.ts +24 -0
- package/dist/core/validators/object/max-keys.js +43 -0
- package/dist/core/validators/object/min-keys.d.ts +24 -0
- package/dist/core/validators/object/min-keys.js +43 -0
- package/dist/core/validators/object/missing-key.d.ts +23 -0
- package/dist/core/validators/object/missing-key.js +42 -0
- package/dist/core/validators/object/no-empty-array-values.d.ts +23 -0
- package/dist/core/validators/object/no-empty-array-values.js +44 -0
- package/dist/core/validators/object/no-empty-object-values.d.ts +23 -0
- package/dist/core/validators/object/no-empty-object-values.js +44 -0
- package/dist/core/validators/object/no-null-values.d.ts +23 -0
- package/dist/core/validators/object/no-null-values.js +44 -0
- package/dist/core/validators/object/no-undefined-values.d.ts +23 -0
- package/dist/core/validators/object/no-undefined-values.js +44 -0
- package/dist/core/validators/object/non-empty-object.d.ts +21 -0
- package/dist/core/validators/object/non-empty-object.js +40 -0
- package/dist/core/validators/object/only-keys.d.ts +23 -0
- package/dist/core/validators/object/only-keys.js +43 -0
- package/dist/core/validators/object/plain-object.d.ts +22 -0
- package/dist/core/validators/object/plain-object.js +35 -0
- package/dist/core/validators/string/alpha-num.d.ts +23 -0
- package/dist/core/validators/string/alpha-num.js +50 -0
- package/dist/core/validators/string/alpha.d.ts +24 -0
- package/dist/core/validators/string/alpha.js +51 -0
- package/dist/core/validators/string/chars-equal.d.ts +23 -0
- package/dist/core/validators/string/chars-equal.js +49 -0
- package/dist/core/validators/string/ends-with.d.ts +23 -0
- package/dist/core/validators/string/ends-with.js +50 -0
- package/dist/core/validators/string/is-ascii.d.ts +24 -0
- package/dist/core/validators/string/is-ascii.js +53 -0
- package/dist/core/validators/string/is-printable.d.ts +25 -0
- package/dist/core/validators/string/is-printable.js +53 -0
- package/dist/core/validators/string/matches.d.ts +23 -0
- package/dist/core/validators/string/matches.js +50 -0
- package/dist/core/validators/string/max-length.d.ts +24 -0
- package/dist/core/validators/string/max-length.js +50 -0
- package/dist/core/validators/string/min-length.d.ts +24 -0
- package/dist/core/validators/string/min-length.js +50 -0
- package/dist/core/validators/string/no-lead-space.d.ts +23 -0
- package/dist/core/validators/string/no-lead-space.js +50 -0
- package/dist/core/validators/string/no-repeat-space.d.ts +25 -0
- package/dist/core/validators/string/no-repeat-space.js +52 -0
- package/dist/core/validators/string/no-space.d.ts +24 -0
- package/dist/core/validators/string/no-space.js +51 -0
- package/dist/core/validators/string/no-trail-space.d.ts +23 -0
- package/dist/core/validators/string/no-trail-space.js +50 -0
- package/dist/core/validators/string/non-empty.d.ts +22 -0
- package/dist/core/validators/string/non-empty.js +48 -0
- package/dist/core/validators/string/not-one-of.d.ts +24 -0
- package/dist/core/validators/string/not-one-of.js +51 -0
- package/dist/core/validators/string/num-string.d.ts +23 -0
- package/dist/core/validators/string/num-string.js +50 -0
- package/dist/core/validators/string/one-of.d.ts +23 -0
- package/dist/core/validators/string/one-of.js +50 -0
- package/dist/core/validators/string/starts-with.d.ts +23 -0
- package/dist/core/validators/string/starts-with.js +50 -0
- package/dist/core/validators/string/string.d.ts +21 -0
- package/dist/core/validators/string/string.js +39 -0
- package/dist/core/validators/string/trimmed.d.ts +24 -0
- package/dist/core/validators/string/trimmed.js +51 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.js +26 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +12 -0
- package/package.json +2 -2
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Pipeline | Pipeline
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Orchestrates all pipeline stages into a unified execution
|
|
7
|
+
* lifecycle.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { attachFluentParsers, attachFluentValidators, createEvent, defaultPolicy, policyDecision, resolvePolicy, } from '../common';
|
|
12
|
+
import { rootPath } from '../field-path';
|
|
13
|
+
import { deepClone, detectStructuralType, normalizationRunner, scanRunner, selectNormalizationRules, selectScanRules, validationRunner, } from '../pipeline';
|
|
14
|
+
import { janeRegistry } from '../fluent-registry';
|
|
15
|
+
import { diff, explain, replay, telemetry } from '../analysis';
|
|
16
|
+
import { parseRunner } from '.';
|
|
17
|
+
import { isFluentValidator, isValidationFactory } from './validate';
|
|
18
|
+
import { isFluentParser, isParseFactory } from '../pipeline';
|
|
19
|
+
import { normalizePolicy } from '../common/policy';
|
|
20
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
21
|
+
|* Pipeline Runner *|
|
|
22
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
23
|
+
/**
|
|
24
|
+
* Runs the configured pipeline through all enabled stages and assembles the
|
|
25
|
+
* complete result. Coordinates scan, normalize, parse, validate, analysis,
|
|
26
|
+
* and policy decision into a single execution flow.
|
|
27
|
+
*/
|
|
28
|
+
export async function pipelineRunner(input) {
|
|
29
|
+
const startedAt = new Date();
|
|
30
|
+
const { raw, path: inputPath, policy, scanRules, parseRules, validationRules, inputName, userMessageOverride, telemetrySink, } = input;
|
|
31
|
+
const path = inputPath ?? rootPath();
|
|
32
|
+
const allEvents = [];
|
|
33
|
+
let scanEvents = [];
|
|
34
|
+
let normalizeEvents = [];
|
|
35
|
+
let parseEvents = [];
|
|
36
|
+
let validateEvents = [];
|
|
37
|
+
// ----------------------------------------
|
|
38
|
+
// 1. Scan (optional, fail-fast on fatal)
|
|
39
|
+
// ----------------------------------------
|
|
40
|
+
let safe = deepClone(raw);
|
|
41
|
+
if (policy.scan) {
|
|
42
|
+
const scanResult = await scanRunner({
|
|
43
|
+
raw,
|
|
44
|
+
path,
|
|
45
|
+
rules: scanRules,
|
|
46
|
+
policy,
|
|
47
|
+
});
|
|
48
|
+
safe = scanResult.safe;
|
|
49
|
+
scanEvents = scanResult.events;
|
|
50
|
+
allEvents.push(...scanResult.events);
|
|
51
|
+
const fatalEvent = scanResult.events.find((e) => e.kind === 'fatal');
|
|
52
|
+
if (fatalEvent) {
|
|
53
|
+
const finishedAt = new Date();
|
|
54
|
+
const metadata = {
|
|
55
|
+
runId: crypto.randomUUID(),
|
|
56
|
+
startedAt: startedAt.toISOString(),
|
|
57
|
+
finishedAt: finishedAt.toISOString(),
|
|
58
|
+
boundaryName: policy.boundaryName,
|
|
59
|
+
pipelineName: policy.pipelineName,
|
|
60
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
61
|
+
inputName,
|
|
62
|
+
analysis: {
|
|
63
|
+
diff: policy.analysis?.diff,
|
|
64
|
+
explain: policy.analysis?.explain,
|
|
65
|
+
replay: policy.analysis?.replay,
|
|
66
|
+
telemetry: policy.analysis?.telemetry,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const policyResult = policyDecision({
|
|
70
|
+
policy,
|
|
71
|
+
raw,
|
|
72
|
+
safe,
|
|
73
|
+
normalized: undefined,
|
|
74
|
+
final: undefined,
|
|
75
|
+
path,
|
|
76
|
+
rawType: detectStructuralType(raw),
|
|
77
|
+
safeType: detectStructuralType(safe),
|
|
78
|
+
normalizedType: detectStructuralType(undefined),
|
|
79
|
+
finalType: detectStructuralType(undefined),
|
|
80
|
+
events: allEvents,
|
|
81
|
+
issues: scanEvents,
|
|
82
|
+
scanEvents,
|
|
83
|
+
normalizeEvents: [],
|
|
84
|
+
parseEvents: [],
|
|
85
|
+
validateEvents: [],
|
|
86
|
+
diff: undefined,
|
|
87
|
+
explain: undefined,
|
|
88
|
+
replay: undefined,
|
|
89
|
+
}, metadata);
|
|
90
|
+
if (policy.analysis?.telemetry && telemetrySink) {
|
|
91
|
+
const tel = telemetry({
|
|
92
|
+
boundaryName: policy.boundaryName ?? 'unknown-boundary',
|
|
93
|
+
pipelineName: policy.pipelineName ?? 'unknown-pipeline',
|
|
94
|
+
result: policyResult,
|
|
95
|
+
});
|
|
96
|
+
telemetrySink(tel.records);
|
|
97
|
+
}
|
|
98
|
+
return policyResult;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
safe = deepClone(raw);
|
|
103
|
+
const event = createEvent('scan', 'info', 'scan.is.disabled', path, 'Scan stage was skipped because policy.scan is false.', undefined, { scan: false, mode: policy.mode });
|
|
104
|
+
scanEvents = [event];
|
|
105
|
+
allEvents.push(event);
|
|
106
|
+
}
|
|
107
|
+
// ----------------------------------------
|
|
108
|
+
// 2. Normalize (mode-aware)
|
|
109
|
+
// ----------------------------------------
|
|
110
|
+
let normalized = safe;
|
|
111
|
+
let finalValue = safe;
|
|
112
|
+
if (policy.mode !== 'strict') {
|
|
113
|
+
const normalizationRules = selectNormalizationRules(safe);
|
|
114
|
+
const normalizationResult = await normalizationRunner({
|
|
115
|
+
safe,
|
|
116
|
+
path,
|
|
117
|
+
rules: normalizationRules,
|
|
118
|
+
mode: policy.mode,
|
|
119
|
+
});
|
|
120
|
+
normalized = normalizationResult.normalized;
|
|
121
|
+
finalValue = normalizationResult.normalized;
|
|
122
|
+
normalizeEvents = normalizationResult.events;
|
|
123
|
+
allEvents.push(...normalizationResult.events);
|
|
124
|
+
}
|
|
125
|
+
// ----------------------------------------
|
|
126
|
+
// 3. Parse (explicit rules only)
|
|
127
|
+
// ----------------------------------------
|
|
128
|
+
if (parseRules.length > 0) {
|
|
129
|
+
if (policy.mode === 'strict') {
|
|
130
|
+
const warn = createEvent('parse', 'warn', 'policy.is.strict', path, 'Parse stage was skipped in strict mode.', undefined, { mode: policy.mode, rules: parseRules.length });
|
|
131
|
+
parseEvents = [warn];
|
|
132
|
+
allEvents.push(warn);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const parseResult = await parseRunner({
|
|
136
|
+
value: normalized,
|
|
137
|
+
path,
|
|
138
|
+
rules: parseRules,
|
|
139
|
+
});
|
|
140
|
+
finalValue = parseResult.parsed;
|
|
141
|
+
parseEvents = parseResult.events;
|
|
142
|
+
allEvents.push(...parseResult.events);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// ----------------------------------------
|
|
146
|
+
// 4. Diff (lazy)
|
|
147
|
+
// ----------------------------------------
|
|
148
|
+
const diffResult = policy.analysis?.diff
|
|
149
|
+
? await diff(safe, normalized)
|
|
150
|
+
: undefined;
|
|
151
|
+
// ----------------------------------------
|
|
152
|
+
// 5. Validate
|
|
153
|
+
// ----------------------------------------
|
|
154
|
+
const validateResult = await validationRunner({
|
|
155
|
+
value: finalValue,
|
|
156
|
+
path,
|
|
157
|
+
rules: validationRules,
|
|
158
|
+
});
|
|
159
|
+
validateEvents = validateResult.events;
|
|
160
|
+
if (userMessageOverride) {
|
|
161
|
+
validateEvents = validateEvents.map((event) => ({
|
|
162
|
+
...event,
|
|
163
|
+
userMessage: userMessageOverride,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
allEvents.push(...validateEvents);
|
|
167
|
+
if (inputName) {
|
|
168
|
+
for (let i = 0; i < allEvents.length; i++) {
|
|
169
|
+
allEvents[i] = {
|
|
170
|
+
...allEvents[i],
|
|
171
|
+
inputName,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ----------------------------------------
|
|
176
|
+
// 6. Explain (lazy)
|
|
177
|
+
// ----------------------------------------
|
|
178
|
+
const explanation = policy.analysis?.explain
|
|
179
|
+
? explain({
|
|
180
|
+
scanEvents,
|
|
181
|
+
normalizationEvents: normalizeEvents,
|
|
182
|
+
parseEvents,
|
|
183
|
+
validationEvents: validateEvents,
|
|
184
|
+
diff: diffResult,
|
|
185
|
+
})
|
|
186
|
+
: undefined;
|
|
187
|
+
// ----------------------------------------
|
|
188
|
+
// 7. Replay (lazy)
|
|
189
|
+
// ----------------------------------------
|
|
190
|
+
const replayResult = policy.analysis?.replay
|
|
191
|
+
? replay({
|
|
192
|
+
before: safe,
|
|
193
|
+
diff: diffResult?.entries ?? [],
|
|
194
|
+
})
|
|
195
|
+
: undefined;
|
|
196
|
+
// ----------------------------------------
|
|
197
|
+
// 8. Decide (policy reducer)
|
|
198
|
+
// ----------------------------------------
|
|
199
|
+
const finishedAt = new Date();
|
|
200
|
+
const metadata = {
|
|
201
|
+
runId: crypto.randomUUID(),
|
|
202
|
+
startedAt: startedAt.toISOString(),
|
|
203
|
+
finishedAt: finishedAt.toISOString(),
|
|
204
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
205
|
+
inputName,
|
|
206
|
+
};
|
|
207
|
+
const policyResult = policyDecision({
|
|
208
|
+
policy,
|
|
209
|
+
raw,
|
|
210
|
+
safe,
|
|
211
|
+
normalized,
|
|
212
|
+
final: finalValue,
|
|
213
|
+
path,
|
|
214
|
+
rawType: detectStructuralType(raw),
|
|
215
|
+
safeType: detectStructuralType(safe),
|
|
216
|
+
normalizedType: detectStructuralType(normalized),
|
|
217
|
+
finalType: detectStructuralType(finalValue),
|
|
218
|
+
events: allEvents,
|
|
219
|
+
issues: [],
|
|
220
|
+
scanEvents,
|
|
221
|
+
normalizeEvents,
|
|
222
|
+
parseEvents,
|
|
223
|
+
validateEvents,
|
|
224
|
+
diff: diffResult,
|
|
225
|
+
explain: explanation,
|
|
226
|
+
replay: replayResult,
|
|
227
|
+
}, metadata);
|
|
228
|
+
const pipelineResult = {
|
|
229
|
+
decision: policyResult.decision,
|
|
230
|
+
policy,
|
|
231
|
+
raw,
|
|
232
|
+
safe,
|
|
233
|
+
normalized,
|
|
234
|
+
final: finalValue,
|
|
235
|
+
path,
|
|
236
|
+
rawType: detectStructuralType(raw),
|
|
237
|
+
safeType: detectStructuralType(safe),
|
|
238
|
+
normalizedType: detectStructuralType(normalized),
|
|
239
|
+
finalType: detectStructuralType(finalValue),
|
|
240
|
+
events: allEvents,
|
|
241
|
+
issues: policyResult.issues,
|
|
242
|
+
scanEvents,
|
|
243
|
+
normalizeEvents,
|
|
244
|
+
parseEvents,
|
|
245
|
+
validateEvents,
|
|
246
|
+
diff: diffResult,
|
|
247
|
+
explain: explanation,
|
|
248
|
+
replay: replayResult,
|
|
249
|
+
metadata,
|
|
250
|
+
};
|
|
251
|
+
// ----------------------------------------
|
|
252
|
+
// 9. Telemetry (after result is complete)
|
|
253
|
+
// ----------------------------------------
|
|
254
|
+
if (policy.analysis?.telemetry && telemetrySink) {
|
|
255
|
+
const tel = telemetry({
|
|
256
|
+
boundaryName: policy.boundaryName ?? 'unknown-boundary',
|
|
257
|
+
pipelineName: policy.pipelineName ?? 'unknown-pipeline',
|
|
258
|
+
result: pipelineResult,
|
|
259
|
+
});
|
|
260
|
+
telemetrySink(tel.records);
|
|
261
|
+
}
|
|
262
|
+
return pipelineResult;
|
|
263
|
+
}
|
|
264
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
265
|
+
|* Create Pipeline *|
|
|
266
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
267
|
+
/**
|
|
268
|
+
* Creates a new pipeline builder rooted at the given raw value and path.
|
|
269
|
+
* Establishes the initial rule sets, policy state, and override surface,
|
|
270
|
+
* returning a fluent interface for assembling and running a complete pipeline.
|
|
271
|
+
*/
|
|
272
|
+
export function createPipeline(raw, path = rootPath(), scanRules = [], parseRules = [], validationRules = [], policy, overrides = {}) {
|
|
273
|
+
const base = {
|
|
274
|
+
raw,
|
|
275
|
+
path,
|
|
276
|
+
scanRules,
|
|
277
|
+
parseRules,
|
|
278
|
+
validationRules,
|
|
279
|
+
policy,
|
|
280
|
+
overrides,
|
|
281
|
+
async run() {
|
|
282
|
+
const effectivePolicy = resolvePolicy(defaultPolicy, this.policy, this.overrides);
|
|
283
|
+
return pipelineRunner({
|
|
284
|
+
raw: this.raw,
|
|
285
|
+
path: this.path,
|
|
286
|
+
policy: effectivePolicy,
|
|
287
|
+
scanRules: [...this.scanRules],
|
|
288
|
+
parseRules: [...this.parseRules],
|
|
289
|
+
validationRules: [...this.validationRules],
|
|
290
|
+
inputName: this.overrides.inputName,
|
|
291
|
+
userMessageOverride: this.overrides.userMessageOverride,
|
|
292
|
+
telemetrySink: this.overrides.telemetrySink,
|
|
293
|
+
});
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
const core = {
|
|
297
|
+
...base,
|
|
298
|
+
scan() {
|
|
299
|
+
return createPipeline(this.raw, this.path, selectScanRules(this.raw), this.parseRules, this.validationRules, this.policy, { ...this.overrides, scan: true });
|
|
300
|
+
},
|
|
301
|
+
parse(ruleOrName, ...args) {
|
|
302
|
+
let rule;
|
|
303
|
+
if (typeof ruleOrName === 'string') {
|
|
304
|
+
const entry = janeRegistry.parsers[ruleOrName];
|
|
305
|
+
if (isParseFactory(entry)) {
|
|
306
|
+
// entry is the factory — NOT ruleOrName
|
|
307
|
+
const factory = entry;
|
|
308
|
+
rule = factory(...args);
|
|
309
|
+
}
|
|
310
|
+
else if (isFluentParser(entry)) {
|
|
311
|
+
rule = entry;
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
throw new Error('Invalid parser entry');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
rule = ruleOrName;
|
|
319
|
+
}
|
|
320
|
+
return createPipeline(this.raw, this.path, this.scanRules, [...this.parseRules, rule], this.validationRules, this.policy, this.overrides);
|
|
321
|
+
},
|
|
322
|
+
validate(ruleOrName, ...args) {
|
|
323
|
+
let rule;
|
|
324
|
+
if (typeof ruleOrName === 'string') {
|
|
325
|
+
const entry = janeRegistry.validators[ruleOrName];
|
|
326
|
+
if (isValidationFactory(entry)) {
|
|
327
|
+
const factory = entry;
|
|
328
|
+
rule = factory(...args);
|
|
329
|
+
}
|
|
330
|
+
else if (isFluentValidator(entry)) {
|
|
331
|
+
rule = entry;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
throw new Error('Invalid validator entry');
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
rule = ruleOrName;
|
|
339
|
+
}
|
|
340
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, [...this.validationRules, rule], this.policy, this.overrides);
|
|
341
|
+
},
|
|
342
|
+
named(name) {
|
|
343
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, {
|
|
344
|
+
...this.overrides,
|
|
345
|
+
inputName: name,
|
|
346
|
+
});
|
|
347
|
+
},
|
|
348
|
+
userMessage(message) {
|
|
349
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, {
|
|
350
|
+
...this.overrides,
|
|
351
|
+
userMessageOverride: message,
|
|
352
|
+
});
|
|
353
|
+
},
|
|
354
|
+
strict() {
|
|
355
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, { ...this.overrides, mode: 'strict' });
|
|
356
|
+
},
|
|
357
|
+
moderate() {
|
|
358
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, { ...this.overrides, mode: 'moderate' });
|
|
359
|
+
},
|
|
360
|
+
lax() {
|
|
361
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, { ...this.overrides, mode: 'lax' });
|
|
362
|
+
},
|
|
363
|
+
withDiff() {
|
|
364
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, {
|
|
365
|
+
...this.overrides,
|
|
366
|
+
analysis: {
|
|
367
|
+
...(this.overrides.analysis ?? {}),
|
|
368
|
+
diff: true,
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
},
|
|
372
|
+
withExplain() {
|
|
373
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, {
|
|
374
|
+
...this.overrides,
|
|
375
|
+
analysis: {
|
|
376
|
+
...(this.overrides.analysis ?? {}),
|
|
377
|
+
explain: true,
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
},
|
|
381
|
+
withReplay() {
|
|
382
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, {
|
|
383
|
+
...this.overrides,
|
|
384
|
+
analysis: {
|
|
385
|
+
...(this.overrides.analysis ?? {}),
|
|
386
|
+
replay: true,
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
},
|
|
390
|
+
withTelemetry(sink) {
|
|
391
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, {
|
|
392
|
+
...this.overrides,
|
|
393
|
+
telemetrySink: sink,
|
|
394
|
+
analysis: {
|
|
395
|
+
...(this.overrides.analysis ?? {}),
|
|
396
|
+
telemetry: true,
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
},
|
|
400
|
+
withPolicy(input) {
|
|
401
|
+
const merged = normalizePolicy(this.policy ?? defaultPolicy, input);
|
|
402
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, merged, this.overrides);
|
|
403
|
+
},
|
|
404
|
+
allowBigint() {
|
|
405
|
+
return createPipeline(this.raw, this.path, this.scanRules, this.parseRules, this.validationRules, this.policy, {
|
|
406
|
+
...this.overrides,
|
|
407
|
+
exception: {
|
|
408
|
+
...this.overrides.exception,
|
|
409
|
+
bigint: true,
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
const builder = core;
|
|
415
|
+
attachFluentValidators(builder);
|
|
416
|
+
attachFluentParsers(builder);
|
|
417
|
+
return builder;
|
|
418
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Pipeline | Scan
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Inspects the contained value and emits structural
|
|
7
|
+
* observations for later stages.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { EventCode, EventKind, FieldPath, JaneEvent, ScanRule, ScanRunner, StructuralType } from '../shapes';
|
|
12
|
+
/**
|
|
13
|
+
* Classifies a raw value into one of Jane’s structural types.
|
|
14
|
+
*
|
|
15
|
+
* Used by the scanner to select appropriate rules without relying on
|
|
16
|
+
* user‑defined schemas or runtime shape assumptions.
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectStructuralType(input: unknown): StructuralType;
|
|
19
|
+
/**
|
|
20
|
+
* Computes the maximum nesting depth of a JSON‑like structure.
|
|
21
|
+
*
|
|
22
|
+
* Traverses objects recursively and returns the deepest level encountered,
|
|
23
|
+
* ignoring non‑object values and null.
|
|
24
|
+
*/
|
|
25
|
+
export declare function measureDepth(value: unknown, current?: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a scan‑stage event.
|
|
28
|
+
*
|
|
29
|
+
* Wraps createEvent with the 'scan' stage tag, producing structured
|
|
30
|
+
* observations emitted during the scan pipeline phase.
|
|
31
|
+
*/
|
|
32
|
+
export declare const scanEvent: (kind: EventKind, code: EventCode, path: FieldPath, message: string, userMessage?: string, meta?: Record<string, unknown>) => JaneEvent;
|
|
33
|
+
/**
|
|
34
|
+
* Executes the scan stage for a single value.
|
|
35
|
+
*
|
|
36
|
+
* Produces a safe contained value, applies all scan rules, collects
|
|
37
|
+
* emitted events, and performs a structural walk to ensure full coverage.
|
|
38
|
+
*/
|
|
39
|
+
export declare const scanRunner: ScanRunner;
|
|
40
|
+
/**
|
|
41
|
+
* Selects scan rules based on the structural type of the raw value.
|
|
42
|
+
*
|
|
43
|
+
* Returns the union of universal rules and the rules specific to the
|
|
44
|
+
* detected type, ensuring consistent and predictable scan behavior.
|
|
45
|
+
*/
|
|
46
|
+
export declare function selectScanRules(raw: unknown): readonly ScanRule[];
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Pipeline | Scan
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Inspects the contained value and emits structural
|
|
7
|
+
* observations for later stages.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { createEvent } from '../common';
|
|
12
|
+
import { rootPath, walk } from '../field-path';
|
|
13
|
+
import { scanRuleRegistry } from '../scanners';
|
|
14
|
+
import { containValue, defaultContainmentOptions } from '.';
|
|
15
|
+
import { makeFieldPath } from '../field-path/construct';
|
|
16
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
17
|
+
|* Detect Structural Type *|
|
|
18
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
19
|
+
/**
|
|
20
|
+
* Classifies a raw value into one of Jane’s structural types.
|
|
21
|
+
*
|
|
22
|
+
* Used by the scanner to select appropriate rules without relying on
|
|
23
|
+
* user‑defined schemas or runtime shape assumptions.
|
|
24
|
+
*/
|
|
25
|
+
export function detectStructuralType(input) {
|
|
26
|
+
if (typeof input === 'string')
|
|
27
|
+
return 'string';
|
|
28
|
+
if (typeof input === 'number')
|
|
29
|
+
return 'number';
|
|
30
|
+
if (typeof input === 'boolean')
|
|
31
|
+
return 'boolean';
|
|
32
|
+
if (typeof input === 'bigint')
|
|
33
|
+
return 'bigint';
|
|
34
|
+
if (input === null)
|
|
35
|
+
return 'unknown';
|
|
36
|
+
if (Array.isArray(input))
|
|
37
|
+
return 'array';
|
|
38
|
+
if (input instanceof Date)
|
|
39
|
+
return 'date';
|
|
40
|
+
if (typeof input === 'object')
|
|
41
|
+
return 'object';
|
|
42
|
+
return 'unknown';
|
|
43
|
+
}
|
|
44
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
45
|
+
|* Measure Depth *|
|
|
46
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
47
|
+
/**
|
|
48
|
+
* Computes the maximum nesting depth of a JSON‑like structure.
|
|
49
|
+
*
|
|
50
|
+
* Traverses objects recursively and returns the deepest level encountered,
|
|
51
|
+
* ignoring non‑object values and null.
|
|
52
|
+
*/
|
|
53
|
+
export function measureDepth(value, current = 0) {
|
|
54
|
+
if (typeof value !== 'object' || value === null)
|
|
55
|
+
return current;
|
|
56
|
+
let max = current;
|
|
57
|
+
for (const key of Object.keys(value)) {
|
|
58
|
+
const child = value[key];
|
|
59
|
+
const depth = measureDepth(child, current + 1);
|
|
60
|
+
if (depth > max)
|
|
61
|
+
max = depth;
|
|
62
|
+
}
|
|
63
|
+
return max;
|
|
64
|
+
}
|
|
65
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
66
|
+
|* Scan Event *|
|
|
67
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
68
|
+
/**
|
|
69
|
+
* Creates a scan‑stage event.
|
|
70
|
+
*
|
|
71
|
+
* Wraps createEvent with the 'scan' stage tag, producing structured
|
|
72
|
+
* observations emitted during the scan pipeline phase.
|
|
73
|
+
*/
|
|
74
|
+
export const scanEvent = (kind, code, path, message, userMessage, meta) => createEvent('scan', kind, code, path, message, userMessage, meta);
|
|
75
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
76
|
+
|* Scan Runner *|
|
|
77
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
78
|
+
/**
|
|
79
|
+
* Executes the scan stage for a single value.
|
|
80
|
+
*
|
|
81
|
+
* Produces a safe contained value, applies all scan rules, collects
|
|
82
|
+
* emitted events, and performs a structural walk to ensure full coverage.
|
|
83
|
+
*/
|
|
84
|
+
export const scanRunner = async (input) => {
|
|
85
|
+
const { raw, path: inputPath, rules, policy } = input;
|
|
86
|
+
const path = inputPath ? makeFieldPath([...inputPath.segments]) : rootPath();
|
|
87
|
+
const events = [];
|
|
88
|
+
const safe = containValue(raw, path, defaultContainmentOptions, policy);
|
|
89
|
+
for (const rule of rules) {
|
|
90
|
+
try {
|
|
91
|
+
const emitted = await rule(raw, path);
|
|
92
|
+
if (emitted && emitted.length > 0) {
|
|
93
|
+
events.push(...emitted);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
events.push(createEvent('scan', 'fatal', 'error.while.scanning', path, String(err)));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
await walk(raw, path, async () => { });
|
|
101
|
+
return { events, safe: safe };
|
|
102
|
+
};
|
|
103
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
104
|
+
|* Select Scan Rules *|
|
|
105
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
106
|
+
/**
|
|
107
|
+
* Selects scan rules based on the structural type of the raw value.
|
|
108
|
+
*
|
|
109
|
+
* Returns the union of universal rules and the rules specific to the
|
|
110
|
+
* detected type, ensuring consistent and predictable scan behavior.
|
|
111
|
+
*/
|
|
112
|
+
export function selectScanRules(raw) {
|
|
113
|
+
const type = detectStructuralType(raw);
|
|
114
|
+
return [...scanRuleRegistry.all, ...scanRuleRegistry[type]];
|
|
115
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Pipeline | Validate
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Evaluates the normalized value and emits rule‑driven
|
|
7
|
+
* correctness events.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { EventCode, EventKind, FieldPath, JaneEvent, ValidatorFactory, ValidationStageContext, ValidationStageOutput, ValidatorFluentRule, ValidationRule } from '../shapes';
|
|
12
|
+
/**
|
|
13
|
+
* Determines whether a fluent validator entry is a factory.
|
|
14
|
+
*
|
|
15
|
+
* Factories accept arbitrary parameters and return a ValidationRule,
|
|
16
|
+
* distinguishing them from fixed‑signature fluent validators.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isValidationFactory(fn: ValidatorFluentRule): fn is ValidatorFactory;
|
|
19
|
+
/**
|
|
20
|
+
* Determines whether a fluent validator entry is a direct validation rule.
|
|
21
|
+
*
|
|
22
|
+
* Fluent validators always expose a two‑argument signature—value and path—
|
|
23
|
+
* making them distinguishable from parameterized factories.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isFluentValidator(fn: ValidatorFluentRule): fn is ValidationRule;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a validation‑stage event.
|
|
28
|
+
*
|
|
29
|
+
* Wraps createEvent with the 'validate' phase tag, producing correctness‑
|
|
30
|
+
* focused messages emitted during rule evaluation.
|
|
31
|
+
*/
|
|
32
|
+
export declare const validationEvent: (kind: EventKind, code: EventCode, path: FieldPath, message?: string, userMessage?: string, meta?: Record<string, unknown>) => JaneEvent;
|
|
33
|
+
/**
|
|
34
|
+
* Executes the validation stage.
|
|
35
|
+
*
|
|
36
|
+
* Applies each validation rule to the value, collects all emitted events,
|
|
37
|
+
* and records fatal errors when rules throw. Produces the complete set of
|
|
38
|
+
* correctness observations for the stage.
|
|
39
|
+
*/
|
|
40
|
+
export declare const validationRunner: (input: ValidationStageContext) => Promise<ValidationStageOutput>;
|