@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,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse Numeric String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses strict numeric strings into numbers, supporting
|
|
7
|
+
* optional decimals while rejecting ambiguous formats.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { parseEvent } from '../pipeline';
|
|
12
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
13
|
+
|* Implementation *|
|
|
14
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
15
|
+
/**
|
|
16
|
+
* Parses strict numeric strings into JavaScript numbers, supporting optional
|
|
17
|
+
* decimals while rejecting scientific notation and non‑numeric characters.
|
|
18
|
+
*/
|
|
19
|
+
export const parseNumericString = (value, path) => {
|
|
20
|
+
if (typeof value !== 'string')
|
|
21
|
+
return [];
|
|
22
|
+
if (!/^-?\d+(\.\d+)?$/.test(value))
|
|
23
|
+
return [];
|
|
24
|
+
const parsed = Number(value);
|
|
25
|
+
if (Number.isNaN(parsed))
|
|
26
|
+
return [];
|
|
27
|
+
const event = parseEvent('info', 'string.now.number', `String parsed into number ${parsed}.`, path, 'Converted text into a number.', { before: value, after: parsed });
|
|
28
|
+
return [{ path, nextValue: parsed, events: [event] }];
|
|
29
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse Object String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses JSON object strings into plain objects, rejecting
|
|
7
|
+
* arrays, null, and non‑object structures.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { ParseRule } from '../shapes';
|
|
12
|
+
/**
|
|
13
|
+
* Parses JSON object strings into plain objects, rejecting arrays, null, and
|
|
14
|
+
* any non‑object structures.
|
|
15
|
+
*/
|
|
16
|
+
export declare const parseObjectString: ParseRule<unknown>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse Object String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses JSON object strings into plain objects, rejecting
|
|
7
|
+
* arrays, null, and non‑object structures.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { parseEvent } from '../pipeline';
|
|
12
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
13
|
+
|* Implementation *|
|
|
14
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
15
|
+
/**
|
|
16
|
+
* Parses JSON object strings into plain objects, rejecting arrays, null, and
|
|
17
|
+
* any non‑object structures.
|
|
18
|
+
*/
|
|
19
|
+
export const parseObjectString = (value, path) => {
|
|
20
|
+
if (typeof value !== 'string')
|
|
21
|
+
return [];
|
|
22
|
+
const trimmed = value.trim();
|
|
23
|
+
if (!trimmed.startsWith('{') || !trimmed.endsWith('}'))
|
|
24
|
+
return [];
|
|
25
|
+
let parsed;
|
|
26
|
+
try {
|
|
27
|
+
parsed = JSON.parse(trimmed);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
33
|
+
return [];
|
|
34
|
+
const event = parseEvent('info', 'string.now.object', 'String parsed into JSON object.', path, 'Converted text into an object.', { before: value, after: parsed });
|
|
35
|
+
return [{ path, nextValue: parsed, events: [event] }];
|
|
36
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse Octal String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses octal string literals (`0o…`) into `bigint` values,
|
|
7
|
+
* enforcing strict base‑8 formatting.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { ParseRule } from '../shapes';
|
|
12
|
+
/**
|
|
13
|
+
* Parses octal string literals (`0o…`) into `bigint` values, validating format
|
|
14
|
+
* and rejecting malformed or non‑octal input.
|
|
15
|
+
*/
|
|
16
|
+
export declare const parseOctalString: ParseRule<unknown>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse Octal String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses octal string literals (`0o…`) into `bigint` values,
|
|
7
|
+
* enforcing strict base‑8 formatting.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { parseEvent } from '../pipeline';
|
|
12
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
13
|
+
|* Implementation *|
|
|
14
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
15
|
+
/**
|
|
16
|
+
* Parses octal string literals (`0o…`) into `bigint` values, validating format
|
|
17
|
+
* and rejecting malformed or non‑octal input.
|
|
18
|
+
*/
|
|
19
|
+
export const parseOctalString = (value, path) => {
|
|
20
|
+
if (typeof value !== 'string')
|
|
21
|
+
return [];
|
|
22
|
+
if (!/^0o[0-7]+$/.test(value))
|
|
23
|
+
return [];
|
|
24
|
+
let parsed;
|
|
25
|
+
try {
|
|
26
|
+
parsed = BigInt(value);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
const event = parseEvent('info', 'string.now.octal', `Octal string parsed into bigint ${parsed}.`, path, 'Converted octal text into a number.', { before: value, after: parsed });
|
|
32
|
+
return [{ path, nextValue: parsed, events: [event] }];
|
|
33
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse Scientific Notation String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses strict scientific‑notation strings into numbers,
|
|
7
|
+
* validating both mantissa and exponent format.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { ParseRule } from '../shapes';
|
|
12
|
+
/**
|
|
13
|
+
* Parses strict scientific‑notation strings into numbers, enforcing canonical
|
|
14
|
+
* formatting for both mantissa and exponent.
|
|
15
|
+
*/
|
|
16
|
+
export declare const parseScientificNotationString: ParseRule<unknown>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse Scientific Notation String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses strict scientific‑notation strings into numbers,
|
|
7
|
+
* validating both mantissa and exponent format.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { parseEvent } from '../pipeline';
|
|
12
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
13
|
+
|* Implementation *|
|
|
14
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
15
|
+
/**
|
|
16
|
+
* Parses strict scientific‑notation strings into numbers, enforcing canonical
|
|
17
|
+
* formatting for both mantissa and exponent.
|
|
18
|
+
*/
|
|
19
|
+
export const parseScientificNotationString = (value, path) => {
|
|
20
|
+
if (typeof value !== 'string')
|
|
21
|
+
return [];
|
|
22
|
+
// Strict scientific notation: digits, optional decimal, 'e' or 'E', signed exponent
|
|
23
|
+
if (!/^-?\d+(\.\d+)?[eE][+-]?\d+$/.test(value))
|
|
24
|
+
return [];
|
|
25
|
+
const parsed = Number(value);
|
|
26
|
+
if (Number.isNaN(parsed))
|
|
27
|
+
return [];
|
|
28
|
+
const event = parseEvent('info', 'string.now.scientific', `String parsed into number ${parsed} using scientific notation.`, path, 'Converted scientific notation into a number.', { before: value, after: parsed });
|
|
29
|
+
return [{ path, nextValue: parsed, events: [event] }];
|
|
30
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse URL String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses URL strings into normalized URL values, ensuring the
|
|
7
|
+
* text represents a valid, fully qualified URL.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { ParseRule } from '../shapes';
|
|
12
|
+
/**
|
|
13
|
+
* Parses URL strings into normalized URL values, ensuring the text represents
|
|
14
|
+
* a syntactically valid and fully qualified URL.
|
|
15
|
+
*/
|
|
16
|
+
export declare const parseUrlString: ParseRule<string>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Parsers | Parse URL String
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Parses URL strings into normalized URL values, ensuring the
|
|
7
|
+
* text represents a valid, fully qualified URL.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { parseEvent } from '../pipeline';
|
|
12
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
13
|
+
|* Implementation *|
|
|
14
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
15
|
+
/**
|
|
16
|
+
* Parses URL strings into normalized URL values, ensuring the text represents
|
|
17
|
+
* a syntactically valid and fully qualified URL.
|
|
18
|
+
*/
|
|
19
|
+
export const parseUrlString = (value, path) => {
|
|
20
|
+
if (typeof value !== 'string')
|
|
21
|
+
return [];
|
|
22
|
+
try {
|
|
23
|
+
const normalized = new URL(value).toString();
|
|
24
|
+
const event = parseEvent('info', 'string.now.url', `String parsed into URL (${normalized}).`, path, 'Converted text into a URL.', { before: value, after: normalized });
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
path,
|
|
28
|
+
nextValue: normalized,
|
|
29
|
+
events: [event],
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Pipeline | Boundary
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Aggregates field results and applies boundary‑level policy
|
|
7
|
+
* to produce a final decision.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { BoundaryContext, BoundaryDecision, BoundaryInput, BoundaryResult } from '../shapes';
|
|
12
|
+
import type { BoundaryRule } from '../shapes/boundary';
|
|
13
|
+
/**
|
|
14
|
+
* Holds all registered boundary‑level rules.
|
|
15
|
+
*
|
|
16
|
+
* Provides a central lookup for rule names used in boundary policies,
|
|
17
|
+
* allowing contributors to extend or customize boundary evaluation
|
|
18
|
+
* without modifying the core engine.
|
|
19
|
+
*/
|
|
20
|
+
export declare const boundaryRuleRegistry: Record<string, BoundaryRule>;
|
|
21
|
+
/**
|
|
22
|
+
* Executes boundary evaluation across all field results.
|
|
23
|
+
*
|
|
24
|
+
* Aggregates issues and events from each pipeline result, applies
|
|
25
|
+
* boundary‑level rules, shapes values and metadata according to policy,
|
|
26
|
+
* and produces the final boundary result used for acceptance decisions.
|
|
27
|
+
*/
|
|
28
|
+
export declare function boundaryRunner(input: BoundaryInput): Promise<BoundaryResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Applies boundary decision logic to the aggregated context.
|
|
31
|
+
*
|
|
32
|
+
* Shapes events and issues through ignore, override, escalate, and
|
|
33
|
+
* visibility rules, evaluates acceptance modes, and optionally invokes
|
|
34
|
+
* a reducer to refine or override the final decision.
|
|
35
|
+
*/
|
|
36
|
+
export declare function decideBoundary(context: BoundaryContext): Promise<BoundaryDecision>;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Pipeline | Boundary
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Aggregates field results and applies boundary‑level policy
|
|
7
|
+
* to produce a final decision.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import { applyEscalate, applyOverride, defaultPolicy, generateRunId, matchesWildcard, resolveLevel, } from '../common';
|
|
12
|
+
import { boundaryPolicyDefault } from '../common/policy';
|
|
13
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
14
|
+
|* Boundary Rule Registry *|
|
|
15
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
16
|
+
/**
|
|
17
|
+
* Holds all registered boundary‑level rules.
|
|
18
|
+
*
|
|
19
|
+
* Provides a central lookup for rule names used in boundary policies,
|
|
20
|
+
* allowing contributors to extend or customize boundary evaluation
|
|
21
|
+
* without modifying the core engine.
|
|
22
|
+
*/
|
|
23
|
+
export const boundaryRuleRegistry = {};
|
|
24
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
25
|
+
|* Boundary Runner *|
|
|
26
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
27
|
+
/**
|
|
28
|
+
* Executes boundary evaluation across all field results.
|
|
29
|
+
*
|
|
30
|
+
* Aggregates issues and events from each pipeline result, applies
|
|
31
|
+
* boundary‑level rules, shapes values and metadata according to policy,
|
|
32
|
+
* and produces the final boundary result used for acceptance decisions.
|
|
33
|
+
*/
|
|
34
|
+
export async function boundaryRunner(input) {
|
|
35
|
+
const startedAt = new Date();
|
|
36
|
+
const runId = generateRunId();
|
|
37
|
+
const { policy = defaultPolicy, fields } = input;
|
|
38
|
+
const boundary = policy.boundary ?? boundaryPolicyDefault;
|
|
39
|
+
const allIssues = [];
|
|
40
|
+
const allEvents = [];
|
|
41
|
+
const metadata = {};
|
|
42
|
+
const value = {};
|
|
43
|
+
for (const key of Object.keys(fields)) {
|
|
44
|
+
const result = fields[key];
|
|
45
|
+
metadata[key] = {
|
|
46
|
+
raw: result.raw,
|
|
47
|
+
safe: result.safe,
|
|
48
|
+
final: result.final,
|
|
49
|
+
path: result.path,
|
|
50
|
+
rawType: result.rawType,
|
|
51
|
+
finalType: result.finalType,
|
|
52
|
+
startedAt: result.metadata.startedAt,
|
|
53
|
+
finishedAt: result.metadata.finishedAt,
|
|
54
|
+
durationMs: result.metadata.durationMs,
|
|
55
|
+
inputName: result.metadata.inputName,
|
|
56
|
+
};
|
|
57
|
+
if (result.decision?.code === 'accept') {
|
|
58
|
+
value[key] = result.final;
|
|
59
|
+
}
|
|
60
|
+
const events = result.events ?? [];
|
|
61
|
+
const issues = events.filter((e) => (e.kind === 'error' || e.kind === 'fatal') &&
|
|
62
|
+
typeof e.code === 'string' &&
|
|
63
|
+
e.code.trim().length > 0);
|
|
64
|
+
allIssues.push(...issues);
|
|
65
|
+
allEvents.push(...events);
|
|
66
|
+
}
|
|
67
|
+
if (boundary?.rules && boundary.rules.length > 0) {
|
|
68
|
+
for (const rule of boundary.rules) {
|
|
69
|
+
const ctx = {
|
|
70
|
+
policy,
|
|
71
|
+
fields,
|
|
72
|
+
events: allEvents,
|
|
73
|
+
issues: allIssues,
|
|
74
|
+
values: value,
|
|
75
|
+
};
|
|
76
|
+
try {
|
|
77
|
+
const result = await rule(ctx);
|
|
78
|
+
if (!result)
|
|
79
|
+
continue;
|
|
80
|
+
if (result.events)
|
|
81
|
+
allEvents.push(...result.events);
|
|
82
|
+
if (result.issues)
|
|
83
|
+
allIssues.push(...result.issues);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
allEvents.push({
|
|
87
|
+
phase: 'decide',
|
|
88
|
+
kind: 'fatal',
|
|
89
|
+
code: 'boundary.fatal.error',
|
|
90
|
+
message: error?.message ?? 'Unknown error',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const finishedAt = new Date();
|
|
96
|
+
const decision = await decideBoundary({
|
|
97
|
+
policy,
|
|
98
|
+
fields,
|
|
99
|
+
issues: allIssues,
|
|
100
|
+
events: allEvents,
|
|
101
|
+
values: value,
|
|
102
|
+
});
|
|
103
|
+
let shapedValues = { ...value };
|
|
104
|
+
if (boundary?.values?.includeRejected) {
|
|
105
|
+
for (const key of Object.keys(fields)) {
|
|
106
|
+
const r = fields[key];
|
|
107
|
+
if (r.decision?.code !== 'accept') {
|
|
108
|
+
shapedValues[key] = r.final;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (boundary?.values?.includeUndefined) {
|
|
113
|
+
for (const key of Object.keys(fields)) {
|
|
114
|
+
if (!(key in shapedValues)) {
|
|
115
|
+
shapedValues[key] = undefined;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (boundary?.values?.transform) {
|
|
120
|
+
shapedValues = boundary.values.transform(shapedValues);
|
|
121
|
+
}
|
|
122
|
+
let shapedMetadata = {
|
|
123
|
+
runId,
|
|
124
|
+
startedAt: startedAt.toISOString(),
|
|
125
|
+
finishedAt: finishedAt.toISOString(),
|
|
126
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
127
|
+
fields: metadata,
|
|
128
|
+
boundaryName: policy.boundaryName,
|
|
129
|
+
pipelineName: policy.pipelineName,
|
|
130
|
+
analysis: {
|
|
131
|
+
diff: policy.analysis?.diff,
|
|
132
|
+
explain: policy.analysis?.explain,
|
|
133
|
+
replay: policy.analysis?.replay,
|
|
134
|
+
telemetry: policy.analysis?.telemetry,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
if (boundary?.metadata) {
|
|
138
|
+
const m = boundary.metadata;
|
|
139
|
+
if (m.includeFields === false) {
|
|
140
|
+
shapedMetadata = { ...shapedMetadata, fields: {} };
|
|
141
|
+
}
|
|
142
|
+
if (m.includeTimestamps === false) {
|
|
143
|
+
shapedMetadata = {
|
|
144
|
+
...shapedMetadata,
|
|
145
|
+
startedAt: undefined,
|
|
146
|
+
finishedAt: undefined,
|
|
147
|
+
durationMs: undefined,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (m.includeRunId === false) {
|
|
151
|
+
shapedMetadata = { ...shapedMetadata, runId: undefined };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
ok: decision.ok,
|
|
156
|
+
issues: decision.issues ?? (allIssues.length > 0 ? allIssues : undefined),
|
|
157
|
+
events: decision.events ?? (allEvents.length > 0 ? allEvents : undefined),
|
|
158
|
+
values: decision.values ?? shapedValues,
|
|
159
|
+
fields,
|
|
160
|
+
metadata: decision.metadata ?? shapedMetadata,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— *\
|
|
164
|
+
|* Decide Boundary *|
|
|
165
|
+
\* ——— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ————— * ——— */
|
|
166
|
+
/**
|
|
167
|
+
* Applies boundary decision logic to the aggregated context.
|
|
168
|
+
*
|
|
169
|
+
* Shapes events and issues through ignore, override, escalate, and
|
|
170
|
+
* visibility rules, evaluates acceptance modes, and optionally invokes
|
|
171
|
+
* a reducer to refine or override the final decision.
|
|
172
|
+
*/
|
|
173
|
+
export async function decideBoundary(context) {
|
|
174
|
+
const { policy, fields } = context;
|
|
175
|
+
const boundary = policy.boundary;
|
|
176
|
+
let shapedEvents = [...context.events];
|
|
177
|
+
if (boundary?.ignore) {
|
|
178
|
+
shapedEvents = shapedEvents.filter((ev) => !matchesWildcard(ev.code, boundary.ignore));
|
|
179
|
+
}
|
|
180
|
+
if (boundary?.override) {
|
|
181
|
+
shapedEvents = shapedEvents.map((ev) => {
|
|
182
|
+
const level = resolveLevel(ev.code, boundary.override);
|
|
183
|
+
return level === undefined ? ev : { ...ev, kind: applyOverride(ev.kind, level) };
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
if (boundary?.escalate) {
|
|
187
|
+
shapedEvents = shapedEvents.map((ev) => {
|
|
188
|
+
const level = resolveLevel(ev.code, boundary.escalate);
|
|
189
|
+
return level === undefined ? ev : { ...ev, kind: applyEscalate(ev.kind, level) };
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (boundary?.hideEvents) {
|
|
193
|
+
shapedEvents = shapedEvents.filter((ev) => !matchesWildcard(ev.code, boundary.hideEvents));
|
|
194
|
+
}
|
|
195
|
+
let shapedIssues = shapedEvents.filter((ev) => (ev.kind === 'error' || ev.kind === 'fatal') &&
|
|
196
|
+
typeof ev.code === 'string' &&
|
|
197
|
+
ev.code.trim().length > 0);
|
|
198
|
+
if (boundary?.hideIssues) {
|
|
199
|
+
shapedIssues = shapedIssues.filter((ev) => !matchesWildcard(ev.code, boundary.hideIssues));
|
|
200
|
+
}
|
|
201
|
+
const rejectPatterns = boundary?.reject ?? policy.decide?.reject ?? [];
|
|
202
|
+
const reviewPatterns = boundary?.review ?? policy.decide?.review ?? [];
|
|
203
|
+
let hasReject = false;
|
|
204
|
+
let hasReview = false;
|
|
205
|
+
for (const ev of shapedEvents) {
|
|
206
|
+
if (ev.kind === 'fatal') {
|
|
207
|
+
hasReject = true;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (matchesWildcard(ev.code, rejectPatterns)) {
|
|
211
|
+
hasReject = true;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (matchesWildcard(ev.code, reviewPatterns)) {
|
|
215
|
+
hasReview = true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const acceptMode = boundary?.accept ?? 'all';
|
|
219
|
+
let ok;
|
|
220
|
+
switch (acceptMode) {
|
|
221
|
+
case 'strict':
|
|
222
|
+
ok = !hasReject && !hasReview && shapedIssues.length === 0;
|
|
223
|
+
break;
|
|
224
|
+
case 'any':
|
|
225
|
+
ok = !hasReject && Object.values(fields).some((r) => r.decision?.code === 'accept');
|
|
226
|
+
break;
|
|
227
|
+
case 'partial':
|
|
228
|
+
ok = !hasReject;
|
|
229
|
+
break;
|
|
230
|
+
case 'all':
|
|
231
|
+
default:
|
|
232
|
+
ok =
|
|
233
|
+
!hasReject &&
|
|
234
|
+
shapedIssues.length === 0 &&
|
|
235
|
+
Object.values(fields).every((r) => r.decision?.code === 'accept');
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
const shapedContext = {
|
|
239
|
+
...context,
|
|
240
|
+
events: shapedEvents,
|
|
241
|
+
issues: shapedIssues,
|
|
242
|
+
};
|
|
243
|
+
if (boundary?.reducer) {
|
|
244
|
+
const result = await boundary.reducer(shapedContext);
|
|
245
|
+
if (result !== undefined) {
|
|
246
|
+
if ('ok' in result && typeof result.ok === 'boolean') {
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
ok,
|
|
251
|
+
...result,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return { ok };
|
|
256
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ----------------------------------------------------------------------------
|
|
3
|
+
* Pipeline | Contain
|
|
4
|
+
* ----------------------------------------------------------------------------
|
|
5
|
+
* @package @clementine-solutions/jane
|
|
6
|
+
* @description Enforces structural limits and produces a safe, cycle‑free
|
|
7
|
+
* representation of input.
|
|
8
|
+
* @see https://jane-io.com
|
|
9
|
+
* ----------------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
import type { ContainmentContext, ContainmentOptions, FieldPath, InternalJsonValue, Policy } from '../shapes';
|
|
12
|
+
/**
|
|
13
|
+
* Sentinel markers used when a value cannot be safely contained.
|
|
14
|
+
*
|
|
15
|
+
* These appear when encountering cycles, excessive depth or size, unsafe
|
|
16
|
+
* structures, or disallowed types such as functions, symbols, and proxies.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ContainmentSentinel: {
|
|
19
|
+
readonly Circular: "[Circular]";
|
|
20
|
+
readonly TooDeep: "[TooDeep]";
|
|
21
|
+
readonly TooLarge: "[TooLarge]";
|
|
22
|
+
readonly Proxy: "[Proxy]";
|
|
23
|
+
readonly Getter: "[Getter]";
|
|
24
|
+
readonly Function: "[Function]";
|
|
25
|
+
readonly Symbol: "[Symbol]";
|
|
26
|
+
readonly BigInt: "[BigInt]";
|
|
27
|
+
};
|
|
28
|
+
export type ContainmentSentinel = (typeof ContainmentSentinel)[keyof typeof ContainmentSentinel];
|
|
29
|
+
/**
|
|
30
|
+
* Contains an array by applying depth and length limits.
|
|
31
|
+
*
|
|
32
|
+
* Recursively contains each element, records the container for cycle
|
|
33
|
+
* detection, and appends a TooLarge sentinel when the array exceeds
|
|
34
|
+
* the configured maximum length.
|
|
35
|
+
*/
|
|
36
|
+
export declare function containArray(value: readonly unknown[], path: FieldPath, context: ContainmentContext, depth: number): unknown;
|
|
37
|
+
/**
|
|
38
|
+
* Represents a bigint value in a safe, JSON‑compatible form.
|
|
39
|
+
*
|
|
40
|
+
* Used only when bigint is explicitly allowed by policy; otherwise
|
|
41
|
+
* containment falls back to the BigInt sentinel.
|
|
42
|
+
*/
|
|
43
|
+
export declare function containBigInt(value: bigint): {
|
|
44
|
+
kind: "bigint";
|
|
45
|
+
asString: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Contains a plain object by enforcing key limits and safe property access.
|
|
49
|
+
*
|
|
50
|
+
* Skips prototype‑pollution vectors, replaces getters/setters with a
|
|
51
|
+
* Getter sentinel, and recursively contains each value. Adds a TooLarge
|
|
52
|
+
* sentinel entry when the object exceeds the configured key limit.
|
|
53
|
+
*/
|
|
54
|
+
export declare function containObject(value: Record<string, unknown>, path: FieldPath, ctx: ContainmentContext, depth: number): unknown;
|
|
55
|
+
/**
|
|
56
|
+
* Recursively contains any value into a safe, JSON‑like structure.
|
|
57
|
+
*
|
|
58
|
+
* Enforces depth limits, detects cycles, handles primitives directly,
|
|
59
|
+
* applies policy‑controlled exceptions (e.g., bigint), and replaces
|
|
60
|
+
* unsafe or non‑plain objects with appropriate sentinels.
|
|
61
|
+
*/
|
|
62
|
+
export declare function containRecursive(value: unknown, path: FieldPath, context: ContainmentContext, depth: number): unknown;
|
|
63
|
+
/**
|
|
64
|
+
* Entry point for containment.
|
|
65
|
+
*
|
|
66
|
+
* Creates a fresh containment context and produces a safe representation
|
|
67
|
+
* of the input value. Falls back to the Proxy sentinel if containment
|
|
68
|
+
* fails unexpectedly.
|
|
69
|
+
*/
|
|
70
|
+
export declare function containValue(value: unknown, path?: FieldPath, options?: ContainmentOptions, policy?: Policy): unknown;
|
|
71
|
+
/**
|
|
72
|
+
* Constructs a containment context with structural limits, policy,
|
|
73
|
+
* and a fresh cycle‑detection map.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createContainmentContext(options: ContainmentOptions, policy: Policy): ContainmentContext;
|
|
76
|
+
/**
|
|
77
|
+
* Produces a deep, acyclic clone of an internal JSON value.
|
|
78
|
+
*
|
|
79
|
+
* Preserves primitives, arrays, plain objects, and Date instances while
|
|
80
|
+
* tracking references to avoid infinite recursion. Used to safely copy
|
|
81
|
+
* containment output without re‑running containment.
|
|
82
|
+
*/
|
|
83
|
+
export declare function deepClone(input: InternalJsonValue, seen?: WeakMap<object, InternalJsonValue>): InternalJsonValue | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Default structural limits applied during containment.
|
|
86
|
+
*
|
|
87
|
+
* These bounds prevent excessive recursion and traversal by capping depth,
|
|
88
|
+
* array length, and object key count.
|
|
89
|
+
*/
|
|
90
|
+
export declare const defaultContainmentOptions: ContainmentOptions;
|
|
91
|
+
/**
|
|
92
|
+
* Determines whether a value is a containment sentinel.
|
|
93
|
+
*
|
|
94
|
+
* Sentinels represent structural hazards or disallowed types encountered
|
|
95
|
+
* during containment and are encoded as well‑known string markers.
|
|
96
|
+
*/
|
|
97
|
+
export declare function isSentinel(value: unknown): value is ContainmentSentinel;
|
|
98
|
+
/**
|
|
99
|
+
* Safely retrieves an object's own enumerable keys.
|
|
100
|
+
*
|
|
101
|
+
* Returns an empty array if key enumeration fails, protecting containment
|
|
102
|
+
* from objects with hostile or unusual prototypes.
|
|
103
|
+
*/
|
|
104
|
+
export declare function safeObjectKeys(value: Record<string, unknown>): string[];
|
|
105
|
+
/**
|
|
106
|
+
* Safely retrieves a property descriptor.
|
|
107
|
+
*
|
|
108
|
+
* Returns undefined if descriptor access throws, allowing containment to
|
|
109
|
+
* gracefully handle objects with unsafe or non‑standard behavior.
|
|
110
|
+
*/
|
|
111
|
+
export declare function safePropertyDescriptor(value: Record<string, unknown>, key: string): PropertyDescriptor | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Maps a containment sentinel to its corresponding event.
|
|
114
|
+
*
|
|
115
|
+
* Used to surface structural hazards—such as cycles, excessive depth,
|
|
116
|
+
* unsafe objects, or disallowed types—as typed events during scanning
|
|
117
|
+
* and policy evaluation.
|
|
118
|
+
*/
|
|
119
|
+
export declare function sentinelEvent(kind: ContainmentSentinel): {
|
|
120
|
+
code: string;
|
|
121
|
+
severity: string;
|
|
122
|
+
};
|