attaform 0.20.2 → 0.21.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/dist/chunks/dev-key-collision-warnings.cjs +58 -0
- package/dist/chunks/dev-key-collision-warnings.cjs.map +1 -0
- package/dist/chunks/dev-key-collision-warnings.mjs +55 -0
- package/dist/chunks/dev-key-collision-warnings.mjs.map +1 -0
- package/dist/chunks/devtools.cjs +1 -1
- package/dist/chunks/devtools.mjs +1 -1
- package/dist/chunks/fingerprint.cjs +186 -0
- package/dist/chunks/fingerprint.cjs.map +1 -0
- package/dist/chunks/fingerprint.mjs +184 -0
- package/dist/chunks/fingerprint.mjs.map +1 -0
- package/dist/chunks/fingerprint2.cjs +162 -0
- package/dist/chunks/fingerprint2.cjs.map +1 -0
- package/dist/chunks/fingerprint2.mjs +160 -0
- package/dist/chunks/fingerprint2.mjs.map +1 -0
- package/dist/chunks/indexeddb.cjs +1 -1
- package/dist/chunks/indexeddb.mjs +1 -1
- package/dist/chunks/local-storage.cjs +1 -1
- package/dist/chunks/local-storage.mjs +1 -1
- package/dist/chunks/multi-tab-sync.cjs +367 -0
- package/dist/chunks/multi-tab-sync.cjs.map +1 -0
- package/dist/chunks/multi-tab-sync.mjs +364 -0
- package/dist/chunks/multi-tab-sync.mjs.map +1 -0
- package/dist/chunks/session-storage.cjs +1 -1
- package/dist/chunks/session-storage.mjs +1 -1
- package/dist/chunks/wire-persistence.cjs +396 -0
- package/dist/chunks/wire-persistence.cjs.map +1 -0
- package/dist/chunks/wire-persistence.mjs +394 -0
- package/dist/chunks/wire-persistence.mjs.map +1 -0
- package/dist/esbuild.cjs +28 -0
- package/dist/esbuild.cjs.map +1 -0
- package/dist/esbuild.d.cts +56 -0
- package/dist/esbuild.d.mts +56 -0
- package/dist/esbuild.d.ts +56 -0
- package/dist/esbuild.mjs +26 -0
- package/dist/esbuild.mjs.map +1 -0
- package/dist/index.cjs +5 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -70
- package/dist/index.d.mts +65 -70
- package/dist/index.d.ts +65 -70
- package/dist/index.mjs +5 -5
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/rollup.cjs +24 -0
- package/dist/rollup.cjs.map +1 -0
- package/dist/rollup.d.cts +35 -0
- package/dist/rollup.d.mts +35 -0
- package/dist/rollup.d.ts +35 -0
- package/dist/rollup.mjs +22 -0
- package/dist/rollup.mjs.map +1 -0
- package/dist/rspack.cjs +10 -0
- package/dist/rspack.cjs.map +1 -0
- package/dist/rspack.d.cts +40 -0
- package/dist/rspack.d.mts +40 -0
- package/dist/rspack.d.ts +40 -0
- package/dist/rspack.mjs +8 -0
- package/dist/rspack.mjs.map +1 -0
- package/dist/runtime/plugins/attaform.cjs +2 -2
- package/dist/runtime/plugins/attaform.mjs +2 -2
- package/dist/shared/{attaform.ceGEAEMk.d.ts → attaform.7lzO9pdM.d.mts} +95 -1
- package/dist/shared/{attaform.99cfHcIt.d.cts → attaform.B1nyO4ec.d.cts} +82 -30
- package/dist/shared/{attaform.99cfHcIt.d.mts → attaform.B1nyO4ec.d.mts} +82 -30
- package/dist/shared/{attaform.99cfHcIt.d.ts → attaform.B1nyO4ec.d.ts} +82 -30
- package/dist/shared/{attaform.z5j3LwJz.cjs → attaform.BA3vRDos.cjs} +3 -3
- package/dist/shared/attaform.BA3vRDos.cjs.map +1 -0
- package/dist/shared/{attaform.BXinSW2T.d.mts → attaform.BDIEq9qP.d.cts} +1 -1
- package/dist/shared/attaform.BJGA_UOS.mjs +37 -0
- package/dist/shared/attaform.BJGA_UOS.mjs.map +1 -0
- package/dist/shared/{attaform.DN5CvZrg.d.ts → attaform.BK1RE2ha.d.ts} +1 -1
- package/dist/shared/{attaform.CywE4y8x.d.cts → attaform.BQ6drorq.d.mts} +1 -1
- package/dist/shared/attaform.BRGIpZo4.cjs +26 -0
- package/dist/shared/attaform.BRGIpZo4.cjs.map +1 -0
- package/dist/shared/{attaform.CwLjUqmQ.cjs → attaform.BUszFoKq.cjs} +383 -911
- package/dist/shared/attaform.BUszFoKq.cjs.map +1 -0
- package/dist/shared/{attaform.C5aYC_T8.mjs → attaform.BnK_bfcb.mjs} +39 -392
- package/dist/shared/attaform.BnK_bfcb.mjs.map +1 -0
- package/dist/shared/{attaform.DAKrGhxc.cjs → attaform.BzvOdiSI.cjs} +101 -417
- package/dist/shared/attaform.BzvOdiSI.cjs.map +1 -0
- package/dist/shared/attaform.C3Doa9Pt.mjs +24 -0
- package/dist/shared/attaform.C3Doa9Pt.mjs.map +1 -0
- package/dist/shared/{attaform.D2SCCd4O.cjs → attaform.CEf6wYfD.cjs} +2 -2
- package/dist/shared/{attaform.D2SCCd4O.cjs.map → attaform.CEf6wYfD.cjs.map} +1 -1
- package/dist/shared/attaform.CQN9R62B.cjs +39 -0
- package/dist/shared/attaform.CQN9R62B.cjs.map +1 -0
- package/dist/shared/{attaform.sWm8B15V.d.mts → attaform.CRsXyy-Y.d.ts} +95 -1
- package/dist/shared/{attaform.Dt7dEcHk.mjs → attaform.CkjTapyq.mjs} +89 -405
- package/dist/shared/attaform.CkjTapyq.mjs.map +1 -0
- package/dist/shared/{attaform.tiWEVznj.mjs → attaform.DSqO6Db7.mjs} +372 -912
- package/dist/shared/attaform.DSqO6Db7.mjs.map +1 -0
- package/dist/shared/attaform.DuzQYscR.d.cts +41 -0
- package/dist/shared/attaform.DuzQYscR.d.mts +41 -0
- package/dist/shared/attaform.DuzQYscR.d.ts +41 -0
- package/dist/shared/{attaform.DbRgDFa7.d.cts → attaform.F8LMHHWV.d.cts} +95 -1
- package/dist/shared/attaform.LEWUFqUw.cjs +54 -0
- package/dist/shared/attaform.LEWUFqUw.cjs.map +1 -0
- package/dist/shared/{attaform.Cd4AOfwu.cjs → attaform.PnqML3xW.cjs} +68 -402
- package/dist/shared/attaform.PnqML3xW.cjs.map +1 -0
- package/dist/shared/{attaform.QG5TG8lB.mjs → attaform.Y_Mgg0Yp.mjs} +3 -3
- package/dist/shared/attaform.Y_Mgg0Yp.mjs.map +1 -0
- package/dist/shared/{attaform.B_hph5AE.cjs → attaform._rsCZy2j.cjs} +172 -20
- package/dist/shared/attaform._rsCZy2j.cjs.map +1 -0
- package/dist/shared/{attaform.CnrxbkB6.mjs → attaform.ezb5Nh2t.mjs} +2 -2
- package/dist/shared/{attaform.CnrxbkB6.mjs.map → attaform.ezb5Nh2t.mjs.map} +1 -1
- package/dist/shared/{attaform.BGk8cfw2.mjs → attaform.r3PePkDR.mjs} +172 -21
- package/dist/shared/attaform.r3PePkDR.mjs.map +1 -0
- package/dist/shared/attaform.sHkHv_98.mjs +51 -0
- package/dist/shared/attaform.sHkHv_98.mjs.map +1 -0
- package/dist/vite.cjs +9 -45
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +36 -0
- package/dist/vite.d.mts +36 -0
- package/dist/vite.d.ts +36 -0
- package/dist/vite.mjs +8 -44
- package/dist/vite.mjs.map +1 -1
- package/dist/webpack.cjs +10 -0
- package/dist/webpack.cjs.map +1 -0
- package/dist/webpack.d.cts +37 -0
- package/dist/webpack.d.mts +37 -0
- package/dist/webpack.d.ts +37 -0
- package/dist/webpack.mjs +8 -0
- package/dist/webpack.mjs.map +1 -0
- package/dist/zod-v3.cjs +3 -3
- package/dist/zod-v3.d.cts +3 -3
- package/dist/zod-v3.d.mts +3 -3
- package/dist/zod-v3.d.ts +3 -3
- package/dist/zod-v3.mjs +3 -3
- package/dist/zod-v4.cjs +3 -3
- package/dist/zod-v4.d.cts +4 -4
- package/dist/zod-v4.d.mts +4 -4
- package/dist/zod-v4.d.ts +4 -4
- package/dist/zod-v4.mjs +3 -3
- package/dist/zod.cjs +8 -8
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +5 -5
- package/dist/zod.d.mts +5 -5
- package/dist/zod.d.ts +5 -5
- package/dist/zod.mjs +6 -6
- package/package.json +19 -5
- package/dist/shared/attaform.BGk8cfw2.mjs.map +0 -1
- package/dist/shared/attaform.B_hph5AE.cjs.map +0 -1
- package/dist/shared/attaform.C5aYC_T8.mjs.map +0 -1
- package/dist/shared/attaform.Cd4AOfwu.cjs.map +0 -1
- package/dist/shared/attaform.CwLjUqmQ.cjs.map +0 -1
- package/dist/shared/attaform.DAKrGhxc.cjs.map +0 -1
- package/dist/shared/attaform.Dt7dEcHk.mjs.map +0 -1
- package/dist/shared/attaform.QG5TG8lB.mjs.map +0 -1
- package/dist/shared/attaform.tiWEVznj.mjs.map +0 -1
- package/dist/shared/attaform.z5j3LwJz.cjs.map +0 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const canonicalStringify = require('../shared/attaform.CQN9R62B.cjs');
|
|
4
|
+
const index = require('../shared/attaform.PnqML3xW.cjs');
|
|
5
|
+
|
|
6
|
+
const cyclicSentinel = "<cyclic>";
|
|
7
|
+
function fingerprintZodSchema(schema) {
|
|
8
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
9
|
+
const inProgress = /* @__PURE__ */ new WeakSet();
|
|
10
|
+
return visit(schema, cache, inProgress);
|
|
11
|
+
}
|
|
12
|
+
function visit(schema, cache, inProgress) {
|
|
13
|
+
const cached = cache.get(schema);
|
|
14
|
+
if (cached !== void 0) return cached;
|
|
15
|
+
if (inProgress.has(schema)) return cyclicSentinel;
|
|
16
|
+
inProgress.add(schema);
|
|
17
|
+
try {
|
|
18
|
+
const computed = computeFingerprint(schema, cache, inProgress);
|
|
19
|
+
cache.set(schema, computed);
|
|
20
|
+
return computed;
|
|
21
|
+
} finally {
|
|
22
|
+
inProgress.delete(schema);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function computeFingerprint(schema, cache, inProgress) {
|
|
26
|
+
const kind = index.kindOf(schema);
|
|
27
|
+
const recurse = (child) => visit(child, cache, inProgress);
|
|
28
|
+
switch (kind) {
|
|
29
|
+
// Kind-only leaves: no further structure to descend into.
|
|
30
|
+
case "boolean":
|
|
31
|
+
case "null":
|
|
32
|
+
case "undefined":
|
|
33
|
+
case "any":
|
|
34
|
+
case "unknown":
|
|
35
|
+
case "nan":
|
|
36
|
+
case "void":
|
|
37
|
+
case "never":
|
|
38
|
+
return kind;
|
|
39
|
+
// Leaves with checks (min/max/email/regex/...). Checks are
|
|
40
|
+
// canonicalised and sorted so `.min(3).max(10)` and `.max(10).min(3)`
|
|
41
|
+
// produce identical fingerprints.
|
|
42
|
+
case "string":
|
|
43
|
+
case "number":
|
|
44
|
+
case "bigint":
|
|
45
|
+
case "date":
|
|
46
|
+
return `${kind}${formatChecks(schema)}`;
|
|
47
|
+
case "literal": {
|
|
48
|
+
const values = [...index.getLiteralValues(schema)].sort((a, b) => {
|
|
49
|
+
const as = canonicalStringify.canonicalStringify(a);
|
|
50
|
+
const bs = canonicalStringify.canonicalStringify(b);
|
|
51
|
+
return as < bs ? -1 : as > bs ? 1 : 0;
|
|
52
|
+
});
|
|
53
|
+
return `literal:${canonicalStringify.canonicalStringify(values)}`;
|
|
54
|
+
}
|
|
55
|
+
case "enum":
|
|
56
|
+
return `enum:${canonicalStringify.canonicalStringify([...index.getEnumValues(schema)].sort((a, b) => compare(a, b)))}`;
|
|
57
|
+
case "object": {
|
|
58
|
+
const shape = index.getObjectShape(schema);
|
|
59
|
+
const sortedEntries = Object.entries(shape).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${recurse(v)}`);
|
|
60
|
+
return `object{${sortedEntries.join(",")}}${formatChecks(schema)}`;
|
|
61
|
+
}
|
|
62
|
+
case "array":
|
|
63
|
+
return `array[${recurse(index.getArrayElement(schema))}]${formatChecks(schema)}`;
|
|
64
|
+
case "set":
|
|
65
|
+
return `set<${recurse(index.getSetValueType(schema))}>${formatChecks(schema)}`;
|
|
66
|
+
case "tuple":
|
|
67
|
+
return `tuple[${index.getTupleItems(schema).map(recurse).join(",")}]`;
|
|
68
|
+
case "record":
|
|
69
|
+
return `record<${recurse(index.getRecordKeyType(schema))},${recurse(index.getRecordValueType(schema))}>`;
|
|
70
|
+
case "union": {
|
|
71
|
+
const options = index.getUnionOptions(schema).map(recurse).sort();
|
|
72
|
+
return `union(${options.join("|")})`;
|
|
73
|
+
}
|
|
74
|
+
case "discriminated-union": {
|
|
75
|
+
const disc = index.getDiscriminator(schema) ?? "?";
|
|
76
|
+
const options = index.getDiscriminatedOptions(schema).map(recurse).sort();
|
|
77
|
+
return `dunion[${JSON.stringify(disc)}](${options.join("|")})`;
|
|
78
|
+
}
|
|
79
|
+
case "optional": {
|
|
80
|
+
const inner = index.unwrapInner(schema);
|
|
81
|
+
return inner === void 0 ? "optional(?)" : `optional(${recurse(inner)})`;
|
|
82
|
+
}
|
|
83
|
+
case "nullable": {
|
|
84
|
+
const inner = index.unwrapInner(schema);
|
|
85
|
+
return inner === void 0 ? "nullable(?)" : `nullable(${recurse(inner)})`;
|
|
86
|
+
}
|
|
87
|
+
case "default": {
|
|
88
|
+
const inner = index.unwrapInner(schema);
|
|
89
|
+
return `default[${stableValueRepr(index.getDefaultValue, schema)}](${inner === void 0 ? "?" : recurse(inner)})`;
|
|
90
|
+
}
|
|
91
|
+
case "readonly": {
|
|
92
|
+
const inner = index.unwrapInner(schema);
|
|
93
|
+
return inner === void 0 ? "readonly(?)" : `readonly(${recurse(inner)})`;
|
|
94
|
+
}
|
|
95
|
+
case "pipe": {
|
|
96
|
+
const inner = index.unwrapPipe(schema);
|
|
97
|
+
return inner === void 0 ? "pipe(?)" : `pipe(${recurse(inner)})`;
|
|
98
|
+
}
|
|
99
|
+
case "catch": {
|
|
100
|
+
const inner = index.unwrapInner(schema);
|
|
101
|
+
return `catch[${stableValueRepr(index.getCatchDefault, schema)}](${inner === void 0 ? "?" : recurse(inner)})`;
|
|
102
|
+
}
|
|
103
|
+
case "lazy": {
|
|
104
|
+
const inner = index.unwrapLazy(schema);
|
|
105
|
+
return inner === void 0 ? "lazy(?)" : `lazy(${recurse(inner)})`;
|
|
106
|
+
}
|
|
107
|
+
case "intersection": {
|
|
108
|
+
const left = index.getIntersectionLeft(schema);
|
|
109
|
+
const right = index.getIntersectionRight(schema);
|
|
110
|
+
const leftFp = left === void 0 ? "?" : recurse(left);
|
|
111
|
+
const rightFp = right === void 0 ? "?" : recurse(right);
|
|
112
|
+
const parts = [leftFp, rightFp].sort();
|
|
113
|
+
return `intersection(${parts.join("&")})`;
|
|
114
|
+
}
|
|
115
|
+
// Structural shape isn't observable for these. Bucket them into
|
|
116
|
+
// kind-only fingerprints — a schema-mismatch warning can't do
|
|
117
|
+
// better than "both are `custom`" here, but that still catches
|
|
118
|
+
// `object` vs `custom` mismatches. `map` / `symbol` / `function`
|
|
119
|
+
// are rejected at adapter construction; kept here for exhaustive
|
|
120
|
+
// switch safety when `fingerprintSchema` is called from tooling.
|
|
121
|
+
case "promise":
|
|
122
|
+
case "custom":
|
|
123
|
+
case "template-literal":
|
|
124
|
+
case "transform":
|
|
125
|
+
case "file":
|
|
126
|
+
case "map":
|
|
127
|
+
case "symbol":
|
|
128
|
+
case "function":
|
|
129
|
+
return `${kind}:*`;
|
|
130
|
+
default: {
|
|
131
|
+
const _ = kind;
|
|
132
|
+
return `unknown:${String(_)}`;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function stableValueRepr(get, schema) {
|
|
137
|
+
const first = get(schema);
|
|
138
|
+
const second = get(schema);
|
|
139
|
+
if (!Object.is(first, second) || typeof first === "function") return "fn:*";
|
|
140
|
+
return canonicalStringify.canonicalStringify(first);
|
|
141
|
+
}
|
|
142
|
+
function formatChecks(schema) {
|
|
143
|
+
const checks = index.getChecks(schema);
|
|
144
|
+
if (checks.length === 0) return "";
|
|
145
|
+
const parts = checks.map((c) => serializeCheck(c)).sort();
|
|
146
|
+
return `[${parts.join(";")}]`;
|
|
147
|
+
}
|
|
148
|
+
function serializeCheck(check) {
|
|
149
|
+
if (check !== null && typeof check === "object") {
|
|
150
|
+
const def = check._zod?.def;
|
|
151
|
+
if (def !== void 0) return canonicalStringify.canonicalStringify(def);
|
|
152
|
+
}
|
|
153
|
+
return canonicalStringify.canonicalStringify(check);
|
|
154
|
+
}
|
|
155
|
+
function compare(a, b) {
|
|
156
|
+
const as = String(a);
|
|
157
|
+
const bs = String(b);
|
|
158
|
+
return as < bs ? -1 : as > bs ? 1 : 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
exports.fingerprintZodSchema = fingerprintZodSchema;
|
|
162
|
+
//# sourceMappingURL=fingerprint2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint2.cjs","sources":["../../src/runtime/adapters/zod-v4/fingerprint.ts"],"sourcesContent":["import type { z } from 'zod'\nimport { canonicalStringify } from '../../core/canonical-stringify'\nimport {\n getArrayElement,\n getCatchDefault,\n getChecks,\n getDefaultValue,\n getDiscriminatedOptions,\n getDiscriminator,\n getEnumValues,\n getIntersectionLeft,\n getIntersectionRight,\n getLiteralValues,\n getObjectShape,\n getRecordKeyType,\n getRecordValueType,\n getSetValueType,\n getTupleItems,\n getUnionOptions,\n kindOf,\n unwrapInner,\n unwrapLazy,\n unwrapPipe,\n} from './introspect'\n\n/**\n * Compute a structural fingerprint for a Zod v4 schema.\n *\n * The returned string is:\n * - **Deterministic** for any pair of schemas with the same shape,\n * regardless of whether they were constructed by the same\n * `z.object({...})` call or two identical ones in different files.\n * - **Key-order-insensitive** for `z.object` — shape entries are\n * sorted before serialisation, so `{a, b}` and `{b, a}` produce\n * the same fingerprint.\n * - **Order-insensitive for `z.union`** — option fingerprints are\n * sorted before they're folded in, because union membership has\n * no semantic order.\n * - **Idempotent** — two fingerprint calls on the same schema\n * reference return identical strings, even when the schema\n * contains non-deterministic metadata (e.g. `.default(() => new\n * Date())`). Factories of any kind collapse to an opaque\n * `fn:*` sentinel for this reason (see `defaultValueRepr`).\n *\n * **Known false negatives** — situations where two semantically\n * different schemas hash the same:\n * - `.refine(fn1)` and `.refine(fn2)`: function bodies aren't\n * hashable in a way that survives minification / different closure\n * captures, so every refinement collapses via the generic `fn:*`\n * sentinel. The warning this powers is a best-effort footgun\n * catcher, not a soundness guarantee — two forms whose only\n * difference is refinement logic will look identical here.\n * - `.transform(fn)`: same reason.\n * - `.default(() => x)` where the factory is non-deterministic:\n * collapses to `fn:*` (idempotence requirement — we can't hash a\n * fresh Date on every call).\n * - `z.custom()` — no structural information to introspect; renders\n * as `custom:*`.\n *\n * **Caching is per-call, not module-global.** A WeakMap cache\n * scoped to the starting schema would break correctness under\n * cycles: the `<cyclic>` sentinel's meaning is relative to the\n * call's starting node, so a cached mid-traversal result from one\n * call is wrong for a different call. Cheapest correct design is\n * \"fresh cache per top-level call.\" A 50-field nested schema\n * fingerprints in microseconds, and the library calls `fingerprint`\n * at most twice per shared-key collision (existing + incoming) —\n * not a hot path.\n */\n\nconst cyclicSentinel = '<cyclic>'\n\nexport function fingerprintZodSchema(schema: z.ZodType): string {\n const cache = new WeakMap<z.ZodType, string>()\n const inProgress = new WeakSet<z.ZodType>()\n return visit(schema, cache, inProgress)\n}\n\nfunction visit(\n schema: z.ZodType,\n cache: WeakMap<z.ZodType, string>,\n inProgress: WeakSet<z.ZodType>\n): string {\n const cached = cache.get(schema)\n if (cached !== undefined) return cached\n if (inProgress.has(schema)) return cyclicSentinel\n inProgress.add(schema)\n try {\n const computed = computeFingerprint(schema, cache, inProgress)\n cache.set(schema, computed)\n return computed\n } finally {\n inProgress.delete(schema)\n }\n}\n\nfunction computeFingerprint(\n schema: z.ZodType,\n cache: WeakMap<z.ZodType, string>,\n inProgress: WeakSet<z.ZodType>\n): string {\n const kind = kindOf(schema)\n const recurse = (child: z.ZodType): string => visit(child, cache, inProgress)\n switch (kind) {\n // Kind-only leaves: no further structure to descend into.\n case 'boolean':\n case 'null':\n case 'undefined':\n case 'any':\n case 'unknown':\n case 'nan':\n case 'void':\n case 'never':\n return kind\n\n // Leaves with checks (min/max/email/regex/...). Checks are\n // canonicalised and sorted so `.min(3).max(10)` and `.max(10).min(3)`\n // produce identical fingerprints.\n case 'string':\n case 'number':\n case 'bigint':\n case 'date':\n return `${kind}${formatChecks(schema)}`\n\n case 'literal': {\n // `z.literal(['a', 'b'])` accepts either — the value set has\n // no semantic order, so canonical-sort before hashing so\n // `['a','b']` and `['b','a']` match. `z.literal` accepts\n // string / number / boolean / null / undefined / bigint /\n // symbol — sort by canonicalised string form to get a total\n // order across those types.\n const values = [...getLiteralValues(schema)].sort((a, b) => {\n const as = canonicalStringify(a)\n const bs = canonicalStringify(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n })\n return `literal:${canonicalStringify(values)}`\n }\n\n case 'enum':\n // Enum values have no semantic order — sort before folding.\n return `enum:${canonicalStringify([...getEnumValues(schema)].sort((a, b) => compare(a, b)))}`\n\n case 'object': {\n const shape = getObjectShape(schema as z.ZodObject)\n const sortedEntries = Object.entries(shape)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([k, v]) => `${JSON.stringify(k)}:${recurse(v)}`)\n return `object{${sortedEntries.join(',')}}${formatChecks(schema)}`\n }\n\n case 'array':\n return `array[${recurse(getArrayElement(schema as z.ZodArray))}]${formatChecks(schema)}`\n\n case 'set':\n return `set<${recurse(getSetValueType(schema))}>${formatChecks(schema)}`\n\n case 'tuple':\n return `tuple[${getTupleItems(schema).map(recurse).join(',')}]`\n\n case 'record':\n return `record<${recurse(getRecordKeyType(schema))},${recurse(getRecordValueType(schema))}>`\n\n case 'union': {\n // Union membership has no order; sort option fingerprints.\n const options = getUnionOptions(schema).map(recurse).sort()\n return `union(${options.join('|')})`\n }\n\n case 'discriminated-union': {\n const disc = getDiscriminator(schema) ?? '?'\n const options = getDiscriminatedOptions(schema).map(recurse).sort()\n return `dunion[${JSON.stringify(disc)}](${options.join('|')})`\n }\n\n case 'optional': {\n const inner = unwrapInner(schema)\n return inner === undefined ? 'optional(?)' : `optional(${recurse(inner)})`\n }\n\n case 'nullable': {\n const inner = unwrapInner(schema)\n return inner === undefined ? 'nullable(?)' : `nullable(${recurse(inner)})`\n }\n\n case 'default': {\n const inner = unwrapInner(schema)\n return `default[${stableValueRepr(getDefaultValue, schema)}](${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'readonly': {\n const inner = unwrapInner(schema)\n return inner === undefined ? 'readonly(?)' : `readonly(${recurse(inner)})`\n }\n\n case 'pipe': {\n const inner = unwrapPipe(schema)\n return inner === undefined ? 'pipe(?)' : `pipe(${recurse(inner)})`\n }\n\n case 'catch': {\n const inner = unwrapInner(schema)\n return `catch[${stableValueRepr(getCatchDefault, schema)}](${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'lazy': {\n // `z.lazy(() => other)` — fingerprint the dereferenced inner.\n // The `inProgress` WeakSet catches real cycles (a schema that\n // references itself through lazy) and returns `cyclicSentinel`\n // for any recursive encounter.\n const inner = unwrapLazy(schema)\n return inner === undefined ? 'lazy(?)' : `lazy(${recurse(inner)})`\n }\n\n case 'intersection': {\n const left = getIntersectionLeft(schema)\n const right = getIntersectionRight(schema)\n const leftFp = left === undefined ? '?' : recurse(left as z.ZodType)\n const rightFp = right === undefined ? '?' : recurse(right as z.ZodType)\n // Intersection members have no semantic order; sort both legs.\n const parts = [leftFp, rightFp].sort()\n return `intersection(${parts.join('&')})`\n }\n\n // Structural shape isn't observable for these. Bucket them into\n // kind-only fingerprints — a schema-mismatch warning can't do\n // better than \"both are `custom`\" here, but that still catches\n // `object` vs `custom` mismatches. `map` / `symbol` / `function`\n // are rejected at adapter construction; kept here for exhaustive\n // switch safety when `fingerprintSchema` is called from tooling.\n case 'promise':\n case 'custom':\n case 'template-literal':\n case 'transform':\n case 'file':\n case 'map':\n case 'symbol':\n case 'function':\n return `${kind}:*`\n\n default: {\n // Exhaustiveness guard — if ZodKind grows a new variant we'll\n // fall through here and get a typecheck-visible warning via\n // the unreachable assignment.\n const _: never = kind\n return `unknown:${String(_)}`\n }\n }\n}\n\n/**\n * Render a default/catch value for the fingerprint. Detects\n * non-deterministic factories (`.default(() => new Date())`) by\n * reading the value twice and comparing — zod v4's getter invokes\n * the factory fresh on each access, so two consecutive reads of a\n * factory-backed default produce distinct objects for any\n * heap-allocated return type. Object.is matches for primitive\n * returns (even from factories) and for literal defaults; in both\n * cases we emit the canonical representation. Without this the\n * fingerprint is non-idempotent for schemas like\n * `.default(() => new Date())`.\n */\nfunction stableValueRepr(get: (s: z.ZodType) => unknown, schema: z.ZodType): string {\n const first = get(schema)\n const second = get(schema)\n if (!Object.is(first, second) || typeof first === 'function') return 'fn:*'\n return canonicalStringify(first)\n}\n\n/**\n * Serialise a check array to a stable string. Checks are sorted by\n * their canonical form so order-of-chain doesn't matter — the zod\n * runtime already collapses `.min(3).max(10)` and `.max(10).min(3)`\n * to the same behaviour, and the fingerprint should match.\n */\nfunction formatChecks(schema: z.ZodType): string {\n const checks = getChecks(schema)\n if (checks.length === 0) return ''\n const parts = checks.map((c) => serializeCheck(c)).sort()\n return `[${parts.join(';')}]`\n}\n\n/**\n * Zod v4 checks are instances of `$ZodCheck` — their state lives on\n * `_zod.def` (kind discriminator + kind-specific args), not on the\n * object's own enumerable properties. A plain `Object.entries`\n * serialise would see an empty object and collapse every check to\n * the same fingerprint — `.min(3)` and `.min(8)` would look\n * identical. Reach into `_zod.def` when it's present; fall back to\n * generic canonicalisation for anything that isn't shaped like a\n * v4 check (custom adapters may pass their own shapes here).\n */\nfunction serializeCheck(check: unknown): string {\n if (check !== null && typeof check === 'object') {\n const def = (check as { _zod?: { def?: unknown } })._zod?.def\n if (def !== undefined) return canonicalStringify(def)\n }\n return canonicalStringify(check)\n}\n\n/** Strict-mode sort comparator that handles mixed string/number enums. */\nfunction compare(a: string | number, b: string | number): number {\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n}\n"],"names":["kindOf","getLiteralValues","canonicalStringify","getEnumValues","getObjectShape","getArrayElement","getSetValueType","getTupleItems","getRecordKeyType","getRecordValueType","getUnionOptions","getDiscriminator","getDiscriminatedOptions","unwrapInner","getDefaultValue","unwrapPipe","getCatchDefault","unwrapLazy","getIntersectionLeft","getIntersectionRight","getChecks"],"mappings":";;;;;AAsEA,MAAM,cAAA,GAAiB,UAAA;AAEhB,SAAS,qBAAqB,MAAA,EAA2B;AAC9D,EAAA,MAAM,KAAA,uBAAY,OAAA,EAA2B;AAC7C,EAAA,MAAM,UAAA,uBAAiB,OAAA,EAAmB;AAC1C,EAAA,OAAO,KAAA,CAAM,MAAA,EAAQ,KAAA,EAAO,UAAU,CAAA;AACxC;AAEA,SAAS,KAAA,CACP,MAAA,EACA,KAAA,EACA,UAAA,EACQ;AACR,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AAC/B,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AACjC,EAAA,IAAI,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA,EAAG,OAAO,cAAA;AACnC,EAAA,UAAA,CAAW,IAAI,MAAM,CAAA;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,MAAA,EAAQ,KAAA,EAAO,UAAU,CAAA;AAC7D,IAAA,KAAA,CAAM,GAAA,CAAI,QAAQ,QAAQ,CAAA;AAC1B,IAAA,OAAO,QAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,UAAA,CAAW,OAAO,MAAM,CAAA;AAAA,EAC1B;AACF;AAEA,SAAS,kBAAA,CACP,MAAA,EACA,KAAA,EACA,UAAA,EACQ;AACR,EAAA,MAAM,IAAA,GAAOA,aAAO,MAAM,CAAA;AAC1B,EAAA,MAAM,UAAU,CAAC,KAAA,KAA6B,KAAA,CAAM,KAAA,EAAO,OAAO,UAAU,CAAA;AAC5E,EAAA,QAAQ,IAAA;AAAM;AAAA,IAEZ,KAAK,SAAA;AAAA,IACL,KAAK,MAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,KAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,KAAA;AAAA,IACL,KAAK,MAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAO,IAAA;AAAA;AAAA;AAAA;AAAA,IAKT,KAAK,QAAA;AAAA,IACL,KAAK,QAAA;AAAA,IACL,KAAK,QAAA;AAAA,IACL,KAAK,MAAA;AACH,MAAA,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA;AAAA,IAEvC,KAAK,SAAA,EAAW;AAOd,MAAA,MAAM,MAAA,GAAS,CAAC,GAAGC,sBAAA,CAAiB,MAAM,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AAC1D,QAAA,MAAM,EAAA,GAAKC,sCAAmB,CAAC,CAAA;AAC/B,QAAA,MAAM,EAAA,GAAKA,sCAAmB,CAAC,CAAA;AAC/B,QAAA,OAAO,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,KAAK,CAAA,GAAI,CAAA;AAAA,MACtC,CAAC,CAAA;AACD,MAAA,OAAO,CAAA,QAAA,EAAWA,qCAAA,CAAmB,MAAM,CAAC,CAAA,CAAA;AAAA,IAC9C;AAAA,IAEA,KAAK,MAAA;AAEH,MAAA,OAAO,QAAQA,qCAAA,CAAmB,CAAC,GAAGC,mBAAA,CAAc,MAAM,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,OAAA,CAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA,CAAA;AAAA,IAE7F,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,KAAA,GAAQC,qBAAe,MAAqB,CAAA;AAClD,MAAA,MAAM,gBAAgB,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CACvC,KAAK,CAAC,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA,KAAO,CAAA,GAAI,CAAA,GAAI,KAAK,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAE,EAC/C,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA,EAAI,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAE,CAAA;AACvD,MAAA,OAAO,CAAA,OAAA,EAAU,cAAc,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,EAAI,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA;AAAA,IAClE;AAAA,IAEA,KAAK,OAAA;AACH,MAAA,OAAO,CAAA,MAAA,EAAS,QAAQC,qBAAA,CAAgB,MAAoB,CAAC,CAAC,CAAA,CAAA,EAAI,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA;AAAA,IAExF,KAAK,KAAA;AACH,MAAA,OAAO,CAAA,IAAA,EAAO,QAAQC,qBAAA,CAAgB,MAAM,CAAC,CAAC,CAAA,CAAA,EAAI,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA;AAAA,IAExE,KAAK,OAAA;AACH,MAAA,OAAO,CAAA,MAAA,EAASC,oBAAc,MAAM,CAAA,CAAE,IAAI,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,IAE9D,KAAK,QAAA;AACH,MAAA,OAAO,CAAA,OAAA,EAAU,OAAA,CAAQC,sBAAA,CAAiB,MAAM,CAAC,CAAC,CAAA,CAAA,EAAI,OAAA,CAAQC,wBAAA,CAAmB,MAAM,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,IAE3F,KAAK,OAAA,EAAS;AAEZ,MAAA,MAAM,UAAUC,qBAAA,CAAgB,MAAM,EAAE,GAAA,CAAI,OAAO,EAAE,IAAA,EAAK;AAC1D,MAAA,OAAO,CAAA,MAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,IACnC;AAAA,IAEA,KAAK,qBAAA,EAAuB;AAC1B,MAAA,MAAM,IAAA,GAAOC,sBAAA,CAAiB,MAAM,CAAA,IAAK,GAAA;AACzC,MAAA,MAAM,UAAUC,6BAAA,CAAwB,MAAM,EAAE,GAAA,CAAI,OAAO,EAAE,IAAA,EAAK;AAClE,MAAA,OAAO,CAAA,OAAA,EAAU,KAAK,SAAA,CAAU,IAAI,CAAC,CAAA,EAAA,EAAK,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,IAC7D;AAAA,IAEA,KAAK,UAAA,EAAY;AACf,MAAA,MAAM,KAAA,GAAQC,kBAAY,MAAM,CAAA;AAChC,MAAA,OAAO,UAAU,MAAA,GAAY,aAAA,GAAgB,CAAA,SAAA,EAAY,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IACzE;AAAA,IAEA,KAAK,UAAA,EAAY;AACf,MAAA,MAAM,KAAA,GAAQA,kBAAY,MAAM,CAAA;AAChC,MAAA,OAAO,UAAU,MAAA,GAAY,aAAA,GAAgB,CAAA,SAAA,EAAY,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IACzE;AAAA,IAEA,KAAK,SAAA,EAAW;AACd,MAAA,MAAM,KAAA,GAAQA,kBAAY,MAAM,CAAA;AAChC,MAAA,OAAO,CAAA,QAAA,EAAW,eAAA,CAAgBC,qBAAA,EAAiB,MAAM,CAAC,CAAA,EAAA,EAAK,KAAA,KAAU,MAAA,GAAY,GAAA,GAAM,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IAC3G;AAAA,IAEA,KAAK,UAAA,EAAY;AACf,MAAA,MAAM,KAAA,GAAQD,kBAAY,MAAM,CAAA;AAChC,MAAA,OAAO,UAAU,MAAA,GAAY,aAAA,GAAgB,CAAA,SAAA,EAAY,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IACzE;AAAA,IAEA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,KAAA,GAAQE,iBAAW,MAAM,CAAA;AAC/B,MAAA,OAAO,UAAU,MAAA,GAAY,SAAA,GAAY,CAAA,KAAA,EAAQ,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IACjE;AAAA,IAEA,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,KAAA,GAAQF,kBAAY,MAAM,CAAA;AAChC,MAAA,OAAO,CAAA,MAAA,EAAS,eAAA,CAAgBG,qBAAA,EAAiB,MAAM,CAAC,CAAA,EAAA,EAAK,KAAA,KAAU,MAAA,GAAY,GAAA,GAAM,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IACzG;AAAA,IAEA,KAAK,MAAA,EAAQ;AAKX,MAAA,MAAM,KAAA,GAAQC,iBAAW,MAAM,CAAA;AAC/B,MAAA,OAAO,UAAU,MAAA,GAAY,SAAA,GAAY,CAAA,KAAA,EAAQ,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,IACjE;AAAA,IAEA,KAAK,cAAA,EAAgB;AACnB,MAAA,MAAM,IAAA,GAAOC,0BAAoB,MAAM,CAAA;AACvC,MAAA,MAAM,KAAA,GAAQC,2BAAqB,MAAM,CAAA;AACzC,MAAA,MAAM,MAAA,GAAS,IAAA,KAAS,MAAA,GAAY,GAAA,GAAM,QAAQ,IAAiB,CAAA;AACnE,MAAA,MAAM,OAAA,GAAU,KAAA,KAAU,MAAA,GAAY,GAAA,GAAM,QAAQ,KAAkB,CAAA;AAEtE,MAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,EAAQ,OAAO,EAAE,IAAA,EAAK;AACrC,MAAA,OAAO,CAAA,aAAA,EAAgB,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,IACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,KAAK,SAAA;AAAA,IACL,KAAK,QAAA;AAAA,IACL,KAAK,kBAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,MAAA;AAAA,IACL,KAAK,KAAA;AAAA,IACL,KAAK,QAAA;AAAA,IACL,KAAK,UAAA;AACH,MAAA,OAAO,GAAG,IAAI,CAAA,EAAA,CAAA;AAAA,IAEhB,SAAS;AAIP,MAAA,MAAM,CAAA,GAAW,IAAA;AACjB,MAAA,OAAO,CAAA,QAAA,EAAW,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAAA,IAC7B;AAAA;AAEJ;AAcA,SAAS,eAAA,CAAgB,KAAgC,MAAA,EAA2B;AAClF,EAAA,MAAM,KAAA,GAAQ,IAAI,MAAM,CAAA;AACxB,EAAA,MAAM,MAAA,GAAS,IAAI,MAAM,CAAA;AACzB,EAAA,IAAI,CAAC,OAAO,EAAA,CAAG,KAAA,EAAO,MAAM,CAAA,IAAK,OAAO,KAAA,KAAU,UAAA,EAAY,OAAO,MAAA;AACrE,EAAA,OAAOjB,sCAAmB,KAAK,CAAA;AACjC;AAQA,SAAS,aAAa,MAAA,EAA2B;AAC/C,EAAA,MAAM,MAAA,GAASkB,gBAAU,MAAM,CAAA;AAC/B,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AAChC,EAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,CAAI,CAAC,MAAM,cAAA,CAAe,CAAC,CAAC,CAAA,CAAE,IAAA,EAAK;AACxD,EAAA,OAAO,CAAA,CAAA,EAAI,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAC5B;AAYA,SAAS,eAAe,KAAA,EAAwB;AAC9C,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC/C,IAAA,MAAM,GAAA,GAAO,MAAuC,IAAA,EAAM,GAAA;AAC1D,IAAA,IAAI,GAAA,KAAQ,MAAA,EAAW,OAAOlB,qCAAA,CAAmB,GAAG,CAAA;AAAA,EACtD;AACA,EAAA,OAAOA,sCAAmB,KAAK,CAAA;AACjC;AAGA,SAAS,OAAA,CAAQ,GAAoB,CAAA,EAA4B;AAC/D,EAAA,MAAM,EAAA,GAAK,OAAO,CAAC,CAAA;AACnB,EAAA,MAAM,EAAA,GAAK,OAAO,CAAC,CAAA;AACnB,EAAA,OAAO,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,KAAK,CAAA,GAAI,CAAA;AACtC;;;;"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { c as canonicalStringify } from '../shared/attaform.BJGA_UOS.mjs';
|
|
2
|
+
import { s as kindOf, j as getIntersectionLeft, k as getIntersectionRight, t as unwrapLazy, u as unwrapInner, v as unwrapPipe, h as getDiscriminator, e as getDiscriminatedOptions, r as getUnionOptions, n as getRecordKeyType, o as getRecordValueType, q as getTupleItems, p as getSetValueType, g as getArrayElement, m as getObjectShape, i as getEnumValues, l as getLiteralValues, c as getChecks, b as getCatchDefault, d as getDefaultValue } from '../shared/attaform.BnK_bfcb.mjs';
|
|
3
|
+
|
|
4
|
+
const cyclicSentinel = "<cyclic>";
|
|
5
|
+
function fingerprintZodSchema(schema) {
|
|
6
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
const inProgress = /* @__PURE__ */ new WeakSet();
|
|
8
|
+
return visit(schema, cache, inProgress);
|
|
9
|
+
}
|
|
10
|
+
function visit(schema, cache, inProgress) {
|
|
11
|
+
const cached = cache.get(schema);
|
|
12
|
+
if (cached !== void 0) return cached;
|
|
13
|
+
if (inProgress.has(schema)) return cyclicSentinel;
|
|
14
|
+
inProgress.add(schema);
|
|
15
|
+
try {
|
|
16
|
+
const computed = computeFingerprint(schema, cache, inProgress);
|
|
17
|
+
cache.set(schema, computed);
|
|
18
|
+
return computed;
|
|
19
|
+
} finally {
|
|
20
|
+
inProgress.delete(schema);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function computeFingerprint(schema, cache, inProgress) {
|
|
24
|
+
const kind = kindOf(schema);
|
|
25
|
+
const recurse = (child) => visit(child, cache, inProgress);
|
|
26
|
+
switch (kind) {
|
|
27
|
+
// Kind-only leaves: no further structure to descend into.
|
|
28
|
+
case "boolean":
|
|
29
|
+
case "null":
|
|
30
|
+
case "undefined":
|
|
31
|
+
case "any":
|
|
32
|
+
case "unknown":
|
|
33
|
+
case "nan":
|
|
34
|
+
case "void":
|
|
35
|
+
case "never":
|
|
36
|
+
return kind;
|
|
37
|
+
// Leaves with checks (min/max/email/regex/...). Checks are
|
|
38
|
+
// canonicalised and sorted so `.min(3).max(10)` and `.max(10).min(3)`
|
|
39
|
+
// produce identical fingerprints.
|
|
40
|
+
case "string":
|
|
41
|
+
case "number":
|
|
42
|
+
case "bigint":
|
|
43
|
+
case "date":
|
|
44
|
+
return `${kind}${formatChecks(schema)}`;
|
|
45
|
+
case "literal": {
|
|
46
|
+
const values = [...getLiteralValues(schema)].sort((a, b) => {
|
|
47
|
+
const as = canonicalStringify(a);
|
|
48
|
+
const bs = canonicalStringify(b);
|
|
49
|
+
return as < bs ? -1 : as > bs ? 1 : 0;
|
|
50
|
+
});
|
|
51
|
+
return `literal:${canonicalStringify(values)}`;
|
|
52
|
+
}
|
|
53
|
+
case "enum":
|
|
54
|
+
return `enum:${canonicalStringify([...getEnumValues(schema)].sort((a, b) => compare(a, b)))}`;
|
|
55
|
+
case "object": {
|
|
56
|
+
const shape = getObjectShape(schema);
|
|
57
|
+
const sortedEntries = Object.entries(shape).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${recurse(v)}`);
|
|
58
|
+
return `object{${sortedEntries.join(",")}}${formatChecks(schema)}`;
|
|
59
|
+
}
|
|
60
|
+
case "array":
|
|
61
|
+
return `array[${recurse(getArrayElement(schema))}]${formatChecks(schema)}`;
|
|
62
|
+
case "set":
|
|
63
|
+
return `set<${recurse(getSetValueType(schema))}>${formatChecks(schema)}`;
|
|
64
|
+
case "tuple":
|
|
65
|
+
return `tuple[${getTupleItems(schema).map(recurse).join(",")}]`;
|
|
66
|
+
case "record":
|
|
67
|
+
return `record<${recurse(getRecordKeyType(schema))},${recurse(getRecordValueType(schema))}>`;
|
|
68
|
+
case "union": {
|
|
69
|
+
const options = getUnionOptions(schema).map(recurse).sort();
|
|
70
|
+
return `union(${options.join("|")})`;
|
|
71
|
+
}
|
|
72
|
+
case "discriminated-union": {
|
|
73
|
+
const disc = getDiscriminator(schema) ?? "?";
|
|
74
|
+
const options = getDiscriminatedOptions(schema).map(recurse).sort();
|
|
75
|
+
return `dunion[${JSON.stringify(disc)}](${options.join("|")})`;
|
|
76
|
+
}
|
|
77
|
+
case "optional": {
|
|
78
|
+
const inner = unwrapInner(schema);
|
|
79
|
+
return inner === void 0 ? "optional(?)" : `optional(${recurse(inner)})`;
|
|
80
|
+
}
|
|
81
|
+
case "nullable": {
|
|
82
|
+
const inner = unwrapInner(schema);
|
|
83
|
+
return inner === void 0 ? "nullable(?)" : `nullable(${recurse(inner)})`;
|
|
84
|
+
}
|
|
85
|
+
case "default": {
|
|
86
|
+
const inner = unwrapInner(schema);
|
|
87
|
+
return `default[${stableValueRepr(getDefaultValue, schema)}](${inner === void 0 ? "?" : recurse(inner)})`;
|
|
88
|
+
}
|
|
89
|
+
case "readonly": {
|
|
90
|
+
const inner = unwrapInner(schema);
|
|
91
|
+
return inner === void 0 ? "readonly(?)" : `readonly(${recurse(inner)})`;
|
|
92
|
+
}
|
|
93
|
+
case "pipe": {
|
|
94
|
+
const inner = unwrapPipe(schema);
|
|
95
|
+
return inner === void 0 ? "pipe(?)" : `pipe(${recurse(inner)})`;
|
|
96
|
+
}
|
|
97
|
+
case "catch": {
|
|
98
|
+
const inner = unwrapInner(schema);
|
|
99
|
+
return `catch[${stableValueRepr(getCatchDefault, schema)}](${inner === void 0 ? "?" : recurse(inner)})`;
|
|
100
|
+
}
|
|
101
|
+
case "lazy": {
|
|
102
|
+
const inner = unwrapLazy(schema);
|
|
103
|
+
return inner === void 0 ? "lazy(?)" : `lazy(${recurse(inner)})`;
|
|
104
|
+
}
|
|
105
|
+
case "intersection": {
|
|
106
|
+
const left = getIntersectionLeft(schema);
|
|
107
|
+
const right = getIntersectionRight(schema);
|
|
108
|
+
const leftFp = left === void 0 ? "?" : recurse(left);
|
|
109
|
+
const rightFp = right === void 0 ? "?" : recurse(right);
|
|
110
|
+
const parts = [leftFp, rightFp].sort();
|
|
111
|
+
return `intersection(${parts.join("&")})`;
|
|
112
|
+
}
|
|
113
|
+
// Structural shape isn't observable for these. Bucket them into
|
|
114
|
+
// kind-only fingerprints — a schema-mismatch warning can't do
|
|
115
|
+
// better than "both are `custom`" here, but that still catches
|
|
116
|
+
// `object` vs `custom` mismatches. `map` / `symbol` / `function`
|
|
117
|
+
// are rejected at adapter construction; kept here for exhaustive
|
|
118
|
+
// switch safety when `fingerprintSchema` is called from tooling.
|
|
119
|
+
case "promise":
|
|
120
|
+
case "custom":
|
|
121
|
+
case "template-literal":
|
|
122
|
+
case "transform":
|
|
123
|
+
case "file":
|
|
124
|
+
case "map":
|
|
125
|
+
case "symbol":
|
|
126
|
+
case "function":
|
|
127
|
+
return `${kind}:*`;
|
|
128
|
+
default: {
|
|
129
|
+
const _ = kind;
|
|
130
|
+
return `unknown:${String(_)}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function stableValueRepr(get, schema) {
|
|
135
|
+
const first = get(schema);
|
|
136
|
+
const second = get(schema);
|
|
137
|
+
if (!Object.is(first, second) || typeof first === "function") return "fn:*";
|
|
138
|
+
return canonicalStringify(first);
|
|
139
|
+
}
|
|
140
|
+
function formatChecks(schema) {
|
|
141
|
+
const checks = getChecks(schema);
|
|
142
|
+
if (checks.length === 0) return "";
|
|
143
|
+
const parts = checks.map((c) => serializeCheck(c)).sort();
|
|
144
|
+
return `[${parts.join(";")}]`;
|
|
145
|
+
}
|
|
146
|
+
function serializeCheck(check) {
|
|
147
|
+
if (check !== null && typeof check === "object") {
|
|
148
|
+
const def = check._zod?.def;
|
|
149
|
+
if (def !== void 0) return canonicalStringify(def);
|
|
150
|
+
}
|
|
151
|
+
return canonicalStringify(check);
|
|
152
|
+
}
|
|
153
|
+
function compare(a, b) {
|
|
154
|
+
const as = String(a);
|
|
155
|
+
const bs = String(b);
|
|
156
|
+
return as < bs ? -1 : as > bs ? 1 : 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export { fingerprintZodSchema };
|
|
160
|
+
//# sourceMappingURL=fingerprint2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint2.mjs","sources":["../../src/runtime/adapters/zod-v4/fingerprint.ts"],"sourcesContent":["import type { z } from 'zod'\nimport { canonicalStringify } from '../../core/canonical-stringify'\nimport {\n getArrayElement,\n getCatchDefault,\n getChecks,\n getDefaultValue,\n getDiscriminatedOptions,\n getDiscriminator,\n getEnumValues,\n getIntersectionLeft,\n getIntersectionRight,\n getLiteralValues,\n getObjectShape,\n getRecordKeyType,\n getRecordValueType,\n getSetValueType,\n getTupleItems,\n getUnionOptions,\n kindOf,\n unwrapInner,\n unwrapLazy,\n unwrapPipe,\n} from './introspect'\n\n/**\n * Compute a structural fingerprint for a Zod v4 schema.\n *\n * The returned string is:\n * - **Deterministic** for any pair of schemas with the same shape,\n * regardless of whether they were constructed by the same\n * `z.object({...})` call or two identical ones in different files.\n * - **Key-order-insensitive** for `z.object` — shape entries are\n * sorted before serialisation, so `{a, b}` and `{b, a}` produce\n * the same fingerprint.\n * - **Order-insensitive for `z.union`** — option fingerprints are\n * sorted before they're folded in, because union membership has\n * no semantic order.\n * - **Idempotent** — two fingerprint calls on the same schema\n * reference return identical strings, even when the schema\n * contains non-deterministic metadata (e.g. `.default(() => new\n * Date())`). Factories of any kind collapse to an opaque\n * `fn:*` sentinel for this reason (see `defaultValueRepr`).\n *\n * **Known false negatives** — situations where two semantically\n * different schemas hash the same:\n * - `.refine(fn1)` and `.refine(fn2)`: function bodies aren't\n * hashable in a way that survives minification / different closure\n * captures, so every refinement collapses via the generic `fn:*`\n * sentinel. The warning this powers is a best-effort footgun\n * catcher, not a soundness guarantee — two forms whose only\n * difference is refinement logic will look identical here.\n * - `.transform(fn)`: same reason.\n * - `.default(() => x)` where the factory is non-deterministic:\n * collapses to `fn:*` (idempotence requirement — we can't hash a\n * fresh Date on every call).\n * - `z.custom()` — no structural information to introspect; renders\n * as `custom:*`.\n *\n * **Caching is per-call, not module-global.** A WeakMap cache\n * scoped to the starting schema would break correctness under\n * cycles: the `<cyclic>` sentinel's meaning is relative to the\n * call's starting node, so a cached mid-traversal result from one\n * call is wrong for a different call. Cheapest correct design is\n * \"fresh cache per top-level call.\" A 50-field nested schema\n * fingerprints in microseconds, and the library calls `fingerprint`\n * at most twice per shared-key collision (existing + incoming) —\n * not a hot path.\n */\n\nconst cyclicSentinel = '<cyclic>'\n\nexport function fingerprintZodSchema(schema: z.ZodType): string {\n const cache = new WeakMap<z.ZodType, string>()\n const inProgress = new WeakSet<z.ZodType>()\n return visit(schema, cache, inProgress)\n}\n\nfunction visit(\n schema: z.ZodType,\n cache: WeakMap<z.ZodType, string>,\n inProgress: WeakSet<z.ZodType>\n): string {\n const cached = cache.get(schema)\n if (cached !== undefined) return cached\n if (inProgress.has(schema)) return cyclicSentinel\n inProgress.add(schema)\n try {\n const computed = computeFingerprint(schema, cache, inProgress)\n cache.set(schema, computed)\n return computed\n } finally {\n inProgress.delete(schema)\n }\n}\n\nfunction computeFingerprint(\n schema: z.ZodType,\n cache: WeakMap<z.ZodType, string>,\n inProgress: WeakSet<z.ZodType>\n): string {\n const kind = kindOf(schema)\n const recurse = (child: z.ZodType): string => visit(child, cache, inProgress)\n switch (kind) {\n // Kind-only leaves: no further structure to descend into.\n case 'boolean':\n case 'null':\n case 'undefined':\n case 'any':\n case 'unknown':\n case 'nan':\n case 'void':\n case 'never':\n return kind\n\n // Leaves with checks (min/max/email/regex/...). Checks are\n // canonicalised and sorted so `.min(3).max(10)` and `.max(10).min(3)`\n // produce identical fingerprints.\n case 'string':\n case 'number':\n case 'bigint':\n case 'date':\n return `${kind}${formatChecks(schema)}`\n\n case 'literal': {\n // `z.literal(['a', 'b'])` accepts either — the value set has\n // no semantic order, so canonical-sort before hashing so\n // `['a','b']` and `['b','a']` match. `z.literal` accepts\n // string / number / boolean / null / undefined / bigint /\n // symbol — sort by canonicalised string form to get a total\n // order across those types.\n const values = [...getLiteralValues(schema)].sort((a, b) => {\n const as = canonicalStringify(a)\n const bs = canonicalStringify(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n })\n return `literal:${canonicalStringify(values)}`\n }\n\n case 'enum':\n // Enum values have no semantic order — sort before folding.\n return `enum:${canonicalStringify([...getEnumValues(schema)].sort((a, b) => compare(a, b)))}`\n\n case 'object': {\n const shape = getObjectShape(schema as z.ZodObject)\n const sortedEntries = Object.entries(shape)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([k, v]) => `${JSON.stringify(k)}:${recurse(v)}`)\n return `object{${sortedEntries.join(',')}}${formatChecks(schema)}`\n }\n\n case 'array':\n return `array[${recurse(getArrayElement(schema as z.ZodArray))}]${formatChecks(schema)}`\n\n case 'set':\n return `set<${recurse(getSetValueType(schema))}>${formatChecks(schema)}`\n\n case 'tuple':\n return `tuple[${getTupleItems(schema).map(recurse).join(',')}]`\n\n case 'record':\n return `record<${recurse(getRecordKeyType(schema))},${recurse(getRecordValueType(schema))}>`\n\n case 'union': {\n // Union membership has no order; sort option fingerprints.\n const options = getUnionOptions(schema).map(recurse).sort()\n return `union(${options.join('|')})`\n }\n\n case 'discriminated-union': {\n const disc = getDiscriminator(schema) ?? '?'\n const options = getDiscriminatedOptions(schema).map(recurse).sort()\n return `dunion[${JSON.stringify(disc)}](${options.join('|')})`\n }\n\n case 'optional': {\n const inner = unwrapInner(schema)\n return inner === undefined ? 'optional(?)' : `optional(${recurse(inner)})`\n }\n\n case 'nullable': {\n const inner = unwrapInner(schema)\n return inner === undefined ? 'nullable(?)' : `nullable(${recurse(inner)})`\n }\n\n case 'default': {\n const inner = unwrapInner(schema)\n return `default[${stableValueRepr(getDefaultValue, schema)}](${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'readonly': {\n const inner = unwrapInner(schema)\n return inner === undefined ? 'readonly(?)' : `readonly(${recurse(inner)})`\n }\n\n case 'pipe': {\n const inner = unwrapPipe(schema)\n return inner === undefined ? 'pipe(?)' : `pipe(${recurse(inner)})`\n }\n\n case 'catch': {\n const inner = unwrapInner(schema)\n return `catch[${stableValueRepr(getCatchDefault, schema)}](${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'lazy': {\n // `z.lazy(() => other)` — fingerprint the dereferenced inner.\n // The `inProgress` WeakSet catches real cycles (a schema that\n // references itself through lazy) and returns `cyclicSentinel`\n // for any recursive encounter.\n const inner = unwrapLazy(schema)\n return inner === undefined ? 'lazy(?)' : `lazy(${recurse(inner)})`\n }\n\n case 'intersection': {\n const left = getIntersectionLeft(schema)\n const right = getIntersectionRight(schema)\n const leftFp = left === undefined ? '?' : recurse(left as z.ZodType)\n const rightFp = right === undefined ? '?' : recurse(right as z.ZodType)\n // Intersection members have no semantic order; sort both legs.\n const parts = [leftFp, rightFp].sort()\n return `intersection(${parts.join('&')})`\n }\n\n // Structural shape isn't observable for these. Bucket them into\n // kind-only fingerprints — a schema-mismatch warning can't do\n // better than \"both are `custom`\" here, but that still catches\n // `object` vs `custom` mismatches. `map` / `symbol` / `function`\n // are rejected at adapter construction; kept here for exhaustive\n // switch safety when `fingerprintSchema` is called from tooling.\n case 'promise':\n case 'custom':\n case 'template-literal':\n case 'transform':\n case 'file':\n case 'map':\n case 'symbol':\n case 'function':\n return `${kind}:*`\n\n default: {\n // Exhaustiveness guard — if ZodKind grows a new variant we'll\n // fall through here and get a typecheck-visible warning via\n // the unreachable assignment.\n const _: never = kind\n return `unknown:${String(_)}`\n }\n }\n}\n\n/**\n * Render a default/catch value for the fingerprint. Detects\n * non-deterministic factories (`.default(() => new Date())`) by\n * reading the value twice and comparing — zod v4's getter invokes\n * the factory fresh on each access, so two consecutive reads of a\n * factory-backed default produce distinct objects for any\n * heap-allocated return type. Object.is matches for primitive\n * returns (even from factories) and for literal defaults; in both\n * cases we emit the canonical representation. Without this the\n * fingerprint is non-idempotent for schemas like\n * `.default(() => new Date())`.\n */\nfunction stableValueRepr(get: (s: z.ZodType) => unknown, schema: z.ZodType): string {\n const first = get(schema)\n const second = get(schema)\n if (!Object.is(first, second) || typeof first === 'function') return 'fn:*'\n return canonicalStringify(first)\n}\n\n/**\n * Serialise a check array to a stable string. Checks are sorted by\n * their canonical form so order-of-chain doesn't matter — the zod\n * runtime already collapses `.min(3).max(10)` and `.max(10).min(3)`\n * to the same behaviour, and the fingerprint should match.\n */\nfunction formatChecks(schema: z.ZodType): string {\n const checks = getChecks(schema)\n if (checks.length === 0) return ''\n const parts = checks.map((c) => serializeCheck(c)).sort()\n return `[${parts.join(';')}]`\n}\n\n/**\n * Zod v4 checks are instances of `$ZodCheck` — their state lives on\n * `_zod.def` (kind discriminator + kind-specific args), not on the\n * object's own enumerable properties. A plain `Object.entries`\n * serialise would see an empty object and collapse every check to\n * the same fingerprint — `.min(3)` and `.min(8)` would look\n * identical. Reach into `_zod.def` when it's present; fall back to\n * generic canonicalisation for anything that isn't shaped like a\n * v4 check (custom adapters may pass their own shapes here).\n */\nfunction serializeCheck(check: unknown): string {\n if (check !== null && typeof check === 'object') {\n const def = (check as { _zod?: { def?: unknown } })._zod?.def\n if (def !== undefined) return canonicalStringify(def)\n }\n return canonicalStringify(check)\n}\n\n/** Strict-mode sort comparator that handles mixed string/number enums. */\nfunction compare(a: string | number, b: string | number): number {\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n}\n"],"names":[],"mappings":"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"}
|