@nekostack/schema 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +422 -0
- package/LICENSE +202 -0
- package/README.md +656 -0
- package/dist/src/builders/array.d.ts +12 -0
- package/dist/src/builders/array.d.ts.map +1 -0
- package/dist/src/builders/array.js +29 -0
- package/dist/src/builders/array.js.map +1 -0
- package/dist/src/builders/object.d.ts +62 -0
- package/dist/src/builders/object.d.ts.map +1 -0
- package/dist/src/builders/object.js +263 -0
- package/dist/src/builders/object.js.map +1 -0
- package/dist/src/builders/primitives.d.ts +37 -0
- package/dist/src/builders/primitives.d.ts.map +1 -0
- package/dist/src/builders/primitives.js +125 -0
- package/dist/src/builders/primitives.js.map +1 -0
- package/dist/src/builders/s.d.ts +27 -0
- package/dist/src/builders/s.d.ts.map +1 -0
- package/dist/src/builders/s.js +39 -0
- package/dist/src/builders/s.js.map +1 -0
- package/dist/src/builders/schema.d.ts +70 -0
- package/dist/src/builders/schema.d.ts.map +1 -0
- package/dist/src/builders/schema.js +98 -0
- package/dist/src/builders/schema.js.map +1 -0
- package/dist/src/cli-integration.d.ts +43 -0
- package/dist/src/cli-integration.d.ts.map +1 -0
- package/dist/src/cli-integration.js +48 -0
- package/dist/src/cli-integration.js.map +1 -0
- package/dist/src/errors/issue.d.ts +34 -0
- package/dist/src/errors/issue.d.ts.map +1 -0
- package/dist/src/errors/issue.js +89 -0
- package/dist/src/errors/issue.js.map +1 -0
- package/dist/src/generators/errors.d.ts +31 -0
- package/dist/src/generators/errors.d.ts.map +1 -0
- package/dist/src/generators/errors.js +34 -0
- package/dist/src/generators/errors.js.map +1 -0
- package/dist/src/generators/header.d.ts +42 -0
- package/dist/src/generators/header.d.ts.map +1 -0
- package/dist/src/generators/header.js +43 -0
- package/dist/src/generators/header.js.map +1 -0
- package/dist/src/generators/json-schema-meta.d.ts +36 -0
- package/dist/src/generators/json-schema-meta.d.ts.map +1 -0
- package/dist/src/generators/json-schema-meta.js +35 -0
- package/dist/src/generators/json-schema-meta.js.map +1 -0
- package/dist/src/generators/json-schema.d.ts +26 -0
- package/dist/src/generators/json-schema.d.ts.map +1 -0
- package/dist/src/generators/json-schema.js +88 -0
- package/dist/src/generators/json-schema.js.map +1 -0
- package/dist/src/generators/openapi.d.ts +33 -0
- package/dist/src/generators/openapi.d.ts.map +1 -0
- package/dist/src/generators/openapi.js +61 -0
- package/dist/src/generators/openapi.js.map +1 -0
- package/dist/src/generators/schema-fragment.d.ts +55 -0
- package/dist/src/generators/schema-fragment.d.ts.map +1 -0
- package/dist/src/generators/schema-fragment.js +253 -0
- package/dist/src/generators/schema-fragment.js.map +1 -0
- package/dist/src/generators/ts.d.ts +19 -0
- package/dist/src/generators/ts.d.ts.map +1 -0
- package/dist/src/generators/ts.js +252 -0
- package/dist/src/generators/ts.js.map +1 -0
- package/dist/src/generators/types.d.ts +96 -0
- package/dist/src/generators/types.d.ts.map +1 -0
- package/dist/src/generators/types.js +10 -0
- package/dist/src/generators/types.js.map +1 -0
- package/dist/src/generators/version.d.ts +11 -0
- package/dist/src/generators/version.d.ts.map +1 -0
- package/dist/src/generators/version.js +11 -0
- package/dist/src/generators/version.js.map +1 -0
- package/dist/src/generators/zod-mapping.d.ts +90 -0
- package/dist/src/generators/zod-mapping.d.ts.map +1 -0
- package/dist/src/generators/zod-mapping.js +174 -0
- package/dist/src/generators/zod-mapping.js.map +1 -0
- package/dist/src/generators/zod.d.ts +17 -0
- package/dist/src/generators/zod.d.ts.map +1 -0
- package/dist/src/generators/zod.js +118 -0
- package/dist/src/generators/zod.js.map +1 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +43 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/ir/hash.d.ts +19 -0
- package/dist/src/ir/hash.d.ts.map +1 -0
- package/dist/src/ir/hash.js +22 -0
- package/dist/src/ir/hash.js.map +1 -0
- package/dist/src/ir/nodes.d.ts +121 -0
- package/dist/src/ir/nodes.d.ts.map +1 -0
- package/dist/src/ir/nodes.js +14 -0
- package/dist/src/ir/nodes.js.map +1 -0
- package/dist/src/ir/serialize.d.ts +8 -0
- package/dist/src/ir/serialize.d.ts.map +1 -0
- package/dist/src/ir/serialize.js +23 -0
- package/dist/src/ir/serialize.js.map +1 -0
- package/dist/src/migrations/build-migration-registry.d.ts +46 -0
- package/dist/src/migrations/build-migration-registry.d.ts.map +1 -0
- package/dist/src/migrations/build-migration-registry.js +134 -0
- package/dist/src/migrations/build-migration-registry.js.map +1 -0
- package/dist/src/migrations/handlers/list.d.ts +35 -0
- package/dist/src/migrations/handlers/list.d.ts.map +1 -0
- package/dist/src/migrations/handlers/list.js +55 -0
- package/dist/src/migrations/handlers/list.js.map +1 -0
- package/dist/src/migrations/handlers/plan.d.ts +26 -0
- package/dist/src/migrations/handlers/plan.d.ts.map +1 -0
- package/dist/src/migrations/handlers/plan.js +28 -0
- package/dist/src/migrations/handlers/plan.js.map +1 -0
- package/dist/src/migrations/handlers/stub.d.ts +22 -0
- package/dist/src/migrations/handlers/stub.d.ts.map +1 -0
- package/dist/src/migrations/handlers/stub.js +24 -0
- package/dist/src/migrations/handlers/stub.js.map +1 -0
- package/dist/src/migrations/handlers/verify.d.ts +25 -0
- package/dist/src/migrations/handlers/verify.d.ts.map +1 -0
- package/dist/src/migrations/handlers/verify.js +27 -0
- package/dist/src/migrations/handlers/verify.js.map +1 -0
- package/dist/src/migrations/parse-provenance.d.ts +78 -0
- package/dist/src/migrations/parse-provenance.d.ts.map +1 -0
- package/dist/src/migrations/parse-provenance.js +157 -0
- package/dist/src/migrations/parse-provenance.js.map +1 -0
- package/dist/src/migrations/plan-migration.d.ts +50 -0
- package/dist/src/migrations/plan-migration.d.ts.map +1 -0
- package/dist/src/migrations/plan-migration.js +256 -0
- package/dist/src/migrations/plan-migration.js.map +1 -0
- package/dist/src/migrations/stub.d.ts +55 -0
- package/dist/src/migrations/stub.d.ts.map +1 -0
- package/dist/src/migrations/stub.js +201 -0
- package/dist/src/migrations/stub.js.map +1 -0
- package/dist/src/migrations/types.d.ts +297 -0
- package/dist/src/migrations/types.d.ts.map +1 -0
- package/dist/src/migrations/types.js +28 -0
- package/dist/src/migrations/types.js.map +1 -0
- package/dist/src/migrations/verify-provenance.d.ts +46 -0
- package/dist/src/migrations/verify-provenance.d.ts.map +1 -0
- package/dist/src/migrations/verify-provenance.js +158 -0
- package/dist/src/migrations/verify-provenance.js.map +1 -0
- package/dist/src/registry/build-registry.d.ts +65 -0
- package/dist/src/registry/build-registry.d.ts.map +1 -0
- package/dist/src/registry/build-registry.js +172 -0
- package/dist/src/registry/build-registry.js.map +1 -0
- package/dist/src/registry/diff.d.ts +25 -0
- package/dist/src/registry/diff.d.ts.map +1 -0
- package/dist/src/registry/diff.js +497 -0
- package/dist/src/registry/diff.js.map +1 -0
- package/dist/src/registry/handlers/check.d.ts +57 -0
- package/dist/src/registry/handlers/check.d.ts.map +1 -0
- package/dist/src/registry/handlers/check.js +181 -0
- package/dist/src/registry/handlers/check.js.map +1 -0
- package/dist/src/registry/handlers/diff.d.ts +33 -0
- package/dist/src/registry/handlers/diff.d.ts.map +1 -0
- package/dist/src/registry/handlers/diff.js +61 -0
- package/dist/src/registry/handlers/diff.js.map +1 -0
- package/dist/src/registry/handlers/generate.d.ts +87 -0
- package/dist/src/registry/handlers/generate.d.ts.map +1 -0
- package/dist/src/registry/handlers/generate.js +223 -0
- package/dist/src/registry/handlers/generate.js.map +1 -0
- package/dist/src/registry/handlers/list.d.ts +36 -0
- package/dist/src/registry/handlers/list.d.ts.map +1 -0
- package/dist/src/registry/handlers/list.js +84 -0
- package/dist/src/registry/handlers/list.js.map +1 -0
- package/dist/src/registry/parse-provenance.d.ts +63 -0
- package/dist/src/registry/parse-provenance.d.ts.map +1 -0
- package/dist/src/registry/parse-provenance.js +182 -0
- package/dist/src/registry/parse-provenance.js.map +1 -0
- package/dist/src/registry/source-hash.d.ts +28 -0
- package/dist/src/registry/source-hash.d.ts.map +1 -0
- package/dist/src/registry/source-hash.js +32 -0
- package/dist/src/registry/source-hash.js.map +1 -0
- package/dist/src/registry/types.d.ts +185 -0
- package/dist/src/registry/types.d.ts.map +1 -0
- package/dist/src/registry/types.js +22 -0
- package/dist/src/registry/types.js.map +1 -0
- package/dist/src/runtime/compile.d.ts +38 -0
- package/dist/src/runtime/compile.d.ts.map +1 -0
- package/dist/src/runtime/compile.js +45 -0
- package/dist/src/runtime/compile.js.map +1 -0
- package/dist/src/runtime/errors.d.ts +25 -0
- package/dist/src/runtime/errors.d.ts.map +1 -0
- package/dist/src/runtime/errors.js +43 -0
- package/dist/src/runtime/errors.js.map +1 -0
- package/dist/src/runtime/normalize-issues.d.ts +65 -0
- package/dist/src/runtime/normalize-issues.d.ts.map +1 -0
- package/dist/src/runtime/normalize-issues.js +208 -0
- package/dist/src/runtime/normalize-issues.js.map +1 -0
- package/dist/src/runtime/parse.d.ts +62 -0
- package/dist/src/runtime/parse.d.ts.map +1 -0
- package/dist/src/runtime/parse.js +107 -0
- package/dist/src/runtime/parse.js.map +1 -0
- package/dist/src/runtime/strip-defaults.d.ts +51 -0
- package/dist/src/runtime/strip-defaults.d.ts.map +1 -0
- package/dist/src/runtime/strip-defaults.js +81 -0
- package/dist/src/runtime/strip-defaults.js.map +1 -0
- package/dist/src/runtime/zod-compile.d.ts +27 -0
- package/dist/src/runtime/zod-compile.d.ts.map +1 -0
- package/dist/src/runtime/zod-compile.js +92 -0
- package/dist/src/runtime/zod-compile.js.map +1 -0
- package/dist/src/types.d.ts +116 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/docs/ABSENCE_SEMANTICS.md +37 -0
- package/docs/BENCHMARKS.md +64 -0
- package/docs/COMPOSITION.md +206 -0
- package/docs/DIFF_CLASSIFICATION.md +137 -0
- package/docs/EXAMPLES.md +221 -0
- package/docs/HEADER_FORMAT.md +66 -0
- package/docs/INVARIANTS.md +58 -0
- package/docs/IR_CONTRACT.md +67 -0
- package/docs/ISSUE_CODES.md +99 -0
- package/docs/JSON_SCHEMA_MAPPING.md +149 -0
- package/docs/MIGRATIONS.md +406 -0
- package/docs/MIGRATION_GUIDE.md +150 -0
- package/docs/OPENAPI_MAPPING.md +66 -0
- package/docs/REGISTRY.md +336 -0
- package/docs/RUNTIME.md +279 -0
- package/docs/SCOPE.md +119 -0
- package/docs/USAGE.md +376 -0
- package/docs/ZOD_MODIFIER_ORDERING.md +77 -0
- package/package.json +45 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cached IR → Zod compiler (Decision #7 of v0.6 plan).
|
|
3
|
+
*
|
|
4
|
+
* The runtime entry points (`parse` / `safeParse` / `validate`, landing
|
|
5
|
+
* in later commits) call `compile(node)` to obtain a live `ZodTypeAny`.
|
|
6
|
+
* Repeated calls with the **same** `SchemaNode` instance return the
|
|
7
|
+
* **same** compiled Zod value — built once, reused thereafter.
|
|
8
|
+
*
|
|
9
|
+
* Cache key is `SchemaNode` *identity*, not IR equality. Two builder
|
|
10
|
+
* outputs with byte-identical IR but different instance identity are
|
|
11
|
+
* NOT shared (per Decision #7); explicit dedup via `irHash` (v0.2)
|
|
12
|
+
* remains a v0.7 registry concern, not a runtime one. The IR is frozen
|
|
13
|
+
* by the builder, so storing the live Zod schema next to its key is
|
|
14
|
+
* safe — the IR cannot mutate out from under the cached value.
|
|
15
|
+
*
|
|
16
|
+
* Compile is lazy on first call (Decision #9). Schemas that are
|
|
17
|
+
* defined-but-never-validated never build their Zod schema.
|
|
18
|
+
*
|
|
19
|
+
* The `WeakMap` lets the entire `(node, compiled)` pair be GC'd when
|
|
20
|
+
* the consumer drops its reference to the schema. Long-running
|
|
21
|
+
* processes that build per-request schemas (anti-pattern, but possible)
|
|
22
|
+
* therefore don't leak.
|
|
23
|
+
*
|
|
24
|
+
* Concurrency: Node is single-threaded, so first-call wins by default
|
|
25
|
+
* and there is no race. A future worker-threads consumer that shares a
|
|
26
|
+
* `SchemaNode` across threads would get a per-thread cache; that
|
|
27
|
+
* trade-off is documented in `docs/RUNTIME.md` (step 9). No v0.6
|
|
28
|
+
* mitigation.
|
|
29
|
+
*/
|
|
30
|
+
import type { ZodTypeAny } from "zod";
|
|
31
|
+
import type { SchemaNode } from "../ir/nodes.js";
|
|
32
|
+
/**
|
|
33
|
+
* Return the compiled Zod schema for `node`, building (and caching)
|
|
34
|
+
* it on the first call. Subsequent calls with the same `SchemaNode`
|
|
35
|
+
* instance return the same `ZodTypeAny` reference.
|
|
36
|
+
*/
|
|
37
|
+
export declare function compile(node: SchemaNode): ZodTypeAny;
|
|
38
|
+
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/runtime/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAKjD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAMpD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cached IR → Zod compiler (Decision #7 of v0.6 plan).
|
|
3
|
+
*
|
|
4
|
+
* The runtime entry points (`parse` / `safeParse` / `validate`, landing
|
|
5
|
+
* in later commits) call `compile(node)` to obtain a live `ZodTypeAny`.
|
|
6
|
+
* Repeated calls with the **same** `SchemaNode` instance return the
|
|
7
|
+
* **same** compiled Zod value — built once, reused thereafter.
|
|
8
|
+
*
|
|
9
|
+
* Cache key is `SchemaNode` *identity*, not IR equality. Two builder
|
|
10
|
+
* outputs with byte-identical IR but different instance identity are
|
|
11
|
+
* NOT shared (per Decision #7); explicit dedup via `irHash` (v0.2)
|
|
12
|
+
* remains a v0.7 registry concern, not a runtime one. The IR is frozen
|
|
13
|
+
* by the builder, so storing the live Zod schema next to its key is
|
|
14
|
+
* safe — the IR cannot mutate out from under the cached value.
|
|
15
|
+
*
|
|
16
|
+
* Compile is lazy on first call (Decision #9). Schemas that are
|
|
17
|
+
* defined-but-never-validated never build their Zod schema.
|
|
18
|
+
*
|
|
19
|
+
* The `WeakMap` lets the entire `(node, compiled)` pair be GC'd when
|
|
20
|
+
* the consumer drops its reference to the schema. Long-running
|
|
21
|
+
* processes that build per-request schemas (anti-pattern, but possible)
|
|
22
|
+
* therefore don't leak.
|
|
23
|
+
*
|
|
24
|
+
* Concurrency: Node is single-threaded, so first-call wins by default
|
|
25
|
+
* and there is no race. A future worker-threads consumer that shares a
|
|
26
|
+
* `SchemaNode` across threads would get a per-thread cache; that
|
|
27
|
+
* trade-off is documented in `docs/RUNTIME.md` (step 9). No v0.6
|
|
28
|
+
* mitigation.
|
|
29
|
+
*/
|
|
30
|
+
import { compileZodSchema } from "./zod-compile.js";
|
|
31
|
+
const cache = new WeakMap();
|
|
32
|
+
/**
|
|
33
|
+
* Return the compiled Zod schema for `node`, building (and caching)
|
|
34
|
+
* it on the first call. Subsequent calls with the same `SchemaNode`
|
|
35
|
+
* instance return the same `ZodTypeAny` reference.
|
|
36
|
+
*/
|
|
37
|
+
export function compile(node) {
|
|
38
|
+
const cached = cache.get(node);
|
|
39
|
+
if (cached !== undefined)
|
|
40
|
+
return cached;
|
|
41
|
+
const built = compileZodSchema(node);
|
|
42
|
+
cache.set(node, built);
|
|
43
|
+
return built;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../src/runtime/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,KAAK,GAAG,IAAI,OAAO,EAA0B,CAAC;AAEpD;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,IAAgB;IACtC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ParseError` — thrown by `parse(schema, input)` when validation
|
|
3
|
+
* fails. Carries the full normalized `Issue` list so handlers can
|
|
4
|
+
* `catch (e) { if (e instanceof ParseError) ... }` and inspect every
|
|
5
|
+
* issue without re-running the parse.
|
|
6
|
+
*
|
|
7
|
+
* `safeParse` and `validate` do NOT throw this — they return a
|
|
8
|
+
* `Result<...>`. The throw exists for the parse path because that's
|
|
9
|
+
* the friction-causing default: code that doesn't explicitly want to
|
|
10
|
+
* handle issues should get loud failure, not silent `undefined`.
|
|
11
|
+
*
|
|
12
|
+
* The `code` field is stable for switching (`"parse_failed"`); tests
|
|
13
|
+
* assert on `code` / `name` / `issues` / `instanceof`, never on the
|
|
14
|
+
* human-readable `message`.
|
|
15
|
+
*
|
|
16
|
+
* Internal-only at this step. The `parse` entry point lands in step 6;
|
|
17
|
+
* the public `src/index.ts` re-export of `ParseError` lands in step 13.
|
|
18
|
+
*/
|
|
19
|
+
import type { Issue } from "../errors/issue.js";
|
|
20
|
+
export declare class ParseError extends Error {
|
|
21
|
+
readonly code: "parse_failed";
|
|
22
|
+
readonly issues: readonly Issue[];
|
|
23
|
+
constructor(issues: readonly Issue[], message?: string);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/runtime/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAU;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;gBAEtB,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM;CASvD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ParseError` — thrown by `parse(schema, input)` when validation
|
|
3
|
+
* fails. Carries the full normalized `Issue` list so handlers can
|
|
4
|
+
* `catch (e) { if (e instanceof ParseError) ... }` and inspect every
|
|
5
|
+
* issue without re-running the parse.
|
|
6
|
+
*
|
|
7
|
+
* `safeParse` and `validate` do NOT throw this — they return a
|
|
8
|
+
* `Result<...>`. The throw exists for the parse path because that's
|
|
9
|
+
* the friction-causing default: code that doesn't explicitly want to
|
|
10
|
+
* handle issues should get loud failure, not silent `undefined`.
|
|
11
|
+
*
|
|
12
|
+
* The `code` field is stable for switching (`"parse_failed"`); tests
|
|
13
|
+
* assert on `code` / `name` / `issues` / `instanceof`, never on the
|
|
14
|
+
* human-readable `message`.
|
|
15
|
+
*
|
|
16
|
+
* Internal-only at this step. The `parse` entry point lands in step 6;
|
|
17
|
+
* the public `src/index.ts` re-export of `ParseError` lands in step 13.
|
|
18
|
+
*/
|
|
19
|
+
export class ParseError extends Error {
|
|
20
|
+
code = "parse_failed";
|
|
21
|
+
issues;
|
|
22
|
+
constructor(issues, message) {
|
|
23
|
+
super(message ?? defaultMessage(issues));
|
|
24
|
+
this.name = "ParseError";
|
|
25
|
+
// Defensive copy — callers may mutate the array they passed in
|
|
26
|
+
// (rare, but a `safeParse` implementation that batches issues in
|
|
27
|
+
// a working array would otherwise leak that mutability into the
|
|
28
|
+
// thrown error). Storing a frozen copy keeps the contract crisp.
|
|
29
|
+
this.issues = Object.freeze(issues.slice());
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function defaultMessage(issues) {
|
|
33
|
+
// Stable enough for humans without being something tests assert on.
|
|
34
|
+
// The leading count gives a quick signal in logs; the first path /
|
|
35
|
+
// code pair points the reader at the most relevant issue.
|
|
36
|
+
const head = issues[0];
|
|
37
|
+
if (head === undefined)
|
|
38
|
+
return "Parse failed (no issues)";
|
|
39
|
+
const where = head.path.length > 0 ? head.path.join(".") : "<root>";
|
|
40
|
+
const extra = issues.length > 1 ? ` (+${issues.length - 1} more)` : "";
|
|
41
|
+
return `Parse failed: ${head.code} at ${where}${extra}`;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/runtime/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,GAAG,cAAuB,CAAC;IAC/B,MAAM,CAAmB;IAElC,YAAY,MAAwB,EAAE,OAAgB;QACpD,KAAK,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,+DAA+D;QAC/D,iEAAiE;QACjE,gEAAgE;QAChE,iEAAiE;QACjE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9C,CAAC;CACF;AAED,SAAS,cAAc,CAAC,MAAwB;IAC9C,oEAAoE;IACpE,mEAAmE;IACnE,0DAA0D;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,0BAA0B,CAAC;IAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,OAAO,iBAAiB,IAAI,CAAC,IAAI,OAAO,KAAK,GAAG,KAAK,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZodError → readonly Issue[] normalization (Decision #12 of v0.6 plan).
|
|
3
|
+
*
|
|
4
|
+
* This is the contract layer between Zod's internal error vocabulary
|
|
5
|
+
* and NekoStack's stable, machine-readable `IssueCode` set. Downstream
|
|
6
|
+
* consumers (form display, API responses, admin diagnostics) read
|
|
7
|
+
* `Issue` only — they never see a `ZodError`. Per the "engine
|
|
8
|
+
* swap-safe" invariant added in v0.6: replacing the runtime engine
|
|
9
|
+
* later must be a no-op for those consumers, so this mapping is the
|
|
10
|
+
* load-bearing translation.
|
|
11
|
+
*
|
|
12
|
+
* **Mapping table (Decision #12, locked).**
|
|
13
|
+
*
|
|
14
|
+
* invalid_type (received: undefined, expected != undefined) → missing_required
|
|
15
|
+
* invalid_type (other) → invalid_type
|
|
16
|
+
* unrecognized_keys → one unknown_key per key
|
|
17
|
+
* invalid_literal → invalid_literal
|
|
18
|
+
* invalid_enum_value → invalid_enum
|
|
19
|
+
* invalid_union → invalid_union
|
|
20
|
+
* invalid_union_discriminator → invalid_union (folded;
|
|
21
|
+
* no v0.6 public surface)
|
|
22
|
+
* invalid_arguments / invalid_return_type → invalid_type (function
|
|
23
|
+
* schemas not in v0.6
|
|
24
|
+
* scope; metadata carries
|
|
25
|
+
* the original code)
|
|
26
|
+
* too_small → too_small
|
|
27
|
+
* too_big → too_big
|
|
28
|
+
* invalid_string → invalid_format
|
|
29
|
+
* invalid_date → invalid_type (DateNode
|
|
30
|
+
* has no v0.6 builder)
|
|
31
|
+
* custom → custom_refinement_failed
|
|
32
|
+
* anything not listed → custom_refinement_failed
|
|
33
|
+
* (+ metadata.source="zod",
|
|
34
|
+
* metadata.zodCode=<orig>)
|
|
35
|
+
*
|
|
36
|
+
* The fallback row exists so adding a new Zod code in a future Zod
|
|
37
|
+
* release does not crash the normalizer; the original code is
|
|
38
|
+
* preserved on `metadata.zodCode` for traceability.
|
|
39
|
+
*
|
|
40
|
+
* **Preserved verbatim.** `path`, `message`, `expected`, `received`
|
|
41
|
+
* come straight from Zod (no re-serialization). `schemaId` /
|
|
42
|
+
* `schemaVersion` come from `schema.metadata` when present.
|
|
43
|
+
* `severity` is always `"error"` in v0.6.
|
|
44
|
+
*
|
|
45
|
+
* Internal-only. Not exported from `src/index.ts` — the public
|
|
46
|
+
* surface ships `Issue` / `IssueCode` / `Result` (already in v0.1).
|
|
47
|
+
*/
|
|
48
|
+
import type { ZodError } from "zod";
|
|
49
|
+
import type { SchemaNode } from "../ir/nodes.js";
|
|
50
|
+
import type { Issue } from "../errors/issue.js";
|
|
51
|
+
/**
|
|
52
|
+
* Normalize a `ZodError` into the NekoStack issue vocabulary.
|
|
53
|
+
*
|
|
54
|
+
* `schema` is the top-level `SchemaNode` whose validation produced
|
|
55
|
+
* the error. Its `metadata.id` / `metadata.version` (when present)
|
|
56
|
+
* are stamped on every emitted issue so consumers can route by
|
|
57
|
+
* schema without re-correlating.
|
|
58
|
+
*
|
|
59
|
+
* `unrecognized_keys` is expanded into one `unknown_key` issue per
|
|
60
|
+
* offending key — Zod batches the keys on a single issue, but the
|
|
61
|
+
* NekoStack contract is one issue per key so downstream UIs render
|
|
62
|
+
* cleanly.
|
|
63
|
+
*/
|
|
64
|
+
export declare function normalizeIssues(error: ZodError, schema: SchemaNode): readonly Issue[];
|
|
65
|
+
//# sourceMappingURL=normalize-issues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-issues.d.ts","sourceRoot":"","sources":["../../../src/runtime/normalize-issues.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,KAAK,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,UAAU,GACjB,SAAS,KAAK,EAAE,CAQlB"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZodError → readonly Issue[] normalization (Decision #12 of v0.6 plan).
|
|
3
|
+
*
|
|
4
|
+
* This is the contract layer between Zod's internal error vocabulary
|
|
5
|
+
* and NekoStack's stable, machine-readable `IssueCode` set. Downstream
|
|
6
|
+
* consumers (form display, API responses, admin diagnostics) read
|
|
7
|
+
* `Issue` only — they never see a `ZodError`. Per the "engine
|
|
8
|
+
* swap-safe" invariant added in v0.6: replacing the runtime engine
|
|
9
|
+
* later must be a no-op for those consumers, so this mapping is the
|
|
10
|
+
* load-bearing translation.
|
|
11
|
+
*
|
|
12
|
+
* **Mapping table (Decision #12, locked).**
|
|
13
|
+
*
|
|
14
|
+
* invalid_type (received: undefined, expected != undefined) → missing_required
|
|
15
|
+
* invalid_type (other) → invalid_type
|
|
16
|
+
* unrecognized_keys → one unknown_key per key
|
|
17
|
+
* invalid_literal → invalid_literal
|
|
18
|
+
* invalid_enum_value → invalid_enum
|
|
19
|
+
* invalid_union → invalid_union
|
|
20
|
+
* invalid_union_discriminator → invalid_union (folded;
|
|
21
|
+
* no v0.6 public surface)
|
|
22
|
+
* invalid_arguments / invalid_return_type → invalid_type (function
|
|
23
|
+
* schemas not in v0.6
|
|
24
|
+
* scope; metadata carries
|
|
25
|
+
* the original code)
|
|
26
|
+
* too_small → too_small
|
|
27
|
+
* too_big → too_big
|
|
28
|
+
* invalid_string → invalid_format
|
|
29
|
+
* invalid_date → invalid_type (DateNode
|
|
30
|
+
* has no v0.6 builder)
|
|
31
|
+
* custom → custom_refinement_failed
|
|
32
|
+
* anything not listed → custom_refinement_failed
|
|
33
|
+
* (+ metadata.source="zod",
|
|
34
|
+
* metadata.zodCode=<orig>)
|
|
35
|
+
*
|
|
36
|
+
* The fallback row exists so adding a new Zod code in a future Zod
|
|
37
|
+
* release does not crash the normalizer; the original code is
|
|
38
|
+
* preserved on `metadata.zodCode` for traceability.
|
|
39
|
+
*
|
|
40
|
+
* **Preserved verbatim.** `path`, `message`, `expected`, `received`
|
|
41
|
+
* come straight from Zod (no re-serialization). `schemaId` /
|
|
42
|
+
* `schemaVersion` come from `schema.metadata` when present.
|
|
43
|
+
* `severity` is always `"error"` in v0.6.
|
|
44
|
+
*
|
|
45
|
+
* Internal-only. Not exported from `src/index.ts` — the public
|
|
46
|
+
* surface ships `Issue` / `IssueCode` / `Result` (already in v0.1).
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Normalize a `ZodError` into the NekoStack issue vocabulary.
|
|
50
|
+
*
|
|
51
|
+
* `schema` is the top-level `SchemaNode` whose validation produced
|
|
52
|
+
* the error. Its `metadata.id` / `metadata.version` (when present)
|
|
53
|
+
* are stamped on every emitted issue so consumers can route by
|
|
54
|
+
* schema without re-correlating.
|
|
55
|
+
*
|
|
56
|
+
* `unrecognized_keys` is expanded into one `unknown_key` issue per
|
|
57
|
+
* offending key — Zod batches the keys on a single issue, but the
|
|
58
|
+
* NekoStack contract is one issue per key so downstream UIs render
|
|
59
|
+
* cleanly.
|
|
60
|
+
*/
|
|
61
|
+
export function normalizeIssues(error, schema) {
|
|
62
|
+
const schemaId = schema.metadata?.id;
|
|
63
|
+
const schemaVersion = schema.metadata?.version;
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const zi of error.issues) {
|
|
66
|
+
appendNormalized(out, zi, schemaId, schemaVersion);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
function appendNormalized(out, zi, schemaId, schemaVersion) {
|
|
71
|
+
const base = {
|
|
72
|
+
path: zi.path.slice(),
|
|
73
|
+
message: zi.message,
|
|
74
|
+
severity: "error",
|
|
75
|
+
...(schemaId !== undefined ? { schemaId } : {}),
|
|
76
|
+
...(schemaVersion !== undefined ? { schemaVersion } : {}),
|
|
77
|
+
};
|
|
78
|
+
switch (zi.code) {
|
|
79
|
+
case "invalid_type": {
|
|
80
|
+
// "field is absent" beats "field has wrong type": Zod reports
|
|
81
|
+
// a missing object property as invalid_type / received="undefined",
|
|
82
|
+
// but the consumer-facing distinction is whether the value was
|
|
83
|
+
// there at all. See Decision #12 first row.
|
|
84
|
+
const isMissing = zi.received === "undefined" && zi.expected !== "undefined";
|
|
85
|
+
out.push({
|
|
86
|
+
...base,
|
|
87
|
+
code: isMissing ? "missing_required" : "invalid_type",
|
|
88
|
+
expected: zi.expected,
|
|
89
|
+
received: zi.received,
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
case "invalid_literal": {
|
|
94
|
+
out.push({
|
|
95
|
+
...base,
|
|
96
|
+
code: "invalid_literal",
|
|
97
|
+
expected: zi.expected,
|
|
98
|
+
received: zi.received,
|
|
99
|
+
});
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
case "unrecognized_keys": {
|
|
103
|
+
// Zod batches all offending keys on a single issue; the
|
|
104
|
+
// NekoStack contract emits one issue per key so a UI can
|
|
105
|
+
// highlight each field independently.
|
|
106
|
+
for (const key of zi.keys) {
|
|
107
|
+
out.push({
|
|
108
|
+
...base,
|
|
109
|
+
path: [...zi.path, key],
|
|
110
|
+
code: "unknown_key",
|
|
111
|
+
received: key,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
case "invalid_enum_value": {
|
|
117
|
+
out.push({
|
|
118
|
+
...base,
|
|
119
|
+
code: "invalid_enum",
|
|
120
|
+
expected: zi.options,
|
|
121
|
+
received: zi.received,
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
case "invalid_union":
|
|
126
|
+
case "invalid_union_discriminator": {
|
|
127
|
+
// Folded — v0.6 has no public discriminated-union surface.
|
|
128
|
+
out.push({ ...base, code: "invalid_union" });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
case "invalid_arguments":
|
|
132
|
+
case "invalid_return_type": {
|
|
133
|
+
// Function schemas are not in v0.6 scope. If Zod somehow emits
|
|
134
|
+
// these (e.g., a downstream hand-written schema), surface as
|
|
135
|
+
// invalid_type with the original code on metadata for triage.
|
|
136
|
+
out.push({
|
|
137
|
+
...base,
|
|
138
|
+
code: "invalid_type",
|
|
139
|
+
metadata: { source: "zod", zodCode: zi.code },
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
case "too_small": {
|
|
144
|
+
out.push({
|
|
145
|
+
...base,
|
|
146
|
+
code: "too_small",
|
|
147
|
+
metadata: {
|
|
148
|
+
minimum: zi.minimum,
|
|
149
|
+
inclusive: zi.inclusive,
|
|
150
|
+
...(zi.exact !== undefined ? { exact: zi.exact } : {}),
|
|
151
|
+
type: zi.type,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
case "too_big": {
|
|
157
|
+
out.push({
|
|
158
|
+
...base,
|
|
159
|
+
code: "too_big",
|
|
160
|
+
metadata: {
|
|
161
|
+
maximum: zi.maximum,
|
|
162
|
+
inclusive: zi.inclusive,
|
|
163
|
+
...(zi.exact !== undefined ? { exact: zi.exact } : {}),
|
|
164
|
+
type: zi.type,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
case "invalid_string": {
|
|
170
|
+
// email / url / uuid / regex / etc. all collapse to invalid_format;
|
|
171
|
+
// the specific validator name is preserved on metadata for UIs
|
|
172
|
+
// that want to render a tailored hint.
|
|
173
|
+
out.push({
|
|
174
|
+
...base,
|
|
175
|
+
code: "invalid_format",
|
|
176
|
+
metadata: { validation: zi.validation },
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
case "invalid_date": {
|
|
181
|
+
// DateNode has no v0.6 builder; fall through to invalid_type per
|
|
182
|
+
// the locked table.
|
|
183
|
+
out.push({ ...base, code: "invalid_type" });
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
case "custom": {
|
|
187
|
+
out.push({ ...base, code: "custom_refinement_failed" });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
default: {
|
|
191
|
+
// Fallback (round-2 amendment to Decision #12): any code we
|
|
192
|
+
// do not explicitly map — `invalid_intersection_types`,
|
|
193
|
+
// `not_multiple_of`, `not_finite`, or any future Zod code —
|
|
194
|
+
// surfaces as `custom_refinement_failed` while preserving the
|
|
195
|
+
// original code on `metadata.zodCode` so it is recoverable
|
|
196
|
+
// downstream. `metadata.source = "zod"` is the discriminator
|
|
197
|
+
// consumers key off to decide whether to trust the field.
|
|
198
|
+
const code = zi.code ?? "unknown";
|
|
199
|
+
out.push({
|
|
200
|
+
...base,
|
|
201
|
+
code: "custom_refinement_failed",
|
|
202
|
+
metadata: { source: "zod", zodCode: code },
|
|
203
|
+
});
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=normalize-issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-issues.js","sourceRoot":"","sources":["../../../src/runtime/normalize-issues.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime API entry points (Step 6 of v0.6 plan).
|
|
3
|
+
*
|
|
4
|
+
* Wires together the Decision #6 value consumer, the Decision #7
|
|
5
|
+
* compile cache, the Decision #8 validate-only variant, the
|
|
6
|
+
* Decision #12 issue normalizer, and `ParseError`.
|
|
7
|
+
*
|
|
8
|
+
* **Three entry points, one engine.**
|
|
9
|
+
*
|
|
10
|
+
* parse(schema, input) -> s.output<S> | throws ParseError
|
|
11
|
+
* safeParse(schema, input) -> Result<s.output<S>>
|
|
12
|
+
* validate(schema, input) -> Result<s.input<S>>
|
|
13
|
+
*
|
|
14
|
+
* `parse` is the friction-causing default — code that doesn't
|
|
15
|
+
* explicitly want to handle issues gets loud failure. `safeParse` is
|
|
16
|
+
* the Result-returning alternative for callers that branch on
|
|
17
|
+
* success/failure. `validate` is the structural check that does NOT
|
|
18
|
+
* apply defaults or transforms — see Decision #8 for the absence-
|
|
19
|
+
* semantics rationale.
|
|
20
|
+
*
|
|
21
|
+
* **Validate-variant cache.** `stripDefaultsForValidate(node)` returns
|
|
22
|
+
* a new tree each call, which would defeat the Step 2 compile cache
|
|
23
|
+
* (the cache keys on `SchemaNode` identity). To keep validate paths
|
|
24
|
+
* cache-friendly, we memoize the stripped variant by original-node
|
|
25
|
+
* identity here. Subsequent `validate(schema, ...)` calls reuse the
|
|
26
|
+
* same variant `SchemaNode` and therefore the same compiled Zod
|
|
27
|
+
* schema.
|
|
28
|
+
*
|
|
29
|
+
* **Issue normalization.** Every failure path runs through
|
|
30
|
+
* `normalizeIssues(error, schema.node)`. We pass the *original*
|
|
31
|
+
* schema node — not the validate variant — so `schemaId` /
|
|
32
|
+
* `schemaVersion` come from the consumer's source-of-truth metadata,
|
|
33
|
+
* regardless of which compile path produced the failure.
|
|
34
|
+
*
|
|
35
|
+
* Internal-only at this step. Public re-exports of `parse` /
|
|
36
|
+
* `safeParse` / `validate` / `ParseError` land in step 13.
|
|
37
|
+
*/
|
|
38
|
+
import type { AnySchema } from "../builders/schema.js";
|
|
39
|
+
import type { Input, Output } from "../types.js";
|
|
40
|
+
import type { Result } from "../errors/issue.js";
|
|
41
|
+
/**
|
|
42
|
+
* Parse `input` against `schema`. Returns the output shape (defaults
|
|
43
|
+
* applied, transforms run) on success; throws `ParseError` with the
|
|
44
|
+
* full normalized issue list on failure.
|
|
45
|
+
*/
|
|
46
|
+
export declare function parse<S extends AnySchema>(schema: S, input: unknown): Output<S>;
|
|
47
|
+
/**
|
|
48
|
+
* Like `parse`, but returns a `Result` rather than throwing. Use
|
|
49
|
+
* when the caller wants to branch on success/failure inline.
|
|
50
|
+
*/
|
|
51
|
+
export declare function safeParse<S extends AnySchema>(schema: S, input: unknown): Result<Output<S>>;
|
|
52
|
+
/**
|
|
53
|
+
* Structural validation. Compiles against the validate-only IR
|
|
54
|
+
* variant (defaults stripped, default-bearing fields flipped to
|
|
55
|
+
* optional per Decision #8). Returns `Result<s.input<S>>` — defaults
|
|
56
|
+
* are NOT filled, transforms are NOT run.
|
|
57
|
+
*
|
|
58
|
+
* Use when the caller wants to know whether the input would parse,
|
|
59
|
+
* without paying for transforms or accepting a default-filled output.
|
|
60
|
+
*/
|
|
61
|
+
export declare function validate<S extends AnySchema>(schema: S, input: unknown): Result<Input<S>>;
|
|
62
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/runtime/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAqBjD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,SAAS,EACvC,MAAM,EAAE,CAAC,EACT,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,CAAC,CAAC,CAKX;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,SAAS,EAC3C,MAAM,EAAE,CAAC,EACT,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAUnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,EAC1C,MAAM,EAAE,CAAC,EACT,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAclB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime API entry points (Step 6 of v0.6 plan).
|
|
3
|
+
*
|
|
4
|
+
* Wires together the Decision #6 value consumer, the Decision #7
|
|
5
|
+
* compile cache, the Decision #8 validate-only variant, the
|
|
6
|
+
* Decision #12 issue normalizer, and `ParseError`.
|
|
7
|
+
*
|
|
8
|
+
* **Three entry points, one engine.**
|
|
9
|
+
*
|
|
10
|
+
* parse(schema, input) -> s.output<S> | throws ParseError
|
|
11
|
+
* safeParse(schema, input) -> Result<s.output<S>>
|
|
12
|
+
* validate(schema, input) -> Result<s.input<S>>
|
|
13
|
+
*
|
|
14
|
+
* `parse` is the friction-causing default — code that doesn't
|
|
15
|
+
* explicitly want to handle issues gets loud failure. `safeParse` is
|
|
16
|
+
* the Result-returning alternative for callers that branch on
|
|
17
|
+
* success/failure. `validate` is the structural check that does NOT
|
|
18
|
+
* apply defaults or transforms — see Decision #8 for the absence-
|
|
19
|
+
* semantics rationale.
|
|
20
|
+
*
|
|
21
|
+
* **Validate-variant cache.** `stripDefaultsForValidate(node)` returns
|
|
22
|
+
* a new tree each call, which would defeat the Step 2 compile cache
|
|
23
|
+
* (the cache keys on `SchemaNode` identity). To keep validate paths
|
|
24
|
+
* cache-friendly, we memoize the stripped variant by original-node
|
|
25
|
+
* identity here. Subsequent `validate(schema, ...)` calls reuse the
|
|
26
|
+
* same variant `SchemaNode` and therefore the same compiled Zod
|
|
27
|
+
* schema.
|
|
28
|
+
*
|
|
29
|
+
* **Issue normalization.** Every failure path runs through
|
|
30
|
+
* `normalizeIssues(error, schema.node)`. We pass the *original*
|
|
31
|
+
* schema node — not the validate variant — so `schemaId` /
|
|
32
|
+
* `schemaVersion` come from the consumer's source-of-truth metadata,
|
|
33
|
+
* regardless of which compile path produced the failure.
|
|
34
|
+
*
|
|
35
|
+
* Internal-only at this step. Public re-exports of `parse` /
|
|
36
|
+
* `safeParse` / `validate` / `ParseError` land in step 13.
|
|
37
|
+
*/
|
|
38
|
+
import { compile } from "./compile.js";
|
|
39
|
+
import { stripDefaultsForValidate } from "./strip-defaults.js";
|
|
40
|
+
import { normalizeIssues } from "./normalize-issues.js";
|
|
41
|
+
import { ParseError } from "./errors.js";
|
|
42
|
+
/**
|
|
43
|
+
* Memoize the validate-only variant by original `SchemaNode` identity.
|
|
44
|
+
* Without this, `validate(sameSchema, ...)` would rebuild the
|
|
45
|
+
* stripped tree on every call and miss the Step 2 compile cache.
|
|
46
|
+
*/
|
|
47
|
+
const validateNodeCache = new WeakMap();
|
|
48
|
+
function getValidateNode(node) {
|
|
49
|
+
const cached = validateNodeCache.get(node);
|
|
50
|
+
if (cached !== undefined)
|
|
51
|
+
return cached;
|
|
52
|
+
const variant = stripDefaultsForValidate(node);
|
|
53
|
+
validateNodeCache.set(node, variant);
|
|
54
|
+
return variant;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse `input` against `schema`. Returns the output shape (defaults
|
|
58
|
+
* applied, transforms run) on success; throws `ParseError` with the
|
|
59
|
+
* full normalized issue list on failure.
|
|
60
|
+
*/
|
|
61
|
+
export function parse(schema, input) {
|
|
62
|
+
const zod = compile(schema.node);
|
|
63
|
+
const result = zod.safeParse(input);
|
|
64
|
+
if (result.success)
|
|
65
|
+
return result.data;
|
|
66
|
+
throw new ParseError(normalizeIssues(result.error, schema.node));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Like `parse`, but returns a `Result` rather than throwing. Use
|
|
70
|
+
* when the caller wants to branch on success/failure inline.
|
|
71
|
+
*/
|
|
72
|
+
export function safeParse(schema, input) {
|
|
73
|
+
const zod = compile(schema.node);
|
|
74
|
+
const result = zod.safeParse(input);
|
|
75
|
+
if (result.success) {
|
|
76
|
+
return { success: true, data: result.data };
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
issues: normalizeIssues(result.error, schema.node),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Structural validation. Compiles against the validate-only IR
|
|
85
|
+
* variant (defaults stripped, default-bearing fields flipped to
|
|
86
|
+
* optional per Decision #8). Returns `Result<s.input<S>>` — defaults
|
|
87
|
+
* are NOT filled, transforms are NOT run.
|
|
88
|
+
*
|
|
89
|
+
* Use when the caller wants to know whether the input would parse,
|
|
90
|
+
* without paying for transforms or accepting a default-filled output.
|
|
91
|
+
*/
|
|
92
|
+
export function validate(schema, input) {
|
|
93
|
+
const variant = getValidateNode(schema.node);
|
|
94
|
+
const zod = compile(variant);
|
|
95
|
+
const result = zod.safeParse(input);
|
|
96
|
+
if (result.success) {
|
|
97
|
+
return { success: true, data: result.data };
|
|
98
|
+
}
|
|
99
|
+
// Pass the *original* schema node so schemaId / schemaVersion come
|
|
100
|
+
// from the user-authored metadata regardless of which compile path
|
|
101
|
+
// (parse or validate) produced the failure.
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
issues: normalizeIssues(result.error, schema.node),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/runtime/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAA0B,CAAC;AAEhE,SAAS,eAAe,CAAC,IAAgB;IACvC,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC/C,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CACnB,MAAS,EACT,KAAc;IAEd,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,IAAiB,CAAC;IACpD,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CACvB,MAAS,EACT,KAAc;IAEd,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAiB,EAAE,CAAC;IAC3D,CAAC;IACD,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC;KACnD,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACtB,MAAS,EACT,KAAc;IAEd,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAgB,EAAE,CAAC;IAC1D,CAAC;IACD,mEAAmE;IACnE,mEAAmE;IACnE,4CAA4C;IAC5C,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC;KACnD,CAAC;AACJ,CAAC"}
|