zod-compiler 1.23.1 → 1.23.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 +9 -6
- package/dist/cli/commands/check.d.ts +10 -7
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +125 -148
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/generate.d.ts +22 -19
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +102 -133
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/watch.d.ts +17 -15
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +126 -154
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli/emitter.d.ts +19 -16
- package/dist/cli/emitter.d.ts.map +1 -1
- package/dist/cli/emitter.js +55 -71
- package/dist/cli/emitter.js.map +1 -1
- package/dist/cli/errors.d.ts +4 -1
- package/dist/cli/errors.d.ts.map +1 -1
- package/dist/cli/errors.js +6 -2
- package/dist/cli/errors.js.map +1 -1
- package/dist/cli/index.d.ts +1 -3
- package/dist/cli/index.js +147 -160
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/logger.d.ts +18 -15
- package/dist/cli/logger.d.ts.map +1 -1
- package/dist/cli/logger.js +38 -37
- package/dist/cli/logger.js.map +1 -1
- package/dist/core/codegen/build-path.d.ts +7 -41
- package/dist/core/codegen/build-path.d.ts.map +1 -1
- package/dist/core/codegen/build-path.js +481 -570
- package/dist/core/codegen/build-path.js.map +1 -1
- package/dist/core/codegen/context.d.ts +256 -253
- package/dist/core/codegen/context.d.ts.map +1 -1
- package/dist/core/codegen/context.js +363 -437
- package/dist/core/codegen/context.js.map +1 -1
- package/dist/core/codegen/dedupe.d.ts +22 -56
- package/dist/core/codegen/dedupe.d.ts.map +1 -1
- package/dist/core/codegen/dedupe.js +150 -242
- package/dist/core/codegen/dedupe.js.map +1 -1
- package/dist/core/codegen/emit-issue.d.ts +44 -68
- package/dist/core/codegen/emit-issue.d.ts.map +1 -1
- package/dist/core/codegen/emit-issue.js +76 -108
- package/dist/core/codegen/emit-issue.js.map +1 -1
- package/dist/core/codegen/emit.d.ts +4 -1
- package/dist/core/codegen/emit.d.ts.map +1 -1
- package/dist/core/codegen/emit.js +16 -13
- package/dist/core/codegen/emit.js.map +1 -1
- package/dist/core/codegen/fast-path.d.ts +7 -12
- package/dist/core/codegen/fast-path.d.ts.map +1 -1
- package/dist/core/codegen/fast-path.js +116 -145
- package/dist/core/codegen/fast-path.js.map +1 -1
- package/dist/core/codegen/fast-size.d.ts +12 -26
- package/dist/core/codegen/fast-size.d.ts.map +1 -1
- package/dist/core/codegen/fast-size.js +169 -244
- package/dist/core/codegen/fast-size.js.map +1 -1
- package/dist/core/codegen/index.d.ts +25 -23
- package/dist/core/codegen/index.d.ts.map +1 -1
- package/dist/core/codegen/index.js +239 -405
- package/dist/core/codegen/index.js.map +1 -1
- package/dist/core/codegen/issue-decls.d.ts +15 -12
- package/dist/core/codegen/issue-decls.d.ts.map +1 -1
- package/dist/core/codegen/issue-decls.js +131 -162
- package/dist/core/codegen/issue-decls.js.map +1 -1
- package/dist/core/codegen/regex-unroll.d.ts +4 -1
- package/dist/core/codegen/regex-unroll.d.ts.map +1 -1
- package/dist/core/codegen/regex-unroll.js +173 -197
- package/dist/core/codegen/regex-unroll.js.map +1 -1
- package/dist/core/codegen/schemas/any.d.ts +7 -4
- package/dist/core/codegen/schemas/any.d.ts.map +1 -1
- package/dist/core/codegen/schemas/any.js +8 -4
- package/dist/core/codegen/schemas/any.js.map +1 -1
- package/dist/core/codegen/schemas/array.d.ts +8 -5
- package/dist/core/codegen/schemas/array.d.ts.map +1 -1
- package/dist/core/codegen/schemas/array.js +77 -95
- package/dist/core/codegen/schemas/array.js.map +1 -1
- package/dist/core/codegen/schemas/bigint.d.ts +7 -4
- package/dist/core/codegen/schemas/bigint.d.ts.map +1 -1
- package/dist/core/codegen/schemas/bigint.js +44 -56
- package/dist/core/codegen/schemas/bigint.js.map +1 -1
- package/dist/core/codegen/schemas/boolean.d.ts +7 -4
- package/dist/core/codegen/schemas/boolean.d.ts.map +1 -1
- package/dist/core/codegen/schemas/boolean.js +12 -11
- package/dist/core/codegen/schemas/boolean.js.map +1 -1
- package/dist/core/codegen/schemas/catch.d.ts +8 -5
- package/dist/core/codegen/schemas/catch.d.ts.map +1 -1
- package/dist/core/codegen/schemas/catch.js +23 -23
- package/dist/core/codegen/schemas/catch.js.map +1 -1
- package/dist/core/codegen/schemas/date.d.ts +7 -4
- package/dist/core/codegen/schemas/date.d.ts.map +1 -1
- package/dist/core/codegen/schemas/date.js +49 -68
- package/dist/core/codegen/schemas/date.js.map +1 -1
- package/dist/core/codegen/schemas/default.d.ts +9 -6
- package/dist/core/codegen/schemas/default.d.ts.map +1 -1
- package/dist/core/codegen/schemas/default.js +29 -27
- package/dist/core/codegen/schemas/default.js.map +1 -1
- package/dist/core/codegen/schemas/discriminated-union.d.ts +12 -10
- package/dist/core/codegen/schemas/discriminated-union.d.ts.map +1 -1
- package/dist/core/codegen/schemas/discriminated-union.js +153 -178
- package/dist/core/codegen/schemas/discriminated-union.js.map +1 -1
- package/dist/core/codegen/schemas/effect.d.ts +9 -6
- package/dist/core/codegen/schemas/effect.d.ts.map +1 -1
- package/dist/core/codegen/schemas/effect.js +54 -67
- package/dist/core/codegen/schemas/effect.js.map +1 -1
- package/dist/core/codegen/schemas/enum.d.ts +7 -4
- package/dist/core/codegen/schemas/enum.d.ts.map +1 -1
- package/dist/core/codegen/schemas/enum.js +15 -21
- package/dist/core/codegen/schemas/enum.js.map +1 -1
- package/dist/core/codegen/schemas/fallback.d.ts +6 -3
- package/dist/core/codegen/schemas/fallback.d.ts.map +1 -1
- package/dist/core/codegen/schemas/fallback.js +14 -13
- package/dist/core/codegen/schemas/fallback.js.map +1 -1
- package/dist/core/codegen/schemas/file.d.ts +7 -4
- package/dist/core/codegen/schemas/file.d.ts.map +1 -1
- package/dist/core/codegen/schemas/file.js +51 -57
- package/dist/core/codegen/schemas/file.js.map +1 -1
- package/dist/core/codegen/schemas/intersection.d.ts +8 -5
- package/dist/core/codegen/schemas/intersection.d.ts.map +1 -1
- package/dist/core/codegen/schemas/intersection.js +16 -13
- package/dist/core/codegen/schemas/intersection.js.map +1 -1
- package/dist/core/codegen/schemas/literal.d.ts +7 -4
- package/dist/core/codegen/schemas/literal.d.ts.map +1 -1
- package/dist/core/codegen/schemas/literal.js +20 -23
- package/dist/core/codegen/schemas/literal.js.map +1 -1
- package/dist/core/codegen/schemas/map.d.ts +8 -5
- package/dist/core/codegen/schemas/map.d.ts.map +1 -1
- package/dist/core/codegen/schemas/map.js +61 -67
- package/dist/core/codegen/schemas/map.js.map +1 -1
- package/dist/core/codegen/schemas/nan.d.ts +7 -4
- package/dist/core/codegen/schemas/nan.d.ts.map +1 -1
- package/dist/core/codegen/schemas/nan.js +8 -4
- package/dist/core/codegen/schemas/nan.js.map +1 -1
- package/dist/core/codegen/schemas/never.d.ts +7 -4
- package/dist/core/codegen/schemas/never.d.ts.map +1 -1
- package/dist/core/codegen/schemas/never.js +8 -4
- package/dist/core/codegen/schemas/never.js.map +1 -1
- package/dist/core/codegen/schemas/null.d.ts +7 -4
- package/dist/core/codegen/schemas/null.d.ts.map +1 -1
- package/dist/core/codegen/schemas/null.js +8 -4
- package/dist/core/codegen/schemas/null.js.map +1 -1
- package/dist/core/codegen/schemas/nullable.d.ts +8 -5
- package/dist/core/codegen/schemas/nullable.d.ts.map +1 -1
- package/dist/core/codegen/schemas/nullable.js +8 -5
- package/dist/core/codegen/schemas/nullable.js.map +1 -1
- package/dist/core/codegen/schemas/number.d.ts +7 -4
- package/dist/core/codegen/schemas/number.d.ts.map +1 -1
- package/dist/core/codegen/schemas/number.js +120 -176
- package/dist/core/codegen/schemas/number.js.map +1 -1
- package/dist/core/codegen/schemas/object.d.ts +8 -5
- package/dist/core/codegen/schemas/object.d.ts.map +1 -1
- package/dist/core/codegen/schemas/object.js +144 -231
- package/dist/core/codegen/schemas/object.js.map +1 -1
- package/dist/core/codegen/schemas/optional.d.ts +9 -6
- package/dist/core/codegen/schemas/optional.d.ts.map +1 -1
- package/dist/core/codegen/schemas/optional.js +23 -31
- package/dist/core/codegen/schemas/optional.js.map +1 -1
- package/dist/core/codegen/schemas/pipe.d.ts +8 -5
- package/dist/core/codegen/schemas/pipe.d.ts.map +1 -1
- package/dist/core/codegen/schemas/pipe.js +20 -27
- package/dist/core/codegen/schemas/pipe.js.map +1 -1
- package/dist/core/codegen/schemas/readonly.d.ts +8 -5
- package/dist/core/codegen/schemas/readonly.d.ts.map +1 -1
- package/dist/core/codegen/schemas/readonly.js +8 -5
- package/dist/core/codegen/schemas/readonly.js.map +1 -1
- package/dist/core/codegen/schemas/record.d.ts +8 -5
- package/dist/core/codegen/schemas/record.d.ts.map +1 -1
- package/dist/core/codegen/schemas/record.js +52 -65
- package/dist/core/codegen/schemas/record.js.map +1 -1
- package/dist/core/codegen/schemas/recursive-ref.d.ts +9 -6
- package/dist/core/codegen/schemas/recursive-ref.d.ts.map +1 -1
- package/dist/core/codegen/schemas/recursive-ref.js +44 -44
- package/dist/core/codegen/schemas/recursive-ref.js.map +1 -1
- package/dist/core/codegen/schemas/set.d.ts +8 -5
- package/dist/core/codegen/schemas/set.d.ts.map +1 -1
- package/dist/core/codegen/schemas/set.js +61 -73
- package/dist/core/codegen/schemas/set.js.map +1 -1
- package/dist/core/codegen/schemas/string-bool.d.ts +6 -3
- package/dist/core/codegen/schemas/string-bool.d.ts.map +1 -1
- package/dist/core/codegen/schemas/string-bool.js +22 -23
- package/dist/core/codegen/schemas/string-bool.js.map +1 -1
- package/dist/core/codegen/schemas/string.d.ts +8 -5
- package/dist/core/codegen/schemas/string.d.ts.map +1 -1
- package/dist/core/codegen/schemas/string.js +168 -207
- package/dist/core/codegen/schemas/string.js.map +1 -1
- package/dist/core/codegen/schemas/symbol.d.ts +7 -4
- package/dist/core/codegen/schemas/symbol.d.ts.map +1 -1
- package/dist/core/codegen/schemas/symbol.js +8 -4
- package/dist/core/codegen/schemas/symbol.js.map +1 -1
- package/dist/core/codegen/schemas/template-literal.d.ts +7 -4
- package/dist/core/codegen/schemas/template-literal.d.ts.map +1 -1
- package/dist/core/codegen/schemas/template-literal.js +12 -13
- package/dist/core/codegen/schemas/template-literal.js.map +1 -1
- package/dist/core/codegen/schemas/tuple.d.ts +8 -5
- package/dist/core/codegen/schemas/tuple.d.ts.map +1 -1
- package/dist/core/codegen/schemas/tuple.js +84 -94
- package/dist/core/codegen/schemas/tuple.js.map +1 -1
- package/dist/core/codegen/schemas/undefined.d.ts +7 -4
- package/dist/core/codegen/schemas/undefined.d.ts.map +1 -1
- package/dist/core/codegen/schemas/undefined.js +8 -4
- package/dist/core/codegen/schemas/undefined.js.map +1 -1
- package/dist/core/codegen/schemas/union.d.ts +8 -5
- package/dist/core/codegen/schemas/union.d.ts.map +1 -1
- package/dist/core/codegen/schemas/union.js +49 -69
- package/dist/core/codegen/schemas/union.js.map +1 -1
- package/dist/core/codegen/schemas/unknown.d.ts +7 -4
- package/dist/core/codegen/schemas/unknown.d.ts.map +1 -1
- package/dist/core/codegen/schemas/unknown.js +8 -4
- package/dist/core/codegen/schemas/unknown.js.map +1 -1
- package/dist/core/codegen/schemas/void.d.ts +7 -4
- package/dist/core/codegen/schemas/void.d.ts.map +1 -1
- package/dist/core/codegen/schemas/void.js +8 -4
- package/dist/core/codegen/schemas/void.js.map +1 -1
- package/dist/core/codegen/slow-path.d.ts +7 -4
- package/dist/core/codegen/slow-path.d.ts.map +1 -1
- package/dist/core/codegen/slow-path.js +71 -96
- package/dist/core/codegen/slow-path.js.map +1 -1
- package/dist/core/codegen/well-known-regex.d.ts +22 -19
- package/dist/core/codegen/well-known-regex.d.ts.map +1 -1
- package/dist/core/codegen/well-known-regex.js +127 -96
- package/dist/core/codegen/well-known-regex.js.map +1 -1
- package/dist/core/compile.d.ts +7 -4
- package/dist/core/compile.d.ts.map +1 -1
- package/dist/core/compile.js +48 -48
- package/dist/core/compile.js.map +1 -1
- package/dist/core/diagnostic.d.ts +38 -39
- package/dist/core/diagnostic.d.ts.map +1 -1
- package/dist/core/diagnostic.js +140 -164
- package/dist/core/diagnostic.js.map +1 -1
- package/dist/core/extract/checks.d.ts +18 -15
- package/dist/core/extract/checks.d.ts.map +1 -1
- package/dist/core/extract/checks.js +318 -311
- package/dist/core/extract/checks.js.map +1 -1
- package/dist/core/extract/effects.d.ts +13 -10
- package/dist/core/extract/effects.d.ts.map +1 -1
- package/dist/core/extract/effects.js +153 -222
- package/dist/core/extract/effects.js.map +1 -1
- package/dist/core/extract/extractors/any.d.ts +5 -2
- package/dist/core/extract/extractors/any.d.ts.map +1 -1
- package/dist/core/extract/extractors/any.js +5 -1
- package/dist/core/extract/extractors/any.js.map +1 -1
- package/dist/core/extract/extractors/array.d.ts +6 -3
- package/dist/core/extract/extractors/array.d.ts.map +1 -1
- package/dist/core/extract/extractors/array.js +25 -20
- package/dist/core/extract/extractors/array.js.map +1 -1
- package/dist/core/extract/extractors/bigint.d.ts +6 -3
- package/dist/core/extract/extractors/bigint.d.ts.map +1 -1
- package/dist/core/extract/extractors/bigint.js +66 -64
- package/dist/core/extract/extractors/bigint.js.map +1 -1
- package/dist/core/extract/extractors/boolean.d.ts +5 -2
- package/dist/core/extract/extractors/boolean.d.ts.map +1 -1
- package/dist/core/extract/extractors/boolean.js +7 -3
- package/dist/core/extract/extractors/boolean.js.map +1 -1
- package/dist/core/extract/extractors/catch.d.ts +6 -3
- package/dist/core/extract/extractors/catch.d.ts.map +1 -1
- package/dist/core/extract/extractors/catch.js +26 -17
- package/dist/core/extract/extractors/catch.js.map +1 -1
- package/dist/core/extract/extractors/date.d.ts +6 -3
- package/dist/core/extract/extractors/date.d.ts.map +1 -1
- package/dist/core/extract/extractors/date.js +42 -46
- package/dist/core/extract/extractors/date.js.map +1 -1
- package/dist/core/extract/extractors/default.d.ts +6 -3
- package/dist/core/extract/extractors/default.d.ts.map +1 -1
- package/dist/core/extract/extractors/default.js +20 -14
- package/dist/core/extract/extractors/default.js.map +1 -1
- package/dist/core/extract/extractors/enum.d.ts +5 -2
- package/dist/core/extract/extractors/enum.d.ts.map +1 -1
- package/dist/core/extract/extractors/enum.js +12 -13
- package/dist/core/extract/extractors/enum.js.map +1 -1
- package/dist/core/extract/extractors/file.d.ts +6 -3
- package/dist/core/extract/extractors/file.d.ts.map +1 -1
- package/dist/core/extract/extractors/file.js +34 -28
- package/dist/core/extract/extractors/file.js.map +1 -1
- package/dist/core/extract/extractors/intersection.d.ts +5 -2
- package/dist/core/extract/extractors/intersection.d.ts.map +1 -1
- package/dist/core/extract/extractors/intersection.js +13 -11
- package/dist/core/extract/extractors/intersection.js.map +1 -1
- package/dist/core/extract/extractors/lazy.d.ts +6 -3
- package/dist/core/extract/extractors/lazy.d.ts.map +1 -1
- package/dist/core/extract/extractors/lazy.js +21 -30
- package/dist/core/extract/extractors/lazy.js.map +1 -1
- package/dist/core/extract/extractors/literal.d.ts +5 -2
- package/dist/core/extract/extractors/literal.d.ts.map +1 -1
- package/dist/core/extract/extractors/literal.js +8 -1
- package/dist/core/extract/extractors/literal.js.map +1 -1
- package/dist/core/extract/extractors/map.d.ts +6 -3
- package/dist/core/extract/extractors/map.d.ts.map +1 -1
- package/dist/core/extract/extractors/map.js +10 -4
- package/dist/core/extract/extractors/map.js.map +1 -1
- package/dist/core/extract/extractors/nan.d.ts +5 -2
- package/dist/core/extract/extractors/nan.d.ts.map +1 -1
- package/dist/core/extract/extractors/nan.js +5 -1
- package/dist/core/extract/extractors/nan.js.map +1 -1
- package/dist/core/extract/extractors/never.d.ts +5 -2
- package/dist/core/extract/extractors/never.d.ts.map +1 -1
- package/dist/core/extract/extractors/never.js +5 -1
- package/dist/core/extract/extractors/never.js.map +1 -1
- package/dist/core/extract/extractors/null.d.ts +5 -2
- package/dist/core/extract/extractors/null.d.ts.map +1 -1
- package/dist/core/extract/extractors/null.js +5 -1
- package/dist/core/extract/extractors/null.js.map +1 -1
- package/dist/core/extract/extractors/nullable.d.ts +5 -2
- package/dist/core/extract/extractors/nullable.d.ts.map +1 -1
- package/dist/core/extract/extractors/nullable.js +7 -3
- package/dist/core/extract/extractors/nullable.js.map +1 -1
- package/dist/core/extract/extractors/number.d.ts +6 -3
- package/dist/core/extract/extractors/number.d.ts.map +1 -1
- package/dist/core/extract/extractors/number.js +35 -35
- package/dist/core/extract/extractors/number.js.map +1 -1
- package/dist/core/extract/extractors/object.d.ts +6 -3
- package/dist/core/extract/extractors/object.d.ts.map +1 -1
- package/dist/core/extract/extractors/object.js +49 -76
- package/dist/core/extract/extractors/object.js.map +1 -1
- package/dist/core/extract/extractors/optional.d.ts +5 -2
- package/dist/core/extract/extractors/optional.d.ts.map +1 -1
- package/dist/core/extract/extractors/optional.js +10 -12
- package/dist/core/extract/extractors/optional.js.map +1 -1
- package/dist/core/extract/extractors/pipe.d.ts +6 -3
- package/dist/core/extract/extractors/pipe.d.ts.map +1 -1
- package/dist/core/extract/extractors/pipe.js +40 -41
- package/dist/core/extract/extractors/pipe.js.map +1 -1
- package/dist/core/extract/extractors/readonly.d.ts +5 -2
- package/dist/core/extract/extractors/readonly.d.ts.map +1 -1
- package/dist/core/extract/extractors/readonly.js +10 -6
- package/dist/core/extract/extractors/readonly.js.map +1 -1
- package/dist/core/extract/extractors/record.d.ts +6 -3
- package/dist/core/extract/extractors/record.d.ts.map +1 -1
- package/dist/core/extract/extractors/record.js +24 -35
- package/dist/core/extract/extractors/record.js.map +1 -1
- package/dist/core/extract/extractors/set.d.ts +6 -3
- package/dist/core/extract/extractors/set.d.ts.map +1 -1
- package/dist/core/extract/extractors/set.js +36 -30
- package/dist/core/extract/extractors/set.js.map +1 -1
- package/dist/core/extract/extractors/string-bool.d.ts +7 -4
- package/dist/core/extract/extractors/string-bool.d.ts.map +1 -1
- package/dist/core/extract/extractors/string-bool.js +66 -84
- package/dist/core/extract/extractors/string-bool.js.map +1 -1
- package/dist/core/extract/extractors/string.d.ts +6 -3
- package/dist/core/extract/extractors/string.d.ts.map +1 -1
- package/dist/core/extract/extractors/string.js +34 -37
- package/dist/core/extract/extractors/string.js.map +1 -1
- package/dist/core/extract/extractors/symbol.d.ts +5 -2
- package/dist/core/extract/extractors/symbol.d.ts.map +1 -1
- package/dist/core/extract/extractors/symbol.js +5 -1
- package/dist/core/extract/extractors/symbol.js.map +1 -1
- package/dist/core/extract/extractors/template-literal.d.ts +6 -3
- package/dist/core/extract/extractors/template-literal.d.ts.map +1 -1
- package/dist/core/extract/extractors/template-literal.js +11 -6
- package/dist/core/extract/extractors/template-literal.js.map +1 -1
- package/dist/core/extract/extractors/tuple.d.ts +6 -3
- package/dist/core/extract/extractors/tuple.d.ts.map +1 -1
- package/dist/core/extract/extractors/tuple.js +10 -4
- package/dist/core/extract/extractors/tuple.js.map +1 -1
- package/dist/core/extract/extractors/undefined.d.ts +5 -2
- package/dist/core/extract/extractors/undefined.d.ts.map +1 -1
- package/dist/core/extract/extractors/undefined.js +5 -1
- package/dist/core/extract/extractors/undefined.js.map +1 -1
- package/dist/core/extract/extractors/union.d.ts +6 -3
- package/dist/core/extract/extractors/union.d.ts.map +1 -1
- package/dist/core/extract/extractors/union.js +38 -64
- package/dist/core/extract/extractors/union.js.map +1 -1
- package/dist/core/extract/extractors/unknown.d.ts +5 -2
- package/dist/core/extract/extractors/unknown.d.ts.map +1 -1
- package/dist/core/extract/extractors/unknown.js +5 -1
- package/dist/core/extract/extractors/unknown.js.map +1 -1
- package/dist/core/extract/extractors/void.d.ts +5 -2
- package/dist/core/extract/extractors/void.d.ts.map +1 -1
- package/dist/core/extract/extractors/void.js +5 -1
- package/dist/core/extract/extractors/void.js.map +1 -1
- package/dist/core/extract/fallback.d.ts +6 -3
- package/dist/core/extract/fallback.d.ts.map +1 -1
- package/dist/core/extract/fallback.js +21 -7
- package/dist/core/extract/fallback.js.map +1 -1
- package/dist/core/extract/index.d.ts +6 -4
- package/dist/core/extract/index.d.ts.map +1 -1
- package/dist/core/extract/index.js +15 -15
- package/dist/core/extract/index.js.map +1 -1
- package/dist/core/extract/registry.d.ts +39 -36
- package/dist/core/extract/registry.d.ts.map +1 -1
- package/dist/core/extract/registry.js +96 -123
- package/dist/core/extract/registry.js.map +1 -1
- package/dist/core/extract/types.d.ts +124 -120
- package/dist/core/extract/types.d.ts.map +1 -1
- package/dist/core/extract/types.js +0 -1
- package/dist/core/iife.d.ts +14 -15
- package/dist/core/iife.d.ts.map +1 -1
- package/dist/core/iife.js +182 -206
- package/dist/core/iife.js.map +1 -1
- package/dist/core/pipeline.d.ts +33 -30
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +67 -74
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/types.d.ts +430 -427
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +0 -5
- package/dist/discovery.d.ts +8 -5
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +31 -32
- package/dist/discovery.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/jit.d.ts +15 -42
- package/dist/jit.d.ts.map +1 -1
- package/dist/jit.js +187 -216
- package/dist/jit.js.map +1 -1
- package/dist/loader.d.ts +14 -11
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +226 -258
- package/dist/loader.js.map +1 -1
- package/dist/static-filter.d.ts +4 -1
- package/dist/static-filter.d.ts.map +1 -1
- package/dist/static-filter.js +240 -367
- package/dist/static-filter.js.map +1 -1
- package/dist/swc.d.ts +38 -35
- package/dist/swc.d.ts.map +1 -1
- package/dist/swc.js +83 -76
- package/dist/swc.js.map +1 -1
- package/dist/unplugin/bun.d.ts +5 -2
- package/dist/unplugin/bun.d.ts.map +1 -1
- package/dist/unplugin/bun.js +5 -1
- package/dist/unplugin/bun.js.map +1 -1
- package/dist/unplugin/dep-graph.d.ts +10 -7
- package/dist/unplugin/dep-graph.d.ts.map +1 -1
- package/dist/unplugin/dep-graph.js +216 -252
- package/dist/unplugin/dep-graph.js.map +1 -1
- package/dist/unplugin/disk-cache.d.ts +96 -93
- package/dist/unplugin/disk-cache.d.ts.map +1 -1
- package/dist/unplugin/disk-cache.js +420 -473
- package/dist/unplugin/disk-cache.js.map +1 -1
- package/dist/unplugin/edits.d.ts +15 -12
- package/dist/unplugin/edits.d.ts.map +1 -1
- package/dist/unplugin/edits.js +24 -37
- package/dist/unplugin/edits.js.map +1 -1
- package/dist/unplugin/esbuild.d.ts +5 -2
- package/dist/unplugin/esbuild.d.ts.map +1 -1
- package/dist/unplugin/esbuild.js +5 -1
- package/dist/unplugin/esbuild.js.map +1 -1
- package/dist/unplugin/farm.d.ts +5 -2
- package/dist/unplugin/farm.d.ts.map +1 -1
- package/dist/unplugin/farm.js +5 -1
- package/dist/unplugin/farm.js.map +1 -1
- package/dist/unplugin/hoist-compile.d.ts +14 -42
- package/dist/unplugin/hoist-compile.d.ts.map +1 -1
- package/dist/unplugin/hoist-compile.js +67 -112
- package/dist/unplugin/hoist-compile.js.map +1 -1
- package/dist/unplugin/hoist.d.ts +56 -54
- package/dist/unplugin/hoist.d.ts.map +1 -1
- package/dist/unplugin/hoist.js +945 -1170
- package/dist/unplugin/hoist.js.map +1 -1
- package/dist/unplugin/index.d.ts +5 -3
- package/dist/unplugin/index.d.ts.map +1 -1
- package/dist/unplugin/index.js +175 -250
- package/dist/unplugin/index.js.map +1 -1
- package/dist/unplugin/rolldown.d.ts +5 -2
- package/dist/unplugin/rolldown.d.ts.map +1 -1
- package/dist/unplugin/rolldown.js +5 -1
- package/dist/unplugin/rolldown.js.map +1 -1
- package/dist/unplugin/rollup.d.ts +5 -2
- package/dist/unplugin/rollup.d.ts.map +1 -1
- package/dist/unplugin/rollup.js +5 -1
- package/dist/unplugin/rollup.js.map +1 -1
- package/dist/unplugin/rsbuild.d.ts +6 -3
- package/dist/unplugin/rsbuild.d.ts.map +1 -1
- package/dist/unplugin/rsbuild.js +15 -11
- package/dist/unplugin/rsbuild.js.map +1 -1
- package/dist/unplugin/rspack.d.ts +5 -2
- package/dist/unplugin/rspack.d.ts.map +1 -1
- package/dist/unplugin/rspack.js +5 -1
- package/dist/unplugin/rspack.js.map +1 -1
- package/dist/unplugin/transform.d.ts +30 -27
- package/dist/unplugin/transform.d.ts.map +1 -1
- package/dist/unplugin/transform.js +433 -620
- package/dist/unplugin/transform.js.map +1 -1
- package/dist/unplugin/types.d.ts +189 -184
- package/dist/unplugin/types.d.ts.map +1 -1
- package/dist/unplugin/types.js +22 -18
- package/dist/unplugin/types.js.map +1 -1
- package/dist/unplugin/virtual.d.ts +11 -8
- package/dist/unplugin/virtual.d.ts.map +1 -1
- package/dist/unplugin/virtual.js +65 -83
- package/dist/unplugin/virtual.js.map +1 -1
- package/dist/unplugin/vite.d.ts +5 -2
- package/dist/unplugin/vite.d.ts.map +1 -1
- package/dist/unplugin/vite.js +5 -1
- package/dist/unplugin/vite.js.map +1 -1
- package/dist/unplugin/webpack.d.ts +5 -2
- package/dist/unplugin/webpack.d.ts.map +1 -1
- package/dist/unplugin/webpack.js +5 -1
- package/dist/unplugin/webpack.js.map +1 -1
- package/package.json +23 -14
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/core/extract/types.js.map +0 -1
- package/dist/core/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -1,642 +1,553 @@
|
|
|
1
|
-
|
|
2
|
-
* Build Path: one uninstrumented pass that VALIDATES and BUILDS the stripped
|
|
3
|
-
* output together, abandoning the whole parse at the first failing check.
|
|
4
|
-
*
|
|
5
|
-
* `z.object()` strips unknown keys, so a successful parse cannot return the
|
|
6
|
-
* input by reference — it must produce a fresh object. That rules out the Fast
|
|
7
|
-
* Path (whose contract is `data === input`), and before this the only remaining
|
|
8
|
-
* option was the eager slow walk: a fully instrumented traversal that collects
|
|
9
|
-
* issues on every parse, valid or not.
|
|
10
|
-
*
|
|
11
|
-
* Two passes are wasteful in either direction. Validating first and building
|
|
12
|
-
* afterwards reads every property twice (measured 29.7 ns vs 21.6 for the slow
|
|
13
|
-
* walk on a 6-field object). Building with issue collection pays the
|
|
14
|
-
* instrumentation even when nothing fails. Doing both in ONE pass, with a
|
|
15
|
-
* sentinel instead of an issues array, beats both — and a failure costs only
|
|
16
|
-
* the checks up to the first bad one, because the issue-producing walk is
|
|
17
|
-
* deferred into `.error` exactly as `__zcFinD` does for mutation-free schemas:
|
|
18
|
-
*
|
|
19
|
-
* object clean object invalid array(8) invalid
|
|
20
|
-
* slow walk 21.6 ns 30.4 ns 197.5 ns
|
|
21
|
-
* build path 18.1 ns 7.7 ns 9.8 ns
|
|
22
|
-
*
|
|
23
|
-
* A subtree that rebuilds nothing is validated with its existing Fast Path
|
|
24
|
-
* expression and passed through by reference, so only nodes that genuinely
|
|
25
|
-
* produce a new value need code here; anything else returns null and keeps the
|
|
26
|
-
* eager walk.
|
|
27
|
-
*
|
|
28
|
-
* Coverage is what decides whether this pass is reached at all, because it is
|
|
29
|
-
* all-or-nothing per schema: ONE unmodelled node anywhere in the tree costs the
|
|
30
|
-
* whole schema its single-pass parse. Modelled, beyond the stripping containers
|
|
31
|
-
* this started with: array size checks and `.refine()`, object-level `.refine()`,
|
|
32
|
-
* `.default()` substitution, ordered string rewrites (`.trim()`,
|
|
33
|
-
* `.toLowerCase()`), and sync `.transform()`. Still declined, via
|
|
34
|
-
* {@link mutatesBeyondStrip} — coerce, `.catch()` (its callback wants the inner
|
|
35
|
-
* schema's issue list, which this pass never builds), `z.url()`, and
|
|
36
|
-
* `superRefine`.
|
|
37
|
-
*/
|
|
38
|
-
import { declareFastTemps, emitEffectCallable, emitEffectFn, emitRuntimeHelper, emitTemp, escapeString, keyMembershipTest, outputAlwaysDefined, rejectsUndefined, } from "./context.js";
|
|
39
|
-
import { createFastGen, generateFast } from "./fast-path.js";
|
|
40
|
-
import { EXTRACT_CAP, estimateFastCost, MIN_EXTRACT, predictedInlineSize } from "./fast-size.js";
|
|
1
|
+
import { declareFastTemps, emitEffectCallable, emitEffectFn, emitRuntimeHelper, emitTemp, escapeString, keyMembershipTest, outputAlwaysDefined, rejectsUndefined } from "./context.js";
|
|
41
2
|
import { ZC_HOP_DECL } from "./issue-decls.js";
|
|
42
3
|
import { defaultValueExpr, needsPostInnerDefault } from "./schemas/default.js";
|
|
4
|
+
import { estimateFastCost, predictedInlineSize } from "./fast-size.js";
|
|
43
5
|
import { innerAppliesDefaultOnUndefined } from "./schemas/optional.js";
|
|
44
6
|
import { fastStringCheck } from "./schemas/string.js";
|
|
7
|
+
import { createFastGen, generateFast } from "./fast-path.js";
|
|
8
|
+
//#region src/core/codegen/build-path.ts
|
|
45
9
|
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
10
|
+
* Which nodes of `root` produce a value that is not their input — a stripping
|
|
11
|
+
* object, coercion, default, overwrite or transform, including containers that
|
|
12
|
+
* contain one. Everything else can be validated in place and passed through,
|
|
13
|
+
* which is what keeps this generator small.
|
|
14
|
+
*
|
|
15
|
+
* Computed as a fixpoint rather than a plain walk because of recursion: a
|
|
16
|
+
* `recursiveRef` is a back-edge with no children, so a local walk reads false
|
|
17
|
+
* for it and would pass the whole recursive subtree through by reference —
|
|
18
|
+
* leaving every nested value unstripped while the outermost one was rebuilt.
|
|
19
|
+
* Resolving the ref against its target closes the cycle, and iterating to a
|
|
20
|
+
* fixpoint settles the mutual dependency between the two.
|
|
21
|
+
*/
|
|
57
22
|
function rebuildSet(root) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// never be handed to `passthrough`, whose fast check would reject the
|
|
83
|
-
// absent value outright.
|
|
84
|
-
node.type === "default" ||
|
|
85
|
-
// An overwrite effect (`.trim()`, `.toLowerCase()`) rewrites the string,
|
|
86
|
-
// so the node's output is a new value: it has to be BUILT rather than
|
|
87
|
-
// validated in place (see buildString).
|
|
88
|
-
(node.type === "string" && node.checks.some((c) => c.kind === "overwrite_effect")) ||
|
|
89
|
-
// `.transform(fn)` replaces the value with the callback's result.
|
|
90
|
-
node.type === "effect" ||
|
|
91
|
-
(target !== undefined && rebuilds.has(target)) ||
|
|
92
|
-
children(node).some((child) => rebuilds.has(child));
|
|
93
|
-
if (rebuild) {
|
|
94
|
-
rebuilds.add(node);
|
|
95
|
-
changed = true;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return rebuilds;
|
|
23
|
+
const targets = /* @__PURE__ */ new Map([[0, root]]);
|
|
24
|
+
const nodes = [];
|
|
25
|
+
const seen = /* @__PURE__ */ new Set();
|
|
26
|
+
const collect = (node) => {
|
|
27
|
+
if (seen.has(node)) return;
|
|
28
|
+
seen.add(node);
|
|
29
|
+
nodes.push(node);
|
|
30
|
+
if (node.type === "recursionTarget") targets.set(node.refId, node.inner);
|
|
31
|
+
for (const child of children(node)) collect(child);
|
|
32
|
+
};
|
|
33
|
+
collect(root);
|
|
34
|
+
const rebuilds = /* @__PURE__ */ new Set();
|
|
35
|
+
for (let changed = true; changed;) {
|
|
36
|
+
changed = false;
|
|
37
|
+
for (const node of nodes) {
|
|
38
|
+
if (rebuilds.has(node)) continue;
|
|
39
|
+
const target = node.type === "recursiveRef" ? targets.get(node.refId ?? 0) : void 0;
|
|
40
|
+
if (node.type === "object" && node.stripUnknownKeys === true || node.type === "default" || node.type === "string" && (node.coerce === true || node.checks.some((c) => c.kind === "overwrite_effect")) || (node.type === "number" || node.type === "boolean" || node.type === "bigint" || node.type === "date") && node.coerce === true || node.type === "effect" || target !== void 0 && rebuilds.has(target) || children(node).some((child) => rebuilds.has(child))) {
|
|
41
|
+
rebuilds.add(node);
|
|
42
|
+
changed = true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return rebuilds;
|
|
100
47
|
}
|
|
101
48
|
/** Does `ir`, taken as a whole schema, produce a value that is not its input? */
|
|
102
|
-
|
|
103
|
-
|
|
49
|
+
function rebuildsOutput(ir) {
|
|
50
|
+
return rebuildSet(ir).has(ir);
|
|
104
51
|
}
|
|
105
52
|
/**
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
53
|
+
* True when the subtree mutates for any reason the build pass cannot reproduce —
|
|
54
|
+
* `.catch()`, `z.url()`, `superRefine`. Those rewrite values in ways this pass
|
|
55
|
+
* (which validates, coerces, substitutes declared defaults, applies ordered
|
|
56
|
+
* string rewrites and copies) does not model, so the schema keeps the eager
|
|
57
|
+
* walk.
|
|
58
|
+
*/
|
|
111
59
|
function mutatesBeyondStrip(ir) {
|
|
112
|
-
|
|
60
|
+
return mutatesHere(ir) || children(ir).some(mutatesBeyondStrip);
|
|
113
61
|
}
|
|
114
62
|
/**
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
63
|
+
* Does this node rewrite values on its own account (ignoring its children, and
|
|
64
|
+
* ignoring the reshaping a strip object does)? Mirrors the node-local half of
|
|
65
|
+
* `hasMutation`; the recursion above supplies the other half.
|
|
66
|
+
*/
|
|
119
67
|
function mutatesHere(ir) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// `default` and `effect` are absent: substituting a constant for `undefined`
|
|
134
|
-
// and applying a sync transform are both modelled (see buildDefault /
|
|
135
|
-
// buildEffect), and their inners are reached through `children`.
|
|
136
|
-
//
|
|
137
|
-
// `catch` is NOT: its catchValue callback receives a ctx carrying the inner
|
|
138
|
-
// schema's collected issues, and this pass produces a sentinel instead of an
|
|
139
|
-
// issue list — there is nothing to hand it.
|
|
140
|
-
case "catch":
|
|
141
|
-
case "fallback":
|
|
142
|
-
case "stringBool":
|
|
143
|
-
return true;
|
|
144
|
-
case "object":
|
|
145
|
-
case "array":
|
|
146
|
-
return superRefines(ir.checks);
|
|
147
|
-
default:
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
68
|
+
switch (ir.type) {
|
|
69
|
+
case "string": return superRefines(ir.checks) || ir.checks.some((c) => c.kind === "string_format" && c.format === "url");
|
|
70
|
+
case "number": return superRefines(ir.checks);
|
|
71
|
+
case "boolean":
|
|
72
|
+
case "bigint":
|
|
73
|
+
case "date": return false;
|
|
74
|
+
case "catch":
|
|
75
|
+
case "fallback":
|
|
76
|
+
case "stringBool": return true;
|
|
77
|
+
case "object":
|
|
78
|
+
case "array": return superRefines(ir.checks);
|
|
79
|
+
default: return false;
|
|
80
|
+
}
|
|
150
81
|
}
|
|
151
82
|
function superRefines(checks) {
|
|
152
|
-
|
|
83
|
+
return checks !== void 0 && checks.some((c) => c.kind === "super_refine_effect");
|
|
153
84
|
}
|
|
154
85
|
function children(ir) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
case "nullable":
|
|
176
|
-
case "readonly":
|
|
177
|
-
case "default":
|
|
178
|
-
case "catch":
|
|
179
|
-
case "effect":
|
|
180
|
-
case "recursionTarget":
|
|
181
|
-
return [ir.inner];
|
|
182
|
-
case "pipe":
|
|
183
|
-
return [ir.in, ir.out];
|
|
184
|
-
default:
|
|
185
|
-
return [];
|
|
186
|
-
}
|
|
86
|
+
switch (ir.type) {
|
|
87
|
+
case "object": return ir.catchall ? [...Object.values(ir.properties), ir.catchall] : Object.values(ir.properties);
|
|
88
|
+
case "array": return [ir.element];
|
|
89
|
+
case "tuple": return ir.rest === null ? ir.items : [...ir.items, ir.rest];
|
|
90
|
+
case "record":
|
|
91
|
+
case "map": return [ir.keyType, ir.valueType];
|
|
92
|
+
case "set": return [ir.valueType];
|
|
93
|
+
case "union":
|
|
94
|
+
case "discriminatedUnion": return ir.options;
|
|
95
|
+
case "intersection": return [ir.left, ir.right];
|
|
96
|
+
case "optional":
|
|
97
|
+
case "nullable":
|
|
98
|
+
case "readonly":
|
|
99
|
+
case "default":
|
|
100
|
+
case "catch":
|
|
101
|
+
case "effect":
|
|
102
|
+
case "recursionTarget": return [ir.inner];
|
|
103
|
+
case "pipe": return [ir.in, ir.out];
|
|
104
|
+
default: return [];
|
|
105
|
+
}
|
|
187
106
|
}
|
|
188
107
|
/**
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
108
|
+
* Host the whole schema as `function NAME(input){…}` returning the built value
|
|
109
|
+
* or the FAIL sentinel. Returns the function name, or null when the schema is
|
|
110
|
+
* not expressible as a single build pass.
|
|
111
|
+
*/
|
|
112
|
+
function generateBuild(ir, ctx) {
|
|
113
|
+
const rebuilds = rebuildSet(ir);
|
|
114
|
+
if (!rebuilds.has(ir) || mutatesBeyondStrip(ir)) return null;
|
|
115
|
+
const fail = emitFailSentinel(ctx);
|
|
116
|
+
const scope = {
|
|
117
|
+
temps: [],
|
|
118
|
+
used: 0
|
|
119
|
+
};
|
|
120
|
+
const built = build(ir, "input", {
|
|
121
|
+
ctx,
|
|
122
|
+
extractable: false,
|
|
123
|
+
fail,
|
|
124
|
+
rebuilds,
|
|
125
|
+
scope
|
|
126
|
+
});
|
|
127
|
+
if (built === null) return null;
|
|
128
|
+
const name = emitTemp(ctx, "vb");
|
|
129
|
+
ctx.preamble.push(`function ${name}(input){${declareFastTemps(scope)}${built.code}return ${built.value};}`);
|
|
130
|
+
return name;
|
|
205
131
|
}
|
|
206
132
|
/** One `{}` per validator, compared by identity — no parse output can equal it. */
|
|
207
133
|
function emitFailSentinel(ctx) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
134
|
+
if (ctx.buildFailName === void 0) {
|
|
135
|
+
ctx.buildFailName = `__bf_${ctx.counter++}`;
|
|
136
|
+
ctx.preamble.push(`var ${ctx.buildFailName}={};`);
|
|
137
|
+
}
|
|
138
|
+
return ctx.buildFailName;
|
|
213
139
|
}
|
|
214
140
|
/**
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
141
|
+
* Statements producing the built value of `ir` read from `input`, or null.
|
|
142
|
+
*
|
|
143
|
+
* Size-gated exactly like the fast path: once inlining `ir` would push the
|
|
144
|
+
* function being assembled past EXTRACT_CAP, the sub-build is hosted as its own
|
|
145
|
+
* `__vb_N(p)` returning value-or-FAIL and replaced by a call. Without this a
|
|
146
|
+
* deeply nested schema emits one enormous build function — measured at 113 KB
|
|
147
|
+
* and 354 KB on the deep fixtures — far past the bytecode size where V8 stops
|
|
148
|
+
* running TurboFan on it, which would forfeit the speed this path exists for.
|
|
149
|
+
*/
|
|
224
150
|
function build(ir, input, g) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
// own, so an oversized hosted helper keeps splitting.
|
|
249
|
-
const before = g.scope.used;
|
|
250
|
-
const out = buildInline(ir, input, { ...g, extractable: true });
|
|
251
|
-
if (out !== null)
|
|
252
|
-
g.scope.used = before + out.code.length;
|
|
253
|
-
return out;
|
|
151
|
+
if (ir.type === "recursiveRef") return buildRecursiveCall(ir.refId ?? 0, input, g);
|
|
152
|
+
if (ir.type === "recursionTarget") return buildRecursionTarget(ir, input, g);
|
|
153
|
+
if (!g.rebuilds.has(ir)) return passthrough(ir, input, g);
|
|
154
|
+
const cache = g.ctx.fastSizeCache ??= /* @__PURE__ */ new WeakMap();
|
|
155
|
+
if (g.extractable && g.scope.used + predictedInlineSize(ir, input.length, cache) > 38e3 && (g.scope.used > 38e3 || estimateFastCost(ir, cache) >= 1200)) {
|
|
156
|
+
const hosted = hostBuild(ir, g);
|
|
157
|
+
if (hosted !== null) {
|
|
158
|
+
const slot = local(g, "bh");
|
|
159
|
+
const code = `${slot}=${hosted}(${input});if(${slot}===${g.fail})return ${g.fail};`;
|
|
160
|
+
g.scope.used += code.length;
|
|
161
|
+
return {
|
|
162
|
+
code,
|
|
163
|
+
value: slot
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const before = g.scope.used;
|
|
168
|
+
const out = buildInline(ir, input, {
|
|
169
|
+
...g,
|
|
170
|
+
extractable: true
|
|
171
|
+
});
|
|
172
|
+
if (out !== null) g.scope.used = before + out.code.length;
|
|
173
|
+
return out;
|
|
254
174
|
}
|
|
255
175
|
/** Host `ir`'s build in its own function over a fresh parameter; returns its name. */
|
|
256
176
|
function hostBuild(ir, g) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
177
|
+
const param = emitTemp(g.ctx, "bp");
|
|
178
|
+
const scope = {
|
|
179
|
+
temps: [],
|
|
180
|
+
used: 0
|
|
181
|
+
};
|
|
182
|
+
const inner = build(ir, param, {
|
|
183
|
+
...g,
|
|
184
|
+
extractable: false,
|
|
185
|
+
scope
|
|
186
|
+
});
|
|
187
|
+
if (inner === null) return null;
|
|
188
|
+
const name = emitTemp(g.ctx, "vb");
|
|
189
|
+
g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}${inner.code}return ${inner.value};}`);
|
|
190
|
+
return name;
|
|
265
191
|
}
|
|
266
192
|
function buildInline(ir, input, g) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
return buildSentinel(ir.inner, input, g, "===null", "null");
|
|
287
|
-
case "default":
|
|
288
|
-
return buildDefault(ir, input, g);
|
|
289
|
-
case "string":
|
|
290
|
-
return buildString(ir, input, g);
|
|
291
|
-
case "effect":
|
|
292
|
-
return buildEffect(ir, input, g);
|
|
293
|
-
case "readonly":
|
|
294
|
-
return build(ir.inner, input, g);
|
|
295
|
-
case "union":
|
|
296
|
-
case "discriminatedUnion":
|
|
297
|
-
return buildUnion(ir, input, g);
|
|
298
|
-
default:
|
|
299
|
-
// A rebuilding intersection, map or set: expressible in principle, but
|
|
300
|
-
// each needs its own output-shaping rules, so they keep the eager walk
|
|
301
|
-
// until there is a measured reason to add them.
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
193
|
+
switch (ir.type) {
|
|
194
|
+
case "object": return buildObject(ir, input, g);
|
|
195
|
+
case "array": return buildArray(ir, input, g);
|
|
196
|
+
case "tuple": return buildTuple(ir, input, g);
|
|
197
|
+
case "record": return buildRecord(ir, input, g);
|
|
198
|
+
case "optional": return innerAppliesDefaultOnUndefined(ir.inner) ? build(ir.inner, input, g) : buildSentinel(ir.inner, input, g, "===undefined", "undefined");
|
|
199
|
+
case "nullable": return buildSentinel(ir.inner, input, g, "===null", "null");
|
|
200
|
+
case "default": return buildDefault(ir, input, g);
|
|
201
|
+
case "string": return buildString(ir, input, g);
|
|
202
|
+
case "number":
|
|
203
|
+
case "boolean":
|
|
204
|
+
case "bigint":
|
|
205
|
+
case "date": return buildCoercedPrimitive(ir, input, g);
|
|
206
|
+
case "effect": return buildEffect(ir, input, g);
|
|
207
|
+
case "readonly": return build(ir.inner, input, g);
|
|
208
|
+
case "union":
|
|
209
|
+
case "discriminatedUnion": return buildUnion(ir, input, g);
|
|
210
|
+
default: return null;
|
|
211
|
+
}
|
|
304
212
|
}
|
|
305
213
|
/**
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
214
|
+
* Host the target's build once under a name registered BEFORE its body is
|
|
215
|
+
* generated, so the back-edges inside that body resolve to it.
|
|
216
|
+
*/
|
|
309
217
|
function buildRecursionTarget(ir, input, g) {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
218
|
+
const table = g.ctx.buildRecNames ??= /* @__PURE__ */ new Map();
|
|
219
|
+
if (!table.has(ir.refId)) {
|
|
220
|
+
const name = emitTemp(g.ctx, "vbr");
|
|
221
|
+
table.set(ir.refId, name);
|
|
222
|
+
const param = emitTemp(g.ctx, "bp");
|
|
223
|
+
const scope = {
|
|
224
|
+
temps: [],
|
|
225
|
+
used: 0
|
|
226
|
+
};
|
|
227
|
+
const inner = build(ir.inner, param, {
|
|
228
|
+
...g,
|
|
229
|
+
extractable: false,
|
|
230
|
+
scope
|
|
231
|
+
});
|
|
232
|
+
if (inner === null) {
|
|
233
|
+
table.delete(ir.refId);
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}${inner.code}return ${inner.value};}`);
|
|
237
|
+
}
|
|
238
|
+
return buildRecursiveCall(ir.refId, input, g);
|
|
324
239
|
}
|
|
325
240
|
/** Call the hosted build for a recursion target, propagating its FAIL. */
|
|
326
241
|
function buildRecursiveCall(refId, input, g) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
};
|
|
242
|
+
const name = g.ctx.buildRecNames?.get(refId);
|
|
243
|
+
if (name === void 0) return null;
|
|
244
|
+
const slot = local(g, "bh");
|
|
245
|
+
return {
|
|
246
|
+
code: `${slot}=${name}(${input});if(${slot}===${g.fail})return ${g.fail};`,
|
|
247
|
+
value: slot
|
|
248
|
+
};
|
|
335
249
|
}
|
|
336
250
|
/**
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
251
|
+
* Try each option in declaration order and take the first that builds — which
|
|
252
|
+
* is what zod's union does with the first option that parses.
|
|
253
|
+
*
|
|
254
|
+
* Every option is HOSTED rather than inlined, and that is load-bearing: a
|
|
255
|
+
* failing build signals with `return FAIL`, which inside the enclosing function
|
|
256
|
+
* would abandon the whole parse instead of moving on to the next option. Behind
|
|
257
|
+
* a call, the same signal is just a value to test.
|
|
258
|
+
*
|
|
259
|
+
* A discriminated union gets the same treatment rather than a switch: the
|
|
260
|
+
* options still have to be probed by call, and its dispatch advantage is
|
|
261
|
+
* already spent by the enclosing container's own work.
|
|
262
|
+
*/
|
|
349
263
|
function buildUnion(ir, input, g) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
return { code, value: out };
|
|
264
|
+
const hosted = [];
|
|
265
|
+
for (const option of ir.options) {
|
|
266
|
+
const fn = g.rebuilds.has(option) ? hostBuild(option, g) : hostPassthrough(option, g);
|
|
267
|
+
if (fn === null) return null;
|
|
268
|
+
hosted.push(fn);
|
|
269
|
+
}
|
|
270
|
+
if (hosted.length === 0) return null;
|
|
271
|
+
const out = local(g, "bu");
|
|
272
|
+
let code = `${out}=${hosted[0]}(${input});`;
|
|
273
|
+
for (const fn of hosted.slice(1)) code += `if(${out}===${g.fail}){${out}=${fn}(${input});}`;
|
|
274
|
+
code += `if(${out}===${g.fail})return ${g.fail};`;
|
|
275
|
+
return {
|
|
276
|
+
code,
|
|
277
|
+
value: out
|
|
278
|
+
};
|
|
366
279
|
}
|
|
367
280
|
/**
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
281
|
+
* Host a non-rebuilding option as `value-or-FAIL`, so a union can probe it with
|
|
282
|
+
* the same protocol as a rebuilding one.
|
|
283
|
+
*/
|
|
371
284
|
function hostPassthrough(ir, g) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
285
|
+
const param = emitTemp(g.ctx, "bp");
|
|
286
|
+
const scope = {
|
|
287
|
+
temps: [],
|
|
288
|
+
used: 0
|
|
289
|
+
};
|
|
290
|
+
const expr = generateFast(ir, createFastGen(param, g.ctx, true, scope));
|
|
291
|
+
if (expr === null) return null;
|
|
292
|
+
const name = emitTemp(g.ctx, "vp");
|
|
293
|
+
g.ctx.preamble.push(`function ${name}(${param}){${declareFastTemps(scope)}return ${expr === "true" ? param : `(${expr})?${param}:${g.fail}`};}`);
|
|
294
|
+
return name;
|
|
380
295
|
}
|
|
381
296
|
/** Validate in place with the Fast Path and hand the input straight back. */
|
|
382
297
|
function passthrough(ir, input, g) {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
298
|
+
const expr = generateFast(ir, createFastGen(input, g.ctx, true, g.scope));
|
|
299
|
+
if (expr === null) return null;
|
|
300
|
+
return {
|
|
301
|
+
code: expr === "true" ? "" : `if(!(${expr}))return ${g.fail};`,
|
|
302
|
+
value: input
|
|
303
|
+
};
|
|
388
304
|
}
|
|
389
305
|
/**
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
306
|
+
* Rebuild from the declared keys. Sound for a stripping object (that IS the
|
|
307
|
+
* output) and for a strict one (unknown keys are rejected, so the declared keys
|
|
308
|
+
* are the whole key set). A loose object or one with a `.catchall()` keeps keys
|
|
309
|
+
* this pass does not enumerate, so those bail.
|
|
310
|
+
*/
|
|
395
311
|
function buildObject(ir, input, g) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
}
|
|
439
|
-
leading = false;
|
|
440
|
-
appends += slot.always
|
|
441
|
-
? `${out}[${slot.keyStr}]=${slot.value};`
|
|
442
|
-
: `if(${slot.value}!==undefined||(${slot.keyStr} in ${input})){${out}[${slot.keyStr}]=${slot.value};}`;
|
|
443
|
-
}
|
|
444
|
-
code += `${out}={${literal.join(",")}};${appends}`;
|
|
445
|
-
// Zod parses the properties into the payload first and skips the check chain
|
|
446
|
-
// when that produced issues, so a bad property suppresses the refine — which
|
|
447
|
-
// this pass gets for free, having already returned FAIL at that property.
|
|
448
|
-
for (const check of refines) {
|
|
449
|
-
code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
|
|
450
|
-
}
|
|
451
|
-
return { code, value: out };
|
|
312
|
+
if (ir.catchall !== void 0) return null;
|
|
313
|
+
if (ir.stripUnknownKeys !== true && ir.strict !== true) return null;
|
|
314
|
+
if (ir.suppressAbsentKeys !== void 0 && ir.suppressAbsentKeys.length > 0) return null;
|
|
315
|
+
const refines = ir.checks ?? [];
|
|
316
|
+
if (refines.some((check) => check.kind !== "refine_effect")) return null;
|
|
317
|
+
let code = `if(typeof ${input}!=="object"||${input}===null||Array.isArray(${input}))return ${g.fail};`;
|
|
318
|
+
if (ir.strict === true) {
|
|
319
|
+
const keyVar = local(g, "bk");
|
|
320
|
+
code += `for(${keyVar} in ${input}){if(!(${keyMembershipTest(g.ctx, Object.keys(ir.properties), keyVar)}))return ${g.fail};}`;
|
|
321
|
+
}
|
|
322
|
+
const slots = [];
|
|
323
|
+
for (const [key, propIR] of Object.entries(ir.properties)) {
|
|
324
|
+
const keyStr = escapeString(key);
|
|
325
|
+
const slot = local(g, "bv");
|
|
326
|
+
code += `${slot}=${input}[${keyStr}];`;
|
|
327
|
+
const propBuilt = build(propIR, slot, g);
|
|
328
|
+
if (propBuilt === null) return null;
|
|
329
|
+
code += propBuilt.code;
|
|
330
|
+
slots.push({
|
|
331
|
+
always: outputAlwaysDefined(propIR),
|
|
332
|
+
keyStr,
|
|
333
|
+
value: propBuilt.value
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
const out = local(g, "bo");
|
|
337
|
+
const literal = [];
|
|
338
|
+
let appends = "";
|
|
339
|
+
let leading = true;
|
|
340
|
+
for (const slot of slots) {
|
|
341
|
+
if (leading && slot.always) {
|
|
342
|
+
literal.push(`${slot.keyStr}:${slot.value}`);
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
leading = false;
|
|
346
|
+
appends += slot.always ? `${out}[${slot.keyStr}]=${slot.value};` : `if(${slot.value}!==undefined||(${slot.keyStr} in ${input})){${out}[${slot.keyStr}]=${slot.value};}`;
|
|
347
|
+
}
|
|
348
|
+
code += `${out}={${literal.join(",")}};${appends}`;
|
|
349
|
+
for (const check of refines) code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
|
|
350
|
+
return {
|
|
351
|
+
code,
|
|
352
|
+
value: out
|
|
353
|
+
};
|
|
452
354
|
}
|
|
453
355
|
function buildArray(ir, input, g) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
const elem = local(g, "be");
|
|
483
|
-
const inner = build(ir.element, elem, g);
|
|
484
|
-
if (inner === null)
|
|
485
|
-
return null;
|
|
486
|
-
let code = `if(!Array.isArray(${input}))return ${g.fail};` +
|
|
487
|
-
sizes +
|
|
488
|
-
`${out}=new Array(${input}.length);` +
|
|
489
|
-
`for(${index}=0;${index}<${input}.length;${index}++){` +
|
|
490
|
-
`${elem}=${input}[${index}];${inner.code}${out}[${index}]=${inner.value};}`;
|
|
491
|
-
// `.refine()` sees the parsed payload, which for a rebuilding element is the
|
|
492
|
-
// freshly assembled array — the same value zod hands its checks.
|
|
493
|
-
for (const check of refines) {
|
|
494
|
-
code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
|
|
495
|
-
}
|
|
496
|
-
return { code, value: out };
|
|
356
|
+
let sizes = "";
|
|
357
|
+
const refines = [];
|
|
358
|
+
for (const check of ir.checks) switch (check.kind) {
|
|
359
|
+
case "min_length":
|
|
360
|
+
sizes += `if(${input}.length<${check.minimum})return ${g.fail};`;
|
|
361
|
+
break;
|
|
362
|
+
case "max_length":
|
|
363
|
+
sizes += `if(${input}.length>${check.maximum})return ${g.fail};`;
|
|
364
|
+
break;
|
|
365
|
+
case "length_equals":
|
|
366
|
+
sizes += `if(${input}.length!==${check.length})return ${g.fail};`;
|
|
367
|
+
break;
|
|
368
|
+
case "refine_effect":
|
|
369
|
+
refines.push(check);
|
|
370
|
+
break;
|
|
371
|
+
default: return null;
|
|
372
|
+
}
|
|
373
|
+
const out = local(g, "ba");
|
|
374
|
+
const index = local(g, "bi");
|
|
375
|
+
const elem = local(g, "be");
|
|
376
|
+
const inner = build(ir.element, elem, g);
|
|
377
|
+
if (inner === null) return null;
|
|
378
|
+
let code = `if(!Array.isArray(${input}))return ${g.fail};` + sizes + `${out}=new Array(${input}.length);for(${index}=0;${index}<${input}.length;${index}++){${elem}=${input}[${index}];${inner.code}${out}[${index}]=${inner.value};}`;
|
|
379
|
+
for (const check of refines) code += `if(!${emitEffectCallable(g.ctx, check)}(${out}))return ${g.fail};`;
|
|
380
|
+
return {
|
|
381
|
+
code,
|
|
382
|
+
value: out
|
|
383
|
+
};
|
|
497
384
|
}
|
|
498
385
|
function buildTuple(ir, input, g) {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
code += `${out}=[${values.join(",")}];`;
|
|
518
|
-
return { code, value: out };
|
|
386
|
+
if (ir.rest !== null) return null;
|
|
387
|
+
if (ir.items.some((item) => !rejectsUndefined(item))) return null;
|
|
388
|
+
let code = `if(!Array.isArray(${input})||${input}.length!==${ir.items.length})return ${g.fail};`;
|
|
389
|
+
const values = [];
|
|
390
|
+
for (const [index, itemIR] of ir.items.entries()) {
|
|
391
|
+
const slot = local(g, "bt");
|
|
392
|
+
code += `${slot}=${input}[${index}];`;
|
|
393
|
+
const inner = build(itemIR, slot, g);
|
|
394
|
+
if (inner === null) return null;
|
|
395
|
+
code += inner.code;
|
|
396
|
+
values.push(inner.value);
|
|
397
|
+
}
|
|
398
|
+
const out = local(g, "bl");
|
|
399
|
+
code += `${out}=[${values.join(",")}];`;
|
|
400
|
+
return {
|
|
401
|
+
code,
|
|
402
|
+
value: out
|
|
403
|
+
};
|
|
519
404
|
}
|
|
520
405
|
function buildRecord(ir, input, g) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
`${out}={};` +
|
|
533
|
-
`for(${keyVar} in ${input}){if(${hop}.call(${input},${keyVar})){` +
|
|
534
|
-
`${valVar}=${input}[${keyVar}];${inner.code}${out}[${keyVar}]=${inner.value};}}`;
|
|
535
|
-
return { code, value: out };
|
|
406
|
+
if (!(ir.keyType.type === "string" && ir.keyType.checks.length === 0 && ir.keyType.coerce !== true)) return null;
|
|
407
|
+
const out = local(g, "br");
|
|
408
|
+
const keyVar = local(g, "brk");
|
|
409
|
+
const valVar = local(g, "brv");
|
|
410
|
+
const inner = build(ir.valueType, valVar, g);
|
|
411
|
+
if (inner === null) return null;
|
|
412
|
+
const hop = emitRuntimeHelper(g.ctx, "__zcHop", ZC_HOP_DECL);
|
|
413
|
+
return {
|
|
414
|
+
code: `if(typeof ${input}!=="object"||${input}===null||Array.isArray(${input}))return ${g.fail};${out}={};for(${keyVar} in ${input}){if(${hop}.call(${input},${keyVar})){${valVar}=${input}[${keyVar}];${inner.code}${out}[${keyVar}]=${inner.value};}}`,
|
|
415
|
+
value: out
|
|
416
|
+
};
|
|
536
417
|
}
|
|
537
418
|
/**
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
419
|
+
* `.transform(fn)`: validate the inner schema, then hand its parsed value to the
|
|
420
|
+
* callback. Zod's transform is a pipe whose `in` failing aborts the whole thing,
|
|
421
|
+
* which is exactly what returning FAIL from the inner build does — so the
|
|
422
|
+
* callback runs only on a clean parse, as `slowEffect` guarantees with its issue
|
|
423
|
+
* count.
|
|
424
|
+
*
|
|
425
|
+
* The IR reaches here only for a synchronous single-argument callback: a
|
|
426
|
+
* `ctx`-taking or async transform is extracted as a `fallback` instead
|
|
427
|
+
* (see extractPipe), so there is no parse context to reproduce.
|
|
428
|
+
*/
|
|
548
429
|
function buildEffect(ir, input, g) {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
};
|
|
430
|
+
const inner = build(ir.inner, input, g);
|
|
431
|
+
if (inner === null) return null;
|
|
432
|
+
const out = local(g, "bx");
|
|
433
|
+
return {
|
|
434
|
+
code: `${inner.code}${out}=${emitEffectCallable(g.ctx, ir)}(${inner.value});`,
|
|
435
|
+
value: out
|
|
436
|
+
};
|
|
557
437
|
}
|
|
558
438
|
/**
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
439
|
+
* A coercing and/or overwrite string (`z.coerce.string()`, `.trim()`,
|
|
440
|
+
* `.toLowerCase()`, ...): coerce first, then emit checks one statement at a time
|
|
441
|
+
* in DECLARATION order, interleaved with rewrites, because a rewrite is visible
|
|
442
|
+
* to every check after it — `z.string().trim().min(1)` rejects `" "` where
|
|
443
|
+
* `z.string().min(1).trim()` accepts it. That ordering is exactly why the fast
|
|
444
|
+
* path, which sorts checks cheapest-first and returns the input unchanged, has
|
|
445
|
+
* to decline these.
|
|
446
|
+
*
|
|
447
|
+
* Only reached for a rewriting string; a non-coercing, check-only one never
|
|
448
|
+
* enters the rebuild set and is validated in place by `passthrough`.
|
|
449
|
+
*/
|
|
569
450
|
function buildString(ir, input, g) {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
451
|
+
const value = local(g, "bs");
|
|
452
|
+
let code = ir.coerce === true ? `try{${value}=String(${input});}catch(_){return ${g.fail};}` : `if(typeof ${input}!=="string")return ${g.fail};${value}=${input};`;
|
|
453
|
+
for (const check of ir.checks) switch (check.kind) {
|
|
454
|
+
case "overwrite_effect":
|
|
455
|
+
code += `${value}=${emitEffectFn(g.ctx, check.source)}(${value});`;
|
|
456
|
+
break;
|
|
457
|
+
case "refine_effect":
|
|
458
|
+
code += `if(!${emitEffectCallable(g.ctx, check)}(${value}))return ${g.fail};`;
|
|
459
|
+
break;
|
|
460
|
+
case "super_refine_effect": return null;
|
|
461
|
+
default: {
|
|
462
|
+
const expr = fastStringCheck(check, value, g.ctx);
|
|
463
|
+
if (expr === null) return null;
|
|
464
|
+
code += `if(!(${expr}))return ${g.fail};`;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
return {
|
|
468
|
+
code,
|
|
469
|
+
value
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Coerce once into a local, then reuse the ordinary Fast Path as the acceptance
|
|
474
|
+
* predicate over the converted value. The build path only needs a verdict on
|
|
475
|
+
* its hot pass; if it fails, the existing deferred slow walk reruns the original
|
|
476
|
+
* coercing schema and produces Zod-identical issues.
|
|
477
|
+
*
|
|
478
|
+
* Number/BigInt/Date conversion can invoke user hooks and throw. Zod catches
|
|
479
|
+
* those throws and reports invalid_type, so the sentinel branch does the same
|
|
480
|
+
* without allocating an issue. Boolean never invokes conversion hooks.
|
|
481
|
+
*/
|
|
482
|
+
function buildCoercedPrimitive(ir, input, g) {
|
|
483
|
+
if (ir.coerce !== true) return null;
|
|
484
|
+
const value = local(g, "bc");
|
|
485
|
+
let conversion;
|
|
486
|
+
switch (ir.type) {
|
|
487
|
+
case "number":
|
|
488
|
+
conversion = `Number(${input})`;
|
|
489
|
+
break;
|
|
490
|
+
case "boolean":
|
|
491
|
+
conversion = `Boolean(${input})`;
|
|
492
|
+
break;
|
|
493
|
+
case "bigint":
|
|
494
|
+
conversion = `BigInt(${input})`;
|
|
495
|
+
break;
|
|
496
|
+
case "date":
|
|
497
|
+
conversion = `new Date(${input})`;
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
const predicate = generateFast({
|
|
501
|
+
...ir,
|
|
502
|
+
coerce: false
|
|
503
|
+
}, createFastGen(value, g.ctx, true, g.scope));
|
|
504
|
+
if (predicate === null) return null;
|
|
505
|
+
const assign = `${value}=${conversion};`;
|
|
506
|
+
return {
|
|
507
|
+
code: (ir.type === "boolean" ? assign : `try{${assign}}catch(_){return ${g.fail};}`) + (predicate === "true" ? "" : `if(!(${predicate}))return ${g.fail};`),
|
|
508
|
+
value
|
|
509
|
+
};
|
|
594
510
|
}
|
|
595
511
|
/**
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
512
|
+
* `.default(v)`: `undefined` yields the declared value without running the
|
|
513
|
+
* inner schema, anything else parses normally — the same two branches
|
|
514
|
+
* `slowDefault` emits, reading the value off the retained schema so a
|
|
515
|
+
* reference-typed default keeps zod's identity (one shared object, not a copy).
|
|
516
|
+
*
|
|
517
|
+
* The substituted value is not validated, so it makes the fast path a PARTIAL
|
|
518
|
+
* predicate (`fc(undefined)` is false where the schema accepts) — which is why
|
|
519
|
+
* this records {@link CodeGenContext.buildSubstitutesValue}, on which
|
|
520
|
+
* `generateValidator` withholds `.is()`.
|
|
521
|
+
*/
|
|
606
522
|
function buildDefault(ir, input, g) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
// input; only emitted when the inner can actually do that.
|
|
618
|
-
const reapply = needsPostInnerDefault(ir) ? `if(${out}===undefined){${out}=${value};}` : "";
|
|
619
|
-
return {
|
|
620
|
-
code: `if(${input}===undefined){${out}=${value};}` +
|
|
621
|
-
`else{${inner.code}${out}=${inner.value};${reapply}}`,
|
|
622
|
-
value: out,
|
|
623
|
-
};
|
|
523
|
+
const inner = build(ir.inner, input, g);
|
|
524
|
+
if (inner === null) return null;
|
|
525
|
+
g.ctx.buildSubstitutesValue = true;
|
|
526
|
+
const out = local(g, "bq");
|
|
527
|
+
const value = defaultValueExpr(ir);
|
|
528
|
+
const reapply = needsPostInnerDefault(ir) ? `if(${out}===undefined){${out}=${value};}` : "";
|
|
529
|
+
return {
|
|
530
|
+
code: `if(${input}===undefined){${out}=${value};}else{${inner.code}${out}=${inner.value};${reapply}}`,
|
|
531
|
+
value: out
|
|
532
|
+
};
|
|
624
533
|
}
|
|
625
534
|
/** `optional` / `nullable` around a rebuilding inner: pass the sentinel through. */
|
|
626
535
|
function buildSentinel(innerIR, input, g, test, sentinel) {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
};
|
|
536
|
+
const inner = build(innerIR, input, g);
|
|
537
|
+
if (inner === null) return null;
|
|
538
|
+
const out = local(g, "bw");
|
|
539
|
+
return {
|
|
540
|
+
code: `if(${input}${test}){${out}=${sentinel};}else{${inner.code}${out}=${inner.value};}`,
|
|
541
|
+
value: out
|
|
542
|
+
};
|
|
635
543
|
}
|
|
636
544
|
/** Allocate a `var` the hosted build function declares. */
|
|
637
545
|
function local(g, prefix) {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
546
|
+
const name = emitTemp(g.ctx, prefix);
|
|
547
|
+
g.scope.temps.push(name);
|
|
548
|
+
return name;
|
|
641
549
|
}
|
|
550
|
+
//#endregion
|
|
551
|
+
export { generateBuild, rebuildsOutput };
|
|
552
|
+
|
|
642
553
|
//# sourceMappingURL=build-path.js.map
|