attaform 0.27.6 → 0.29.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.
Files changed (192) hide show
  1. package/dist/abstract.d.mts +5 -4
  2. package/dist/abstract.mjs +4 -3
  3. package/dist/chunks/fingerprint.mjs +1 -2
  4. package/dist/chunks/fingerprint2.mjs +2 -3
  5. package/dist/dev/abstract.mjs +4 -0
  6. package/dist/{chunks → dev/chunks}/dev-key-collision-warnings.mjs +0 -1
  7. package/dist/{chunks → dev/chunks}/devtools.mjs +5 -6
  8. package/dist/{chunks/fingerprint.cjs → dev/chunks/fingerprint.mjs} +7 -10
  9. package/dist/{chunks/fingerprint2.cjs → dev/chunks/fingerprint2.mjs} +32 -35
  10. package/dist/dev/directive.mjs +1 -0
  11. package/dist/dev/history.mjs +89 -0
  12. package/dist/dev/index.mjs +5 -0
  13. package/dist/dev/runtime/plugins/attaform.mjs +40 -0
  14. package/dist/dev/shared/attaform-dev.A-TpJW0B.mjs +207 -0
  15. package/dist/dev/shared/attaform-dev.BO-71R54.mjs +820 -0
  16. package/dist/{shared/attaform.D6tk90Rc.cjs → dev/shared/attaform-dev.BgM6FdtA.mjs} +324 -73
  17. package/dist/dev/shared/attaform-dev.ButTkwHd.mjs +375 -0
  18. package/dist/{shared/attaform.BJGA_UOS.mjs → dev/shared/attaform-dev.BxfsuwBR.mjs} +8 -1
  19. package/dist/{shared/attaform.nMaz2C5P.mjs → dev/shared/attaform-dev.D8aoKb89.mjs} +190 -400
  20. package/dist/dev/shared/attaform-dev.DD5m2W51.mjs +220 -0
  21. package/dist/{shared/attaform.CKH2lGdL.mjs → dev/shared/attaform-dev.DHuydLAC.mjs} +3867 -4731
  22. package/dist/{shared/attaform.DYEr28Pt.mjs → dev/shared/attaform-dev.DrzObAZo.mjs} +6 -7
  23. package/dist/{shared/attaform.B1ZYt2Li.mjs → dev/shared/attaform-dev.q6UutkCx.mjs} +274 -672
  24. package/dist/dev/zod-v3.mjs +17 -0
  25. package/dist/dev/zod-v4.mjs +16 -0
  26. package/dist/dev/zod.mjs +5 -0
  27. package/dist/directive.d.mts +20 -0
  28. package/dist/directive.mjs +1 -0
  29. package/dist/esbuild.mjs +0 -1
  30. package/dist/history.d.mts +59 -0
  31. package/dist/history.mjs +89 -0
  32. package/dist/index.d.mts +14 -6
  33. package/dist/index.mjs +5 -4
  34. package/dist/nuxt.d.mts +10 -10
  35. package/dist/nuxt.mjs +5 -2
  36. package/dist/rollup.mjs +0 -1
  37. package/dist/rspack.d.mts +6 -1
  38. package/dist/rspack.mjs +0 -1
  39. package/dist/runtime/components/AttaformDevtoolsPanel.vue +9 -8
  40. package/dist/runtime/plugins/attaform.mjs +1 -2
  41. package/dist/shared/{attaform.CoR4mWfv.mjs → attaform.B0dKL8ST.mjs} +309 -46
  42. package/dist/shared/{attaform.Cs2Rbdlo.mjs → attaform.BK0cgu2K.mjs} +123 -140
  43. package/dist/shared/{attaform.B9Wyhfro.cjs → attaform.BndjUUYX.mjs} +11 -16
  44. package/dist/shared/{attaform.CQN9R62B.cjs → attaform.BxfsuwBR.mjs} +9 -4
  45. package/dist/shared/attaform.C2MVyuxC.mjs +811 -0
  46. package/dist/shared/{attaform.Fp3sCrVs.d.ts → attaform.CIWLMY-R.d.mts} +2 -2
  47. package/dist/shared/attaform.CZMAYwSK.mjs +6383 -0
  48. package/dist/shared/attaform.CZYt_5N_.mjs +207 -0
  49. package/dist/shared/{attaform.DniawQLP.d.cts → attaform.CsoeRi3P.d.mts} +490 -98
  50. package/dist/shared/attaform.Cvao8bW5.mjs +358 -0
  51. package/dist/shared/attaform.D0x-qSXm.mjs +197 -0
  52. package/dist/shared/{attaform.D8kliaKw.cjs → attaform.D1fnTifF.mjs} +279 -692
  53. package/dist/shared/{attaform.CHlJLAiv.d.mts → attaform.DDtqHYv1.d.mts} +155 -184
  54. package/dist/shared/{attaform.Biytrv0-.cjs → attaform.DffRL5pP.mjs} +215 -547
  55. package/dist/shared/attaform.DhnPb6nK.mjs +0 -1
  56. package/dist/shared/attaform.KvlEedlF.mjs +0 -1
  57. package/dist/shared/attaform.axHXVQO7.d.mts +44 -0
  58. package/dist/shared/attaform.v0fQtWyA.mjs +0 -1
  59. package/dist/transforms.d.mts +0 -22
  60. package/dist/transforms.mjs +1 -2
  61. package/dist/vite.d.mts +30 -9
  62. package/dist/vite.mjs +27 -4
  63. package/dist/webpack.d.mts +6 -1
  64. package/dist/webpack.mjs +0 -1
  65. package/dist/zod-v3.d.mts +13 -6
  66. package/dist/zod-v3.mjs +17 -4
  67. package/dist/zod-v4.d.mts +19 -26
  68. package/dist/zod-v4.mjs +16 -4
  69. package/dist/zod.d.mts +4 -3
  70. package/dist/zod.mjs +5 -4
  71. package/package.json +38 -20
  72. package/skills/attaform/SKILL.md +6 -2
  73. package/skills/attaform/references/custom-components.md +7 -2
  74. package/skills/attaform/references/errors.md +8 -3
  75. package/skills/attaform/references/saving.md +77 -0
  76. package/skills/attaform/references/wizards.md +10 -8
  77. package/dist/abstract.cjs +0 -48
  78. package/dist/abstract.cjs.map +0 -1
  79. package/dist/abstract.d.cts +0 -42
  80. package/dist/abstract.d.ts +0 -42
  81. package/dist/abstract.mjs.map +0 -1
  82. package/dist/chunks/dev-key-collision-warnings.cjs +0 -25
  83. package/dist/chunks/dev-key-collision-warnings.cjs.map +0 -1
  84. package/dist/chunks/dev-key-collision-warnings.mjs.map +0 -1
  85. package/dist/chunks/devtools.cjs +0 -157
  86. package/dist/chunks/devtools.cjs.map +0 -1
  87. package/dist/chunks/devtools.mjs.map +0 -1
  88. package/dist/chunks/fingerprint.cjs.map +0 -1
  89. package/dist/chunks/fingerprint.mjs.map +0 -1
  90. package/dist/chunks/fingerprint2.cjs.map +0 -1
  91. package/dist/chunks/fingerprint2.mjs.map +0 -1
  92. package/dist/esbuild.cjs +0 -28
  93. package/dist/esbuild.cjs.map +0 -1
  94. package/dist/esbuild.d.cts +0 -56
  95. package/dist/esbuild.d.ts +0 -56
  96. package/dist/esbuild.mjs.map +0 -1
  97. package/dist/index.cjs +0 -51
  98. package/dist/index.cjs.map +0 -1
  99. package/dist/index.d.cts +0 -249
  100. package/dist/index.d.ts +0 -249
  101. package/dist/index.mjs.map +0 -1
  102. package/dist/nuxt.cjs +0 -84
  103. package/dist/nuxt.cjs.map +0 -1
  104. package/dist/nuxt.d.cts +0 -66
  105. package/dist/nuxt.d.ts +0 -66
  106. package/dist/nuxt.mjs.map +0 -1
  107. package/dist/rollup.cjs +0 -24
  108. package/dist/rollup.cjs.map +0 -1
  109. package/dist/rollup.d.cts +0 -35
  110. package/dist/rollup.d.ts +0 -35
  111. package/dist/rollup.mjs.map +0 -1
  112. package/dist/rspack.cjs +0 -10
  113. package/dist/rspack.cjs.map +0 -1
  114. package/dist/rspack.d.cts +0 -40
  115. package/dist/rspack.d.ts +0 -40
  116. package/dist/rspack.mjs.map +0 -1
  117. package/dist/runtime/components/AttaformDevtoolsPanel.vue.d.ts +0 -7
  118. package/dist/runtime/components/DevtoolsValueTree.vue.d.ts +0 -35
  119. package/dist/runtime/plugins/attaform.cjs +0 -43
  120. package/dist/runtime/plugins/attaform.cjs.map +0 -1
  121. package/dist/runtime/plugins/attaform.d.cts +0 -5
  122. package/dist/runtime/plugins/attaform.d.ts +0 -5
  123. package/dist/runtime/plugins/attaform.mjs.map +0 -1
  124. package/dist/shared/attaform.B1ZYt2Li.mjs.map +0 -1
  125. package/dist/shared/attaform.B9Wyhfro.cjs.map +0 -1
  126. package/dist/shared/attaform.BGDV42hI.d.cts +0 -232
  127. package/dist/shared/attaform.BJGA_UOS.mjs.map +0 -1
  128. package/dist/shared/attaform.Biytrv0-.cjs.map +0 -1
  129. package/dist/shared/attaform.Bn0IzhD_.cjs +0 -800
  130. package/dist/shared/attaform.Bn0IzhD_.cjs.map +0 -1
  131. package/dist/shared/attaform.C9fPTxjB.d.cts +0 -41
  132. package/dist/shared/attaform.C9fPTxjB.d.ts +0 -41
  133. package/dist/shared/attaform.CKH2lGdL.mjs.map +0 -1
  134. package/dist/shared/attaform.CQN9R62B.cjs.map +0 -1
  135. package/dist/shared/attaform.CoR4mWfv.mjs.map +0 -1
  136. package/dist/shared/attaform.Cs2Rbdlo.mjs.map +0 -1
  137. package/dist/shared/attaform.D6tk90Rc.cjs.map +0 -1
  138. package/dist/shared/attaform.D8kliaKw.cjs.map +0 -1
  139. package/dist/shared/attaform.DLknk9nF.d.mts +0 -232
  140. package/dist/shared/attaform.DMxM2kol.mjs +0 -1275
  141. package/dist/shared/attaform.DMxM2kol.mjs.map +0 -1
  142. package/dist/shared/attaform.DRUT703x.d.cts +0 -56
  143. package/dist/shared/attaform.DRUT703x.d.ts +0 -56
  144. package/dist/shared/attaform.DYEr28Pt.mjs.map +0 -1
  145. package/dist/shared/attaform.DdQN7sgN.cjs +0 -1302
  146. package/dist/shared/attaform.DdQN7sgN.cjs.map +0 -1
  147. package/dist/shared/attaform.DhnPb6nK.mjs.map +0 -1
  148. package/dist/shared/attaform.DniawQLP.d.mts +0 -4763
  149. package/dist/shared/attaform.DniawQLP.d.ts +0 -4763
  150. package/dist/shared/attaform.DoQm_Vkd.cjs +0 -58
  151. package/dist/shared/attaform.DoQm_Vkd.cjs.map +0 -1
  152. package/dist/shared/attaform.DrvMscNX.cjs +0 -7697
  153. package/dist/shared/attaform.DrvMscNX.cjs.map +0 -1
  154. package/dist/shared/attaform.F2Q8iv38.d.ts +0 -2494
  155. package/dist/shared/attaform.FmqKO1Ex.d.cts +0 -2494
  156. package/dist/shared/attaform.KvlEedlF.mjs.map +0 -1
  157. package/dist/shared/attaform.RaTzp1WF.cjs +0 -26
  158. package/dist/shared/attaform.RaTzp1WF.cjs.map +0 -1
  159. package/dist/shared/attaform.nMaz2C5P.mjs.map +0 -1
  160. package/dist/shared/attaform.v0fQtWyA.mjs.map +0 -1
  161. package/dist/shared/attaform.yUrz7C2z.cjs +0 -29
  162. package/dist/shared/attaform.yUrz7C2z.cjs.map +0 -1
  163. package/dist/transforms.cjs +0 -12
  164. package/dist/transforms.cjs.map +0 -1
  165. package/dist/transforms.d.cts +0 -73
  166. package/dist/transforms.d.ts +0 -73
  167. package/dist/transforms.mjs.map +0 -1
  168. package/dist/vite.cjs +0 -363
  169. package/dist/vite.cjs.map +0 -1
  170. package/dist/vite.d.cts +0 -133
  171. package/dist/vite.d.ts +0 -133
  172. package/dist/vite.mjs.map +0 -1
  173. package/dist/webpack.cjs +0 -10
  174. package/dist/webpack.cjs.map +0 -1
  175. package/dist/webpack.d.cts +0 -37
  176. package/dist/webpack.d.ts +0 -37
  177. package/dist/webpack.mjs.map +0 -1
  178. package/dist/zod-v3.cjs +0 -53
  179. package/dist/zod-v3.cjs.map +0 -1
  180. package/dist/zod-v3.d.cts +0 -246
  181. package/dist/zod-v3.d.ts +0 -246
  182. package/dist/zod-v3.mjs.map +0 -1
  183. package/dist/zod-v4.cjs +0 -55
  184. package/dist/zod-v4.cjs.map +0 -1
  185. package/dist/zod-v4.d.cts +0 -172
  186. package/dist/zod-v4.d.ts +0 -172
  187. package/dist/zod-v4.mjs.map +0 -1
  188. package/dist/zod.cjs +0 -51
  189. package/dist/zod.cjs.map +0 -1
  190. package/dist/zod.d.cts +0 -7
  191. package/dist/zod.d.ts +0 -7
  192. package/dist/zod.mjs.map +0 -1
@@ -1,157 +0,0 @@
1
- 'use strict';
2
-
3
- const devtoolsShared = require('../shared/attaform.Biytrv0-.cjs');
4
-
5
- const INSPECTOR_ID = "attaform";
6
- const TIMELINE_LAYER_ID = "attaform:events";
7
- async function setupAttaformDevtools(app, registry) {
8
- let mod;
9
- try {
10
- mod = await import('@vue/devtools-api');
11
- } catch {
12
- return false;
13
- }
14
- const setupDevtoolsPlugin = mod.setupDevtoolsPlugin;
15
- if (typeof setupDevtoolsPlugin !== "function") return false;
16
- setupDevtoolsPlugin(
17
- {
18
- id: INSPECTOR_ID,
19
- label: "Attaform",
20
- packageName: "attaform",
21
- homepage: "https://github.com/attaform/Attaform",
22
- app,
23
- componentStateTypes: ["Attaform form"]
24
- },
25
- (api) => wire(api, app, registry)
26
- );
27
- return true;
28
- }
29
- function wire(api, app, registry) {
30
- const subscriberUnsubs = /* @__PURE__ */ new Map();
31
- api.addInspector({ id: INSPECTOR_ID, label: "Attaform", app });
32
- api.addTimelineLayer({ id: TIMELINE_LAYER_ID, label: "Attaform", color: 6000111 });
33
- function refreshTree() {
34
- api.sendInspectorTree(INSPECTOR_ID);
35
- }
36
- function refreshState() {
37
- api.sendInspectorState(INSPECTOR_ID);
38
- }
39
- function subscribeForm(state) {
40
- if (subscriberUnsubs.has(state.formKey)) return;
41
- const unsubChange = state.onFormChange(() => {
42
- refreshState();
43
- api.addTimelineEvent({
44
- layerId: TIMELINE_LAYER_ID,
45
- event: {
46
- time: Date.now(),
47
- title: "form.change",
48
- subtitle: state.formKey,
49
- // Devtools is dev-only — emit raw values. Consumers worried
50
- // about screen-share leaks should close the panel before
51
- // sharing, same as they would for the browser DevTools
52
- // console.
53
- data: { form: state.form.value }
54
- }
55
- });
56
- });
57
- const unsubSubmit = state.onSubmitSuccess(() => {
58
- api.addTimelineEvent({
59
- layerId: TIMELINE_LAYER_ID,
60
- event: {
61
- time: Date.now(),
62
- title: "submit.success",
63
- subtitle: state.formKey,
64
- data: { form: state.form.value }
65
- }
66
- });
67
- });
68
- const unsubReset = state.onReset(() => {
69
- refreshState();
70
- api.addTimelineEvent({
71
- layerId: TIMELINE_LAYER_ID,
72
- event: {
73
- time: Date.now(),
74
- title: "reset",
75
- subtitle: state.formKey
76
- }
77
- });
78
- });
79
- subscriberUnsubs.set(state.formKey, () => {
80
- unsubChange();
81
- unsubSubmit();
82
- unsubReset();
83
- });
84
- }
85
- function syncForms() {
86
- for (const [, state] of registry.forms) {
87
- subscribeForm(state);
88
- }
89
- for (const [formKey, unsub] of subscriberUnsubs) {
90
- if (!registry.forms.has(formKey)) {
91
- unsub();
92
- subscriberUnsubs.delete(formKey);
93
- }
94
- }
95
- }
96
- api.on.getInspectorTree((payload) => {
97
- if (payload.inspectorId !== INSPECTOR_ID) return;
98
- syncForms();
99
- payload.rootNodes = [...registry.forms.keys()].map((key) => ({
100
- id: `form:${key}`,
101
- label: key,
102
- tags: []
103
- }));
104
- });
105
- api.on.getInspectorState((payload) => {
106
- if (payload.inspectorId !== INSPECTOR_ID) return;
107
- if (!payload.nodeId.startsWith("form:")) return;
108
- const formKey = payload.nodeId.slice("form:".length);
109
- const state = registry.forms.get(formKey);
110
- if (state === void 0) return;
111
- payload.state["Form value"] = [
112
- {
113
- key: "form",
114
- value: state.form.value,
115
- editable: true
116
- }
117
- ];
118
- payload.state["Schema Errors"] = [
119
- ...[...state.schemaErrors.entries()].map(([k, v]) => ({
120
- key: String(k),
121
- value: v
122
- }))
123
- ];
124
- payload.state["User Errors"] = [
125
- ...[...state.userErrors.entries()].map(([k, v]) => ({
126
- key: String(k),
127
- value: v
128
- }))
129
- ];
130
- payload.state["Aggregates"] = [
131
- { key: "submitting", value: state.submitting.value },
132
- { key: "submissionAttempts", value: state.submissionAttempts.value },
133
- { key: "departAttempts", value: state.departAttempts.value },
134
- { key: "submitError", value: state.submitError.value },
135
- { key: "activeValidations", value: state.activeValidations.value }
136
- ];
137
- });
138
- api.on.editInspectorState((payload) => {
139
- if (payload.inspectorId !== INSPECTOR_ID) return;
140
- if (!payload.nodeId.startsWith("form:")) return;
141
- const formKey = payload.nodeId.slice("form:".length);
142
- const state = registry.forms.get(formKey);
143
- if (state === void 0) return;
144
- if (payload.path.length < 3) return;
145
- const section = payload.path[0];
146
- if (section !== "Form value") return;
147
- const segments = payload.path.slice(2);
148
- const { segments: canonicalPath } = devtoolsShared.canonicalizePath(segments);
149
- state.setValueAtPath(canonicalPath, payload.state.value);
150
- refreshState();
151
- });
152
- syncForms();
153
- refreshTree();
154
- }
155
-
156
- exports.setupAttaformDevtools = setupAttaformDevtools;
157
- //# sourceMappingURL=devtools.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"devtools.cjs","sources":["../../src/runtime/core/devtools.ts"],"sourcesContent":["import type { App } from 'vue'\nimport type { FormStore } from './create-form-store'\nimport type { AttaformRegistry } from './registry'\nimport type { GenericForm } from '../types/types-core'\nimport type { FormKey } from '../types/types-api'\nimport { canonicalizePath } from './paths'\n\n/**\n * Vue DevTools plugin wiring for attaform. Lazy-imported by\n * `createAttaform` under dev-mode guards so the production\n * bundle tree-shakes it out entirely.\n *\n * Registers:\n * - An inspector (per-app) that lists every registered form, with\n * nodes for form value / errors / aggregates / history.\n * - A timeline layer that emits events on submit start/success/\n * failure, reset, undo, redo, and form mutations.\n * - State editing — modifying a leaf inside the inspector tree\n * pushes through `state.setValueAtPath`, mutating the form.\n *\n * Tolerant of missing `@vue/devtools-api` — the peer dep is marked\n * optional. If the import fails, `setupAttaformDevtools` silently\n * no-ops so production builds / users without DevTools installed\n * don't see errors.\n */\n\nconst INSPECTOR_ID = 'attaform'\nconst TIMELINE_LAYER_ID = 'attaform:events'\n\ntype UnsafeDevtoolsApi = {\n addInspector(opts: { id: string; label: string; icon?: string; app: App }): void\n addTimelineLayer(opts: { id: string; label: string; color: number }): void\n sendInspectorTree(inspectorId: string): void\n sendInspectorState(inspectorId: string): void\n addTimelineEvent(payload: {\n layerId: string\n event: {\n time: number\n title: string\n subtitle?: string\n data?: Record<string, unknown>\n groupId?: string | number\n }\n }): void\n on: {\n getInspectorTree(\n handler: (payload: {\n inspectorId: string\n filter: string\n rootNodes: Array<{ id: string; label: string; tags?: unknown[] }>\n }) => void\n ): void\n getInspectorState(\n handler: (payload: {\n inspectorId: string\n nodeId: string\n state: Record<string, Array<{ key: string; value: unknown; editable?: boolean }>>\n }) => void\n ): void\n editInspectorState(\n handler: (payload: {\n inspectorId: string\n nodeId: string\n path: string[]\n state: { value: unknown; newKey?: string | null; remove?: boolean }\n }) => void\n ): void\n }\n}\n\ntype SetupDevtoolsPluginFn = (\n descriptor: {\n id: string\n label: string\n packageName?: string\n homepage?: string\n componentStateTypes?: string[]\n app: App\n },\n setup: (api: UnsafeDevtoolsApi) => void\n) => void\n\n/**\n * Install the DevTools plugin for the given Vue app + registry. Safe\n * to call in production — if `@vue/devtools-api` isn't installed, the\n * dynamic import fails and we log nothing. Returns `true` when\n * DevTools was wired successfully, `false` otherwise — useful for\n * tests.\n */\nexport async function setupAttaformDevtools(\n app: App,\n registry: AttaformRegistry\n): Promise<boolean> {\n let mod: { setupDevtoolsPlugin?: SetupDevtoolsPluginFn }\n try {\n mod = (await import('@vue/devtools-api')) as {\n setupDevtoolsPlugin?: SetupDevtoolsPluginFn\n }\n } catch {\n // Peer dep not installed — silently skip. Production builds pass\n // `{ devtools: false }` explicitly, but this catch covers the\n // \"dev without the peer dep\" case without a noisy warning.\n return false\n }\n const setupDevtoolsPlugin = mod.setupDevtoolsPlugin\n if (typeof setupDevtoolsPlugin !== 'function') return false\n\n setupDevtoolsPlugin(\n {\n id: INSPECTOR_ID,\n label: 'Attaform',\n packageName: 'attaform',\n homepage: 'https://github.com/attaform/Attaform',\n app,\n componentStateTypes: ['Attaform form'],\n },\n (api) => wire(api, app, registry)\n )\n return true\n}\n\nfunction wire(api: UnsafeDevtoolsApi, app: App, registry: AttaformRegistry): void {\n // Per-form subscriber bookkeeping — we keep the unsubscribers so\n // the registry's eviction path can detach them when a form is\n // disposed. Using a Map keyed by FormKey mirrors the registry.\n const subscriberUnsubs = new Map<FormKey, () => void>()\n\n api.addInspector({ id: INSPECTOR_ID, label: 'Attaform', app })\n api.addTimelineLayer({ id: TIMELINE_LAYER_ID, label: 'Attaform', color: 0x5b8def })\n\n function refreshTree(): void {\n api.sendInspectorTree(INSPECTOR_ID)\n }\n\n function refreshState(): void {\n api.sendInspectorState(INSPECTOR_ID)\n }\n\n function subscribeForm(state: FormStore<GenericForm>): void {\n if (subscriberUnsubs.has(state.formKey)) return\n const unsubChange = state.onFormChange(() => {\n refreshState()\n api.addTimelineEvent({\n layerId: TIMELINE_LAYER_ID,\n event: {\n time: Date.now(),\n title: 'form.change',\n subtitle: state.formKey,\n // Devtools is dev-only — emit raw values. Consumers worried\n // about screen-share leaks should close the panel before\n // sharing, same as they would for the browser DevTools\n // console.\n data: { form: state.form.value as Record<string, unknown> },\n },\n })\n })\n const unsubSubmit = state.onSubmitSuccess(() => {\n api.addTimelineEvent({\n layerId: TIMELINE_LAYER_ID,\n event: {\n time: Date.now(),\n title: 'submit.success',\n subtitle: state.formKey,\n data: { form: state.form.value as Record<string, unknown> },\n },\n })\n })\n const unsubReset = state.onReset(() => {\n refreshState()\n api.addTimelineEvent({\n layerId: TIMELINE_LAYER_ID,\n event: {\n time: Date.now(),\n title: 'reset',\n subtitle: state.formKey,\n },\n })\n })\n subscriberUnsubs.set(state.formKey, () => {\n unsubChange()\n unsubSubmit()\n unsubReset()\n })\n }\n\n // Subscribe all currently-registered forms + register as they're\n // added. The registry's `forms` Map is shallowReactive — we poll\n // once per render on refresh; for live change detection, each\n // useForm call that adds a new form triggers a tree/state refresh\n // via the form's own onFormChange emission on the first\n // applyFormReplacement.\n function syncForms(): void {\n for (const [, state] of registry.forms) {\n subscribeForm(state)\n }\n // Drop subscribers for forms that were evicted.\n for (const [formKey, unsub] of subscriberUnsubs) {\n if (!registry.forms.has(formKey)) {\n unsub()\n subscriberUnsubs.delete(formKey)\n }\n }\n }\n\n api.on.getInspectorTree((payload) => {\n if (payload.inspectorId !== INSPECTOR_ID) return\n syncForms()\n payload.rootNodes = [...registry.forms.keys()].map((key) => ({\n id: `form:${key}`,\n label: key,\n tags: [],\n }))\n })\n\n api.on.getInspectorState((payload) => {\n if (payload.inspectorId !== INSPECTOR_ID) return\n if (!payload.nodeId.startsWith('form:')) return\n const formKey = payload.nodeId.slice('form:'.length)\n const state = registry.forms.get(formKey)\n if (state === undefined) return\n // Devtools is dev-only — render raw values for everything,\n // including sensitive-named paths. Consumers concerned about\n // screen-share leaks should close the panel before sharing.\n payload.state['Form value'] = [\n {\n key: 'form',\n value: state.form.value,\n editable: true,\n },\n ]\n // Schema-driven and user-injected errors land in separate inspector\n // sections so devs can see the source distinction at a glance — a\n // user-injected entry surviving a successful submit, or a schema\n // entry that should have cleared after a value fix, are immediately\n // visible without cross-referencing call sites.\n payload.state['Schema Errors'] = [\n ...[...state.schemaErrors.entries()].map(([k, v]) => ({\n key: String(k),\n value: v as unknown,\n })),\n ]\n payload.state['User Errors'] = [\n ...[...state.userErrors.entries()].map(([k, v]) => ({\n key: String(k),\n value: v as unknown,\n })),\n ]\n payload.state['Aggregates'] = [\n { key: 'submitting', value: state.submitting.value },\n { key: 'submissionAttempts', value: state.submissionAttempts.value },\n { key: 'departAttempts', value: state.departAttempts.value },\n { key: 'submitError', value: state.submitError.value },\n { key: 'activeValidations', value: state.activeValidations.value },\n ]\n })\n\n api.on.editInspectorState((payload) => {\n if (payload.inspectorId !== INSPECTOR_ID) return\n if (!payload.nodeId.startsWith('form:')) return\n const formKey = payload.nodeId.slice('form:'.length)\n const state = registry.forms.get(formKey)\n if (state === undefined) return\n // payload.path is `['Form value', 'form', ...pathSegments]` — the\n // first two segments are the inspector section + key, the rest is\n // the target form path the user edited. Pass the segment array\n // directly to `canonicalizePath`: join('.') would collapse a\n // literal-dot field key (`{\"user.email\": ...}`) into two segments,\n // writing to the wrong leaf.\n if (payload.path.length < 3) return\n const section = payload.path[0]\n if (section !== 'Form value') return\n const segments = payload.path.slice(2)\n const { segments: canonicalPath } = canonicalizePath(segments)\n state.setValueAtPath(canonicalPath, payload.state.value)\n refreshState()\n })\n\n // Initial sync so existing forms show up.\n syncForms()\n refreshTree()\n}\n"],"names":["canonicalizePath"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"devtools.mjs","sources":["../../src/runtime/core/devtools.ts"],"sourcesContent":["import type { App } from 'vue'\nimport type { FormStore } from './create-form-store'\nimport type { AttaformRegistry } from './registry'\nimport type { GenericForm } from '../types/types-core'\nimport type { FormKey } from '../types/types-api'\nimport { canonicalizePath } from './paths'\n\n/**\n * Vue DevTools plugin wiring for attaform. Lazy-imported by\n * `createAttaform` under dev-mode guards so the production\n * bundle tree-shakes it out entirely.\n *\n * Registers:\n * - An inspector (per-app) that lists every registered form, with\n * nodes for form value / errors / aggregates / history.\n * - A timeline layer that emits events on submit start/success/\n * failure, reset, undo, redo, and form mutations.\n * - State editing — modifying a leaf inside the inspector tree\n * pushes through `state.setValueAtPath`, mutating the form.\n *\n * Tolerant of missing `@vue/devtools-api` — the peer dep is marked\n * optional. If the import fails, `setupAttaformDevtools` silently\n * no-ops so production builds / users without DevTools installed\n * don't see errors.\n */\n\nconst INSPECTOR_ID = 'attaform'\nconst TIMELINE_LAYER_ID = 'attaform:events'\n\ntype UnsafeDevtoolsApi = {\n addInspector(opts: { id: string; label: string; icon?: string; app: App }): void\n addTimelineLayer(opts: { id: string; label: string; color: number }): void\n sendInspectorTree(inspectorId: string): void\n sendInspectorState(inspectorId: string): void\n addTimelineEvent(payload: {\n layerId: string\n event: {\n time: number\n title: string\n subtitle?: string\n data?: Record<string, unknown>\n groupId?: string | number\n }\n }): void\n on: {\n getInspectorTree(\n handler: (payload: {\n inspectorId: string\n filter: string\n rootNodes: Array<{ id: string; label: string; tags?: unknown[] }>\n }) => void\n ): void\n getInspectorState(\n handler: (payload: {\n inspectorId: string\n nodeId: string\n state: Record<string, Array<{ key: string; value: unknown; editable?: boolean }>>\n }) => void\n ): void\n editInspectorState(\n handler: (payload: {\n inspectorId: string\n nodeId: string\n path: string[]\n state: { value: unknown; newKey?: string | null; remove?: boolean }\n }) => void\n ): void\n }\n}\n\ntype SetupDevtoolsPluginFn = (\n descriptor: {\n id: string\n label: string\n packageName?: string\n homepage?: string\n componentStateTypes?: string[]\n app: App\n },\n setup: (api: UnsafeDevtoolsApi) => void\n) => void\n\n/**\n * Install the DevTools plugin for the given Vue app + registry. Safe\n * to call in production — if `@vue/devtools-api` isn't installed, the\n * dynamic import fails and we log nothing. Returns `true` when\n * DevTools was wired successfully, `false` otherwise — useful for\n * tests.\n */\nexport async function setupAttaformDevtools(\n app: App,\n registry: AttaformRegistry\n): Promise<boolean> {\n let mod: { setupDevtoolsPlugin?: SetupDevtoolsPluginFn }\n try {\n mod = (await import('@vue/devtools-api')) as {\n setupDevtoolsPlugin?: SetupDevtoolsPluginFn\n }\n } catch {\n // Peer dep not installed — silently skip. Production builds pass\n // `{ devtools: false }` explicitly, but this catch covers the\n // \"dev without the peer dep\" case without a noisy warning.\n return false\n }\n const setupDevtoolsPlugin = mod.setupDevtoolsPlugin\n if (typeof setupDevtoolsPlugin !== 'function') return false\n\n setupDevtoolsPlugin(\n {\n id: INSPECTOR_ID,\n label: 'Attaform',\n packageName: 'attaform',\n homepage: 'https://github.com/attaform/Attaform',\n app,\n componentStateTypes: ['Attaform form'],\n },\n (api) => wire(api, app, registry)\n )\n return true\n}\n\nfunction wire(api: UnsafeDevtoolsApi, app: App, registry: AttaformRegistry): void {\n // Per-form subscriber bookkeeping — we keep the unsubscribers so\n // the registry's eviction path can detach them when a form is\n // disposed. Using a Map keyed by FormKey mirrors the registry.\n const subscriberUnsubs = new Map<FormKey, () => void>()\n\n api.addInspector({ id: INSPECTOR_ID, label: 'Attaform', app })\n api.addTimelineLayer({ id: TIMELINE_LAYER_ID, label: 'Attaform', color: 0x5b8def })\n\n function refreshTree(): void {\n api.sendInspectorTree(INSPECTOR_ID)\n }\n\n function refreshState(): void {\n api.sendInspectorState(INSPECTOR_ID)\n }\n\n function subscribeForm(state: FormStore<GenericForm>): void {\n if (subscriberUnsubs.has(state.formKey)) return\n const unsubChange = state.onFormChange(() => {\n refreshState()\n api.addTimelineEvent({\n layerId: TIMELINE_LAYER_ID,\n event: {\n time: Date.now(),\n title: 'form.change',\n subtitle: state.formKey,\n // Devtools is dev-only — emit raw values. Consumers worried\n // about screen-share leaks should close the panel before\n // sharing, same as they would for the browser DevTools\n // console.\n data: { form: state.form.value as Record<string, unknown> },\n },\n })\n })\n const unsubSubmit = state.onSubmitSuccess(() => {\n api.addTimelineEvent({\n layerId: TIMELINE_LAYER_ID,\n event: {\n time: Date.now(),\n title: 'submit.success',\n subtitle: state.formKey,\n data: { form: state.form.value as Record<string, unknown> },\n },\n })\n })\n const unsubReset = state.onReset(() => {\n refreshState()\n api.addTimelineEvent({\n layerId: TIMELINE_LAYER_ID,\n event: {\n time: Date.now(),\n title: 'reset',\n subtitle: state.formKey,\n },\n })\n })\n subscriberUnsubs.set(state.formKey, () => {\n unsubChange()\n unsubSubmit()\n unsubReset()\n })\n }\n\n // Subscribe all currently-registered forms + register as they're\n // added. The registry's `forms` Map is shallowReactive — we poll\n // once per render on refresh; for live change detection, each\n // useForm call that adds a new form triggers a tree/state refresh\n // via the form's own onFormChange emission on the first\n // applyFormReplacement.\n function syncForms(): void {\n for (const [, state] of registry.forms) {\n subscribeForm(state)\n }\n // Drop subscribers for forms that were evicted.\n for (const [formKey, unsub] of subscriberUnsubs) {\n if (!registry.forms.has(formKey)) {\n unsub()\n subscriberUnsubs.delete(formKey)\n }\n }\n }\n\n api.on.getInspectorTree((payload) => {\n if (payload.inspectorId !== INSPECTOR_ID) return\n syncForms()\n payload.rootNodes = [...registry.forms.keys()].map((key) => ({\n id: `form:${key}`,\n label: key,\n tags: [],\n }))\n })\n\n api.on.getInspectorState((payload) => {\n if (payload.inspectorId !== INSPECTOR_ID) return\n if (!payload.nodeId.startsWith('form:')) return\n const formKey = payload.nodeId.slice('form:'.length)\n const state = registry.forms.get(formKey)\n if (state === undefined) return\n // Devtools is dev-only — render raw values for everything,\n // including sensitive-named paths. Consumers concerned about\n // screen-share leaks should close the panel before sharing.\n payload.state['Form value'] = [\n {\n key: 'form',\n value: state.form.value,\n editable: true,\n },\n ]\n // Schema-driven and user-injected errors land in separate inspector\n // sections so devs can see the source distinction at a glance — a\n // user-injected entry surviving a successful submit, or a schema\n // entry that should have cleared after a value fix, are immediately\n // visible without cross-referencing call sites.\n payload.state['Schema Errors'] = [\n ...[...state.schemaErrors.entries()].map(([k, v]) => ({\n key: String(k),\n value: v as unknown,\n })),\n ]\n payload.state['User Errors'] = [\n ...[...state.userErrors.entries()].map(([k, v]) => ({\n key: String(k),\n value: v as unknown,\n })),\n ]\n payload.state['Aggregates'] = [\n { key: 'submitting', value: state.submitting.value },\n { key: 'submissionAttempts', value: state.submissionAttempts.value },\n { key: 'departAttempts', value: state.departAttempts.value },\n { key: 'submitError', value: state.submitError.value },\n { key: 'activeValidations', value: state.activeValidations.value },\n ]\n })\n\n api.on.editInspectorState((payload) => {\n if (payload.inspectorId !== INSPECTOR_ID) return\n if (!payload.nodeId.startsWith('form:')) return\n const formKey = payload.nodeId.slice('form:'.length)\n const state = registry.forms.get(formKey)\n if (state === undefined) return\n // payload.path is `['Form value', 'form', ...pathSegments]` — the\n // first two segments are the inspector section + key, the rest is\n // the target form path the user edited. Pass the segment array\n // directly to `canonicalizePath`: join('.') would collapse a\n // literal-dot field key (`{\"user.email\": ...}`) into two segments,\n // writing to the wrong leaf.\n if (payload.path.length < 3) return\n const section = payload.path[0]\n if (section !== 'Form value') return\n const segments = payload.path.slice(2)\n const { segments: canonicalPath } = canonicalizePath(segments)\n state.setValueAtPath(canonicalPath, payload.state.value)\n refreshState()\n })\n\n // Initial sync so existing forms show up.\n syncForms()\n refreshTree()\n}\n"],"names":[],"mappings":";;AA0BA,MAAM,YAAA,GAAe,UAAA;AACrB,MAAM,iBAAA,GAAoB,iBAAA;AA8D1B,eAAsB,qBAAA,CACpB,KACA,QAAA,EACkB;AAClB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAO,MAAM,OAAO,mBAAmB,CAAA;AAAA,EAGzC,CAAA,CAAA,MAAQ;AAIN,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,sBAAsB,GAAA,CAAI,mBAAA;AAChC,EAAA,IAAI,OAAO,mBAAA,KAAwB,UAAA,EAAY,OAAO,KAAA;AAEtD,EAAA,mBAAA;AAAA,IACE;AAAA,MACE,EAAA,EAAI,YAAA;AAAA,MACJ,KAAA,EAAO,UAAA;AAAA,MACP,WAAA,EAAa,UAAA;AAAA,MACb,QAAA,EAAU,sCAAA;AAAA,MACV,GAAA;AAAA,MACA,mBAAA,EAAqB,CAAC,eAAe;AAAA,KACvC;AAAA,IACA,CAAC,GAAA,KAAQ,IAAA,CAAK,GAAA,EAAK,KAAK,QAAQ;AAAA,GAClC;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,IAAA,CAAK,GAAA,EAAwB,GAAA,EAAU,QAAA,EAAkC;AAIhF,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAyB;AAEtD,EAAA,GAAA,CAAI,aAAa,EAAE,EAAA,EAAI,cAAc,KAAA,EAAO,UAAA,EAAY,KAAK,CAAA;AAC7D,EAAA,GAAA,CAAI,gBAAA,CAAiB,EAAE,EAAA,EAAI,iBAAA,EAAmB,OAAO,UAAA,EAAY,KAAA,EAAO,SAAU,CAAA;AAElF,EAAA,SAAS,WAAA,GAAoB;AAC3B,IAAA,GAAA,CAAI,kBAAkB,YAAY,CAAA;AAAA,EACpC;AAEA,EAAA,SAAS,YAAA,GAAqB;AAC5B,IAAA,GAAA,CAAI,mBAAmB,YAAY,CAAA;AAAA,EACrC;AAEA,EAAA,SAAS,cAAc,KAAA,EAAqC;AAC1D,IAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AACzC,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,YAAA,CAAa,MAAM;AAC3C,MAAA,YAAA,EAAa;AACb,MAAA,GAAA,CAAI,gBAAA,CAAiB;AAAA,QACnB,OAAA,EAAS,iBAAA;AAAA,QACT,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,KAAK,GAAA,EAAI;AAAA,UACf,KAAA,EAAO,aAAA;AAAA,UACP,UAAU,KAAA,CAAM,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAKhB,IAAA,EAAM,EAAE,IAAA,EAAM,KAAA,CAAM,KAAK,KAAA;AAAiC;AAC5D,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AACD,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,eAAA,CAAgB,MAAM;AAC9C,MAAA,GAAA,CAAI,gBAAA,CAAiB;AAAA,QACnB,OAAA,EAAS,iBAAA;AAAA,QACT,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,KAAK,GAAA,EAAI;AAAA,UACf,KAAA,EAAO,gBAAA;AAAA,UACP,UAAU,KAAA,CAAM,OAAA;AAAA,UAChB,IAAA,EAAM,EAAE,IAAA,EAAM,KAAA,CAAM,KAAK,KAAA;AAAiC;AAC5D,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AACD,IAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAQ,MAAM;AACrC,MAAA,YAAA,EAAa;AACb,MAAA,GAAA,CAAI,gBAAA,CAAiB;AAAA,QACnB,OAAA,EAAS,iBAAA;AAAA,QACT,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,KAAK,GAAA,EAAI;AAAA,UACf,KAAA,EAAO,OAAA;AAAA,UACP,UAAU,KAAA,CAAM;AAAA;AAClB,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AACD,IAAA,gBAAA,CAAiB,GAAA,CAAI,KAAA,CAAM,OAAA,EAAS,MAAM;AACxC,MAAA,WAAA,EAAY;AACZ,MAAA,WAAA,EAAY;AACZ,MAAA,UAAA,EAAW;AAAA,IACb,CAAC,CAAA;AAAA,EACH;AAQA,EAAA,SAAS,SAAA,GAAkB;AACzB,IAAA,KAAA,MAAW,GAAG,KAAK,CAAA,IAAK,SAAS,KAAA,EAAO;AACtC,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB;AAEA,IAAA,KAAA,MAAW,CAAC,OAAA,EAAS,KAAK,CAAA,IAAK,gBAAA,EAAkB;AAC/C,MAAA,IAAI,CAAC,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAChC,QAAA,KAAA,EAAM;AACN,QAAA,gBAAA,CAAiB,OAAO,OAAO,CAAA;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,GAAA,CAAI,EAAA,CAAG,gBAAA,CAAiB,CAAC,OAAA,KAAY;AACnC,IAAA,IAAI,OAAA,CAAQ,gBAAgB,YAAA,EAAc;AAC1C,IAAA,SAAA,EAAU;AACV,IAAA,OAAA,CAAQ,SAAA,GAAY,CAAC,GAAG,QAAA,CAAS,KAAA,CAAM,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,GAAA,MAAS;AAAA,MAC3D,EAAA,EAAI,QAAQ,GAAG,CAAA,CAAA;AAAA,MACf,KAAA,EAAO,GAAA;AAAA,MACP,MAAM;AAAC,KACT,CAAE,CAAA;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,GAAA,CAAI,EAAA,CAAG,iBAAA,CAAkB,CAAC,OAAA,KAAY;AACpC,IAAA,IAAI,OAAA,CAAQ,gBAAgB,YAAA,EAAc;AAC1C,IAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,CAAO,UAAA,CAAW,OAAO,CAAA,EAAG;AACzC,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,QAAQ,MAAM,CAAA;AACnD,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AACxC,IAAA,IAAI,UAAU,MAAA,EAAW;AAIzB,IAAA,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAA,GAAI;AAAA,MAC5B;AAAA,QACE,GAAA,EAAK,MAAA;AAAA,QACL,KAAA,EAAO,MAAM,IAAA,CAAK,KAAA;AAAA,QAClB,QAAA,EAAU;AAAA;AACZ,KACF;AAMA,IAAA,OAAA,CAAQ,KAAA,CAAM,eAAe,CAAA,GAAI;AAAA,MAC/B,GAAG,CAAC,GAAG,KAAA,CAAM,YAAA,CAAa,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,MAAO;AAAA,QACpD,GAAA,EAAK,OAAO,CAAC,CAAA;AAAA,QACb,KAAA,EAAO;AAAA,OACT,CAAE;AAAA,KACJ;AACA,IAAA,OAAA,CAAQ,KAAA,CAAM,aAAa,CAAA,GAAI;AAAA,MAC7B,GAAG,CAAC,GAAG,KAAA,CAAM,UAAA,CAAW,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,MAAO;AAAA,QAClD,GAAA,EAAK,OAAO,CAAC,CAAA;AAAA,QACb,KAAA,EAAO;AAAA,OACT,CAAE;AAAA,KACJ;AACA,IAAA,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAA,GAAI;AAAA,MAC5B,EAAE,GAAA,EAAK,YAAA,EAAc,KAAA,EAAO,KAAA,CAAM,WAAW,KAAA,EAAM;AAAA,MACnD,EAAE,GAAA,EAAK,oBAAA,EAAsB,KAAA,EAAO,KAAA,CAAM,mBAAmB,KAAA,EAAM;AAAA,MACnE,EAAE,GAAA,EAAK,gBAAA,EAAkB,KAAA,EAAO,KAAA,CAAM,eAAe,KAAA,EAAM;AAAA,MAC3D,EAAE,GAAA,EAAK,aAAA,EAAe,KAAA,EAAO,KAAA,CAAM,YAAY,KAAA,EAAM;AAAA,MACrD,EAAE,GAAA,EAAK,mBAAA,EAAqB,KAAA,EAAO,KAAA,CAAM,kBAAkB,KAAA;AAAM,KACnE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,GAAA,CAAI,EAAA,CAAG,kBAAA,CAAmB,CAAC,OAAA,KAAY;AACrC,IAAA,IAAI,OAAA,CAAQ,gBAAgB,YAAA,EAAc;AAC1C,IAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,CAAO,UAAA,CAAW,OAAO,CAAA,EAAG;AACzC,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,QAAQ,MAAM,CAAA;AACnD,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AACxC,IAAA,IAAI,UAAU,MAAA,EAAW;AAOzB,IAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG;AAC7B,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAC9B,IAAA,IAAI,YAAY,YAAA,EAAc;AAC9B,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACrC,IAAA,MAAM,EAAE,QAAA,EAAU,aAAA,EAAc,GAAI,iBAAiB,QAAQ,CAAA;AAC7D,IAAA,KAAA,CAAM,cAAA,CAAe,aAAA,EAAe,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA;AACvD,IAAA,YAAA,EAAa;AAAA,EACf,CAAC,CAAA;AAGD,EAAA,SAAA,EAAU;AACV,EAAA,WAAA,EAAY;AACd;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"fingerprint.cjs","sources":["../../src/runtime/adapters/zod-v3/fingerprint.ts"],"sourcesContent":["import type { z } from 'zod-v3'\nimport { canonicalStringify } from '../../core/canonical-stringify'\n\n/**\n * Compute a structural fingerprint for a Zod v3 schema.\n *\n * Same contract as the v4 counterpart — deterministic across\n * reference-distinct but structurally-equal schemas, key-order-\n * insensitive for `z.object` shapes, membership-order-insensitive\n * for `z.union` options, idempotent across calls. See\n * `src/runtime/adapters/zod-v4/fingerprint.ts` for the full\n * rationale and the list of compromises (function-valued\n * refinements / transforms / non-deterministic default factories\n * collapse to opaque `fn:*` sentinels).\n *\n * Caching is per-call, not module-global: cycles mean a cached\n * mid-traversal result from one call is invalid for another\n * (the `<cyclic>` sentinel's meaning depends on the starting\n * node). A WeakSet guards against cycles introduced by `z.lazy`.\n */\n\ntype V3Schema = z.ZodTypeAny\n\ninterface V3Def {\n readonly typeName?: string\n readonly shape?: () => Record<string, V3Schema>\n readonly type?: V3Schema\n readonly keyType?: V3Schema\n readonly valueType?: V3Schema\n readonly items?: readonly V3Schema[]\n readonly options?: readonly V3Schema[]\n readonly discriminator?: string\n // ZodEnum stores its admitted values as an array; ZodNativeEnum\n // stores them as the enum OBJECT (`{Red: 'red', '0': 'Red'}` for a\n // numeric enum). The fingerprint walker handles the two shapes in\n // separate branches.\n readonly values?: readonly unknown[] | Record<string, unknown>\n readonly value?: unknown\n readonly innerType?: V3Schema\n readonly defaultValue?: () => unknown\n readonly checks?: readonly unknown[]\n readonly schema?: V3Schema\n readonly effect?: { readonly type?: string }\n readonly getter?: () => V3Schema\n readonly left?: V3Schema\n readonly right?: V3Schema\n readonly catchValue?: () => unknown\n // ZodPipeline stores its input + output sides on `in` / `out`\n // respectively — NOT on `schema`. The pre-fix walker read `schema`\n // (always `undefined`) and emitted `ZodPipeline(?)` for every\n // pipeline.\n readonly in?: V3Schema\n readonly out?: V3Schema\n}\n\nconst cyclicSentinel = '<cyclic>'\n\nexport function fingerprintZodSchema(schema: V3Schema): string {\n const cache = new WeakMap<object, string>()\n const inProgress = new WeakSet<object>()\n return visit(schema, cache, inProgress)\n}\n\nfunction visit(\n schema: V3Schema,\n cache: WeakMap<object, string>,\n inProgress: WeakSet<object>\n): string {\n const key = schema as unknown as object\n const cached = cache.get(key)\n if (cached !== undefined) return cached\n if (inProgress.has(key)) return cyclicSentinel\n inProgress.add(key)\n try {\n const computed = computeFingerprint(schema, cache, inProgress)\n cache.set(key, computed)\n return computed\n } finally {\n inProgress.delete(key)\n }\n}\n\nfunction getDef(schema: V3Schema): V3Def {\n return (schema as unknown as { _def: V3Def })._def\n}\n\nfunction computeFingerprint(\n schema: V3Schema,\n cache: WeakMap<object, string>,\n inProgress: WeakSet<object>\n): string {\n const def = getDef(schema)\n const kind = def.typeName ?? 'ZodUnknown'\n const recurse = (child: V3Schema): string => visit(child, cache, inProgress)\n\n switch (kind) {\n case 'ZodString':\n case 'ZodNumber':\n case 'ZodBigInt':\n case 'ZodDate':\n return `${kind}${formatChecks(def.checks)}`\n\n case 'ZodBoolean':\n case 'ZodNull':\n case 'ZodUndefined':\n case 'ZodAny':\n case 'ZodUnknown':\n case 'ZodNaN':\n case 'ZodVoid':\n case 'ZodNever':\n return kind\n\n case 'ZodLiteral':\n return `ZodLiteral:${canonicalStringify(def.value)}`\n\n case 'ZodEnum': {\n // ZodEnum stores its admitted values as an array on `_def.values`.\n // Sort + canonicalStringify for a deterministic fingerprint.\n const values = Array.isArray(def.values) ? def.values : []\n const sorted = [...values].sort((a, b) => {\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n })\n return `ZodEnum:${canonicalStringify(sorted)}`\n }\n\n case 'ZodNativeEnum': {\n // ZodNativeEnum stores the enum OBJECT on `_def.values` (e.g.\n // `{Red: 'red'}` for a string enum or `{A: 0, '0': 'A'}` for a\n // numeric enum). The pre-fix walker shared the ZodEnum branch\n // which did `[...values]` — that throws `TypeError: not\n // iterable` on the object. Use `Object.values` to extract the\n // admitted runtime members; numeric enums include their\n // reverse-mapped string keys, which is fine for fingerprint\n // determinism (both forms are valid Zod inputs).\n const values =\n def.values && typeof def.values === 'object' && !Array.isArray(def.values)\n ? Object.values(def.values)\n : []\n const sorted = [...values].sort((a, b) => {\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n })\n return `ZodNativeEnum:${canonicalStringify(sorted)}`\n }\n\n case 'ZodObject': {\n const shape = readShapeSafely(def)\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 // Object-level `formatChecks` matches v4's `object{…}${formatChecks(schema)}`\n // (`fingerprint.ts:148`). ZodObject rarely carries `_def.checks`\n // in v3 — the call is structurally for parity rather than\n // expected-to-fire — but consumers who reach through a custom\n // ZodObject builder that stores extra constraints get them\n // surfaced symmetrically.\n return `ZodObject{${sortedEntries.join(',')}}${formatChecks(def.checks)}`\n }\n\n case 'ZodArray':\n return `ZodArray[${def.type === undefined ? '?' : recurse(def.type)}]${formatChecks(def.checks)}`\n\n case 'ZodTuple': {\n const items = def.items ?? []\n return `ZodTuple[${items.map(recurse).join(',')}]`\n }\n\n case 'ZodRecord': {\n const keyPart = def.keyType === undefined ? '?' : recurse(def.keyType)\n const valuePart = def.valueType === undefined ? '?' : recurse(def.valueType)\n return `ZodRecord<${keyPart},${valuePart}>`\n }\n\n case 'ZodUnion': {\n const options = (def.options ?? []).map(recurse).sort()\n return `ZodUnion(${options.join('|')})`\n }\n\n case 'ZodDiscriminatedUnion': {\n const disc = def.discriminator ?? '?'\n const options = (def.options ?? []).map(recurse).sort()\n return `ZodDiscriminatedUnion[${JSON.stringify(disc)}](${options.join('|')})`\n }\n\n case 'ZodOptional': {\n const inner = def.innerType\n return inner === undefined ? 'ZodOptional(?)' : `ZodOptional(${recurse(inner)})`\n }\n\n case 'ZodNullable': {\n const inner = def.innerType\n return inner === undefined ? 'ZodNullable(?)' : `ZodNullable(${recurse(inner)})`\n }\n\n case 'ZodDefault': {\n const inner = def.innerType\n // v3 stores defaults as a factory: `defaultValue: () => X`.\n // Call it twice and compare with Object.is — non-deterministic\n // factories (`() => new Date()`) return distinct objects each\n // call, so we collapse to `fn:*` to stay idempotent. Pure\n // factories that return the same primitive / cached reference\n // serialise normally.\n return `ZodDefault[${defaultFactoryRepr(def.defaultValue)}](${\n inner === undefined ? '?' : recurse(inner)\n })`\n }\n\n case 'ZodReadonly': {\n const inner = def.innerType\n return inner === undefined ? 'ZodReadonly(?)' : `ZodReadonly(${recurse(inner)})`\n }\n\n case 'ZodEffects': {\n // `.refine` / `.transform` / `.preprocess` — the effect function\n // isn't stably hashable. We can distinguish effect kinds (refine\n // vs transform) via `def.effect.type` and fold that into the\n // fingerprint, but the function body collapses to an opaque\n // sentinel.\n const effectType = def.effect?.type ?? 'effect'\n const inner = def.schema\n return `ZodEffects:${effectType}:fn:*(${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'ZodPipeline': {\n // Internally `z.pipe(a, b)` — `.in` and `.out` live on the def\n // (NOT `.schema`). The pre-fix walker read `def.schema`\n // (undefined for a pipeline) so every pipeline collapsed to\n // `ZodPipeline(?)`. Read the input side first (mirrors v4's\n // `unwrapPipe` which returns `in ?? out`); the output side is\n // a derived shape rather than a consumer-authored schema.\n const inner = def.in ?? def.out\n return inner === undefined ? 'ZodPipeline(?)' : `ZodPipeline(${recurse(inner)})`\n }\n\n case 'ZodCatch': {\n const inner = def.innerType ?? def.schema\n const catchRepr = defaultFactoryRepr(def.catchValue)\n return `ZodCatch[${catchRepr}](${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'ZodLazy': {\n const resolve = def.getter\n if (typeof resolve !== 'function') return 'ZodLazy(?)'\n try {\n const inner = resolve()\n return `ZodLazy(${recurse(inner)})`\n } catch {\n return 'ZodLazy(?)'\n }\n }\n\n case 'ZodIntersection': {\n const leftPart = def.left === undefined ? '?' : recurse(def.left)\n const rightPart = def.right === undefined ? '?' : recurse(def.right)\n const parts = [leftPart, rightPart].sort()\n return `ZodIntersection(${parts.join('&')})`\n }\n\n case 'ZodSet': {\n // ZodSet stores its element type on `_def.valueType` (same slot\n // ZodRecord uses for its value type). The pre-fix walker fell\n // through to the opaque default branch, so `z.set(z.string())`\n // and `z.set(z.number())` collapsed to the same `ZodSet:*`.\n // Mirrors v4's `set<element>${formatChecks(schema)}`.\n const inner = def.valueType\n return inner === undefined\n ? 'ZodSet(?)'\n : `ZodSet<${recurse(inner)}>${formatChecks(def.checks)}`\n }\n\n case 'ZodBranded': {\n // ZodBranded stores its inner on `_def.type` (the v3 quirk; v4's\n // brand is type-only). The pre-fix walker fell through to the\n // opaque default branch and lost the inner's shape entirely, so\n // `z.string().brand<'A'>()` and `z.number().brand<'B'>()`\n // collapsed to the same `ZodBranded:*`. Brand annotations are\n // type-level only at runtime, so emit just the inner's\n // fingerprint with a transparent wrapper.\n const inner = def.type\n return inner === undefined ? 'ZodBranded(?)' : `ZodBranded(${recurse(inner)})`\n }\n\n // Structural opacity — schemas whose runtime behaviour isn't\n // introspectable via `_def` fall here. Still distinguishable\n // from other kinds by the returned string.\n case 'ZodPromise':\n case 'ZodFunction':\n case 'ZodMap':\n case 'ZodSymbol':\n default:\n return `${kind}:*`\n }\n}\n\nfunction readShapeSafely(def: V3Def): Record<string, V3Schema> {\n if (typeof def.shape !== 'function') return {}\n try {\n return def.shape()\n } catch {\n return {}\n }\n}\n\n/**\n * Render a v3 default / catch factory. Called twice; if the two\n * results differ (by `Object.is`), the factory is non-deterministic\n * and we collapse to `fn:*` to preserve idempotence. Same fix as\n * v4's `defaultValueRepr` — factories like `() => new Date()` would\n * otherwise make the fingerprint time-dependent.\n */\nfunction defaultFactoryRepr(factory: (() => unknown) | undefined): string {\n if (typeof factory !== 'function') return 'none'\n let first: unknown\n let second: unknown\n try {\n first = factory()\n second = factory()\n } catch {\n return 'fn:*'\n }\n if (!Object.is(first, second)) return 'fn:*'\n if (typeof first === 'function') return 'fn:*'\n return canonicalStringify(first)\n}\n\nfunction formatChecks(checks: readonly unknown[] | undefined): string {\n if (!Array.isArray(checks) || checks.length === 0) return ''\n const parts = checks.map((c) => canonicalStringify(c)).sort()\n return `[${parts.join(';')}]`\n}\n"],"names":["canonicalStringify"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"fingerprint.mjs","sources":["../../src/runtime/adapters/zod-v3/fingerprint.ts"],"sourcesContent":["import type { z } from 'zod-v3'\nimport { canonicalStringify } from '../../core/canonical-stringify'\n\n/**\n * Compute a structural fingerprint for a Zod v3 schema.\n *\n * Same contract as the v4 counterpart — deterministic across\n * reference-distinct but structurally-equal schemas, key-order-\n * insensitive for `z.object` shapes, membership-order-insensitive\n * for `z.union` options, idempotent across calls. See\n * `src/runtime/adapters/zod-v4/fingerprint.ts` for the full\n * rationale and the list of compromises (function-valued\n * refinements / transforms / non-deterministic default factories\n * collapse to opaque `fn:*` sentinels).\n *\n * Caching is per-call, not module-global: cycles mean a cached\n * mid-traversal result from one call is invalid for another\n * (the `<cyclic>` sentinel's meaning depends on the starting\n * node). A WeakSet guards against cycles introduced by `z.lazy`.\n */\n\ntype V3Schema = z.ZodTypeAny\n\ninterface V3Def {\n readonly typeName?: string\n readonly shape?: () => Record<string, V3Schema>\n readonly type?: V3Schema\n readonly keyType?: V3Schema\n readonly valueType?: V3Schema\n readonly items?: readonly V3Schema[]\n readonly options?: readonly V3Schema[]\n readonly discriminator?: string\n // ZodEnum stores its admitted values as an array; ZodNativeEnum\n // stores them as the enum OBJECT (`{Red: 'red', '0': 'Red'}` for a\n // numeric enum). The fingerprint walker handles the two shapes in\n // separate branches.\n readonly values?: readonly unknown[] | Record<string, unknown>\n readonly value?: unknown\n readonly innerType?: V3Schema\n readonly defaultValue?: () => unknown\n readonly checks?: readonly unknown[]\n readonly schema?: V3Schema\n readonly effect?: { readonly type?: string }\n readonly getter?: () => V3Schema\n readonly left?: V3Schema\n readonly right?: V3Schema\n readonly catchValue?: () => unknown\n // ZodPipeline stores its input + output sides on `in` / `out`\n // respectively — NOT on `schema`. The pre-fix walker read `schema`\n // (always `undefined`) and emitted `ZodPipeline(?)` for every\n // pipeline.\n readonly in?: V3Schema\n readonly out?: V3Schema\n}\n\nconst cyclicSentinel = '<cyclic>'\n\nexport function fingerprintZodSchema(schema: V3Schema): string {\n const cache = new WeakMap<object, string>()\n const inProgress = new WeakSet<object>()\n return visit(schema, cache, inProgress)\n}\n\nfunction visit(\n schema: V3Schema,\n cache: WeakMap<object, string>,\n inProgress: WeakSet<object>\n): string {\n const key = schema as unknown as object\n const cached = cache.get(key)\n if (cached !== undefined) return cached\n if (inProgress.has(key)) return cyclicSentinel\n inProgress.add(key)\n try {\n const computed = computeFingerprint(schema, cache, inProgress)\n cache.set(key, computed)\n return computed\n } finally {\n inProgress.delete(key)\n }\n}\n\nfunction getDef(schema: V3Schema): V3Def {\n return (schema as unknown as { _def: V3Def })._def\n}\n\nfunction computeFingerprint(\n schema: V3Schema,\n cache: WeakMap<object, string>,\n inProgress: WeakSet<object>\n): string {\n const def = getDef(schema)\n const kind = def.typeName ?? 'ZodUnknown'\n const recurse = (child: V3Schema): string => visit(child, cache, inProgress)\n\n switch (kind) {\n case 'ZodString':\n case 'ZodNumber':\n case 'ZodBigInt':\n case 'ZodDate':\n return `${kind}${formatChecks(def.checks)}`\n\n case 'ZodBoolean':\n case 'ZodNull':\n case 'ZodUndefined':\n case 'ZodAny':\n case 'ZodUnknown':\n case 'ZodNaN':\n case 'ZodVoid':\n case 'ZodNever':\n return kind\n\n case 'ZodLiteral':\n return `ZodLiteral:${canonicalStringify(def.value)}`\n\n case 'ZodEnum': {\n // ZodEnum stores its admitted values as an array on `_def.values`.\n // Sort + canonicalStringify for a deterministic fingerprint.\n const values = Array.isArray(def.values) ? def.values : []\n const sorted = [...values].sort((a, b) => {\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n })\n return `ZodEnum:${canonicalStringify(sorted)}`\n }\n\n case 'ZodNativeEnum': {\n // ZodNativeEnum stores the enum OBJECT on `_def.values` (e.g.\n // `{Red: 'red'}` for a string enum or `{A: 0, '0': 'A'}` for a\n // numeric enum). The pre-fix walker shared the ZodEnum branch\n // which did `[...values]` — that throws `TypeError: not\n // iterable` on the object. Use `Object.values` to extract the\n // admitted runtime members; numeric enums include their\n // reverse-mapped string keys, which is fine for fingerprint\n // determinism (both forms are valid Zod inputs).\n const values =\n def.values && typeof def.values === 'object' && !Array.isArray(def.values)\n ? Object.values(def.values)\n : []\n const sorted = [...values].sort((a, b) => {\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n })\n return `ZodNativeEnum:${canonicalStringify(sorted)}`\n }\n\n case 'ZodObject': {\n const shape = readShapeSafely(def)\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 // Object-level `formatChecks` matches v4's `object{…}${formatChecks(schema)}`\n // (`fingerprint.ts:148`). ZodObject rarely carries `_def.checks`\n // in v3 — the call is structurally for parity rather than\n // expected-to-fire — but consumers who reach through a custom\n // ZodObject builder that stores extra constraints get them\n // surfaced symmetrically.\n return `ZodObject{${sortedEntries.join(',')}}${formatChecks(def.checks)}`\n }\n\n case 'ZodArray':\n return `ZodArray[${def.type === undefined ? '?' : recurse(def.type)}]${formatChecks(def.checks)}`\n\n case 'ZodTuple': {\n const items = def.items ?? []\n return `ZodTuple[${items.map(recurse).join(',')}]`\n }\n\n case 'ZodRecord': {\n const keyPart = def.keyType === undefined ? '?' : recurse(def.keyType)\n const valuePart = def.valueType === undefined ? '?' : recurse(def.valueType)\n return `ZodRecord<${keyPart},${valuePart}>`\n }\n\n case 'ZodUnion': {\n const options = (def.options ?? []).map(recurse).sort()\n return `ZodUnion(${options.join('|')})`\n }\n\n case 'ZodDiscriminatedUnion': {\n const disc = def.discriminator ?? '?'\n const options = (def.options ?? []).map(recurse).sort()\n return `ZodDiscriminatedUnion[${JSON.stringify(disc)}](${options.join('|')})`\n }\n\n case 'ZodOptional': {\n const inner = def.innerType\n return inner === undefined ? 'ZodOptional(?)' : `ZodOptional(${recurse(inner)})`\n }\n\n case 'ZodNullable': {\n const inner = def.innerType\n return inner === undefined ? 'ZodNullable(?)' : `ZodNullable(${recurse(inner)})`\n }\n\n case 'ZodDefault': {\n const inner = def.innerType\n // v3 stores defaults as a factory: `defaultValue: () => X`.\n // Call it twice and compare with Object.is — non-deterministic\n // factories (`() => new Date()`) return distinct objects each\n // call, so we collapse to `fn:*` to stay idempotent. Pure\n // factories that return the same primitive / cached reference\n // serialise normally.\n return `ZodDefault[${defaultFactoryRepr(def.defaultValue)}](${\n inner === undefined ? '?' : recurse(inner)\n })`\n }\n\n case 'ZodReadonly': {\n const inner = def.innerType\n return inner === undefined ? 'ZodReadonly(?)' : `ZodReadonly(${recurse(inner)})`\n }\n\n case 'ZodEffects': {\n // `.refine` / `.transform` / `.preprocess` — the effect function\n // isn't stably hashable. We can distinguish effect kinds (refine\n // vs transform) via `def.effect.type` and fold that into the\n // fingerprint, but the function body collapses to an opaque\n // sentinel.\n const effectType = def.effect?.type ?? 'effect'\n const inner = def.schema\n return `ZodEffects:${effectType}:fn:*(${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'ZodPipeline': {\n // Internally `z.pipe(a, b)` — `.in` and `.out` live on the def\n // (NOT `.schema`). The pre-fix walker read `def.schema`\n // (undefined for a pipeline) so every pipeline collapsed to\n // `ZodPipeline(?)`. Read the input side first (mirrors v4's\n // `unwrapPipe` which returns `in ?? out`); the output side is\n // a derived shape rather than a consumer-authored schema.\n const inner = def.in ?? def.out\n return inner === undefined ? 'ZodPipeline(?)' : `ZodPipeline(${recurse(inner)})`\n }\n\n case 'ZodCatch': {\n const inner = def.innerType ?? def.schema\n const catchRepr = defaultFactoryRepr(def.catchValue)\n return `ZodCatch[${catchRepr}](${inner === undefined ? '?' : recurse(inner)})`\n }\n\n case 'ZodLazy': {\n const resolve = def.getter\n if (typeof resolve !== 'function') return 'ZodLazy(?)'\n try {\n const inner = resolve()\n return `ZodLazy(${recurse(inner)})`\n } catch {\n return 'ZodLazy(?)'\n }\n }\n\n case 'ZodIntersection': {\n const leftPart = def.left === undefined ? '?' : recurse(def.left)\n const rightPart = def.right === undefined ? '?' : recurse(def.right)\n const parts = [leftPart, rightPart].sort()\n return `ZodIntersection(${parts.join('&')})`\n }\n\n case 'ZodSet': {\n // ZodSet stores its element type on `_def.valueType` (same slot\n // ZodRecord uses for its value type). The pre-fix walker fell\n // through to the opaque default branch, so `z.set(z.string())`\n // and `z.set(z.number())` collapsed to the same `ZodSet:*`.\n // Mirrors v4's `set<element>${formatChecks(schema)}`.\n const inner = def.valueType\n return inner === undefined\n ? 'ZodSet(?)'\n : `ZodSet<${recurse(inner)}>${formatChecks(def.checks)}`\n }\n\n case 'ZodBranded': {\n // ZodBranded stores its inner on `_def.type` (the v3 quirk; v4's\n // brand is type-only). The pre-fix walker fell through to the\n // opaque default branch and lost the inner's shape entirely, so\n // `z.string().brand<'A'>()` and `z.number().brand<'B'>()`\n // collapsed to the same `ZodBranded:*`. Brand annotations are\n // type-level only at runtime, so emit just the inner's\n // fingerprint with a transparent wrapper.\n const inner = def.type\n return inner === undefined ? 'ZodBranded(?)' : `ZodBranded(${recurse(inner)})`\n }\n\n // Structural opacity — schemas whose runtime behaviour isn't\n // introspectable via `_def` fall here. Still distinguishable\n // from other kinds by the returned string.\n case 'ZodPromise':\n case 'ZodFunction':\n case 'ZodMap':\n case 'ZodSymbol':\n default:\n return `${kind}:*`\n }\n}\n\nfunction readShapeSafely(def: V3Def): Record<string, V3Schema> {\n if (typeof def.shape !== 'function') return {}\n try {\n return def.shape()\n } catch {\n return {}\n }\n}\n\n/**\n * Render a v3 default / catch factory. Called twice; if the two\n * results differ (by `Object.is`), the factory is non-deterministic\n * and we collapse to `fn:*` to preserve idempotence. Same fix as\n * v4's `defaultValueRepr` — factories like `() => new Date()` would\n * otherwise make the fingerprint time-dependent.\n */\nfunction defaultFactoryRepr(factory: (() => unknown) | undefined): string {\n if (typeof factory !== 'function') return 'none'\n let first: unknown\n let second: unknown\n try {\n first = factory()\n second = factory()\n } catch {\n return 'fn:*'\n }\n if (!Object.is(first, second)) return 'fn:*'\n if (typeof first === 'function') return 'fn:*'\n return canonicalStringify(first)\n}\n\nfunction formatChecks(checks: readonly unknown[] | undefined): string {\n if (!Array.isArray(checks) || checks.length === 0) return ''\n const parts = checks.map((c) => canonicalStringify(c)).sort()\n return `[${parts.join(';')}]`\n}\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
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;;;;"}
@@ -1 +0,0 @@
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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"}
package/dist/esbuild.cjs DELETED
@@ -1,28 +0,0 @@
1
- 'use strict';
2
-
3
- const detectZodMajor = require('./shared/attaform.DoQm_Vkd.cjs');
4
-
5
- function attaform(options = {}) {
6
- const resolveZodAlias = options.resolveZodAlias !== false;
7
- const warnState = { warned: false };
8
- return {
9
- name: "attaform",
10
- setup(build) {
11
- const root = build.initialOptions.absWorkingDir ?? options.root ?? process.cwd();
12
- const target = detectZodMajor.resolveZodAliasTarget(root, "attaform/esbuild", resolveZodAlias, warnState);
13
- if (target === null) return;
14
- build.onResolve({ filter: detectZodMajor.REWRITABLE_ZOD_SPECIFIER_FILTER }, async (args) => {
15
- const result = await build.resolve(target, {
16
- kind: args.kind,
17
- importer: args.importer,
18
- resolveDir: args.resolveDir
19
- });
20
- if (result.errors.length > 0) return { errors: result.errors };
21
- return { path: result.path, external: result.external, namespace: result.namespace };
22
- });
23
- }
24
- };
25
- }
26
-
27
- exports.attaform = attaform;
28
- //# sourceMappingURL=esbuild.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"esbuild.cjs","sources":["../src/esbuild.ts"],"sourcesContent":["/**\n * `attaform/esbuild` — esbuild plugin that rewrites `attaform` and\n * `attaform/zod` imports to the single matching adapter subpath\n * (`attaform/zod-v3` or `attaform/zod-v4`) at build time, based on the\n * consumer's installed Zod major. Without it, esbuild ships both adapters\n * because those entries import both for runtime dispatch.\n *\n * Usage:\n *\n * // build.mjs\n * import { build } from 'esbuild'\n * import { attaform } from 'attaform/esbuild'\n *\n * await build({\n * entryPoints: ['src/main.ts'],\n * bundle: true,\n * plugins: [attaform()],\n * })\n *\n * This plugin only does the adapter rewrite. The Vue SFC `v-register`\n * transforms that `attaform/vite` wires (load-bearing for SSR initial\n * render) are `@vitejs/plugin-vue`-specific and do not transfer; a\n * non-Vite consumer that needs them wires `attaform/transforms` into\n * their Vue compiler separately.\n *\n * Zero-dep: the plugin imports nothing from `esbuild` (the bundler injects\n * its plugin API at the consumer's build); the structural types below are\n * all it needs to compile.\n */\nimport { resolveZodAliasTarget, REWRITABLE_ZOD_SPECIFIER_FILTER } from './core/detect-zod-major'\n\n/** Options for the esbuild `attaform()` plugin. */\nexport interface AttaformEsbuildPluginOptions {\n /**\n * Rewrite `attaform` and `attaform/zod` imports at build time to the\n * matching adapter subpath. Default `true`. Set to `false` to keep the\n * runtime-dispatch unified entry (ships both adapters).\n */\n resolveZodAlias?: boolean\n /**\n * Project root to resolve the installed Zod from. Defaults to the\n * build's `absWorkingDir`, falling back to `process.cwd()`. Set this\n * when the build runs from a directory other than the project that owns\n * the Zod dependency.\n */\n root?: string\n}\n\ninterface EsbuildOnResolveArgs {\n path: string\n importer: string\n resolveDir: string\n kind: string\n}\ninterface EsbuildResolveResult {\n path: string\n external: boolean\n namespace: string\n errors: unknown[]\n}\ninterface EsbuildOnResolveResult {\n path?: string\n external?: boolean\n namespace?: string\n errors?: unknown[]\n}\ninterface EsbuildPluginBuild {\n initialOptions: { absWorkingDir?: string }\n onResolve(\n options: { filter: RegExp },\n callback: (args: EsbuildOnResolveArgs) => Promise<EsbuildOnResolveResult>\n ): void\n resolve(\n path: string,\n options: { kind: string; importer?: string; resolveDir?: string }\n ): Promise<EsbuildResolveResult>\n}\n\n/** The structural shape esbuild requires of the plugin. */\nexport interface AttaformEsbuildPlugin {\n name: string\n setup(build: EsbuildPluginBuild): void\n}\n\nexport function attaform(options: AttaformEsbuildPluginOptions = {}): AttaformEsbuildPlugin {\n const resolveZodAlias = options.resolveZodAlias !== false\n const warnState = { warned: false }\n return {\n name: 'attaform',\n setup(build) {\n const root = build.initialOptions.absWorkingDir ?? options.root ?? process.cwd()\n const target = resolveZodAliasTarget(root, 'attaform/esbuild', resolveZodAlias, warnState)\n // Nothing to rewrite (opt-out, or unclassifiable version): leave the\n // unified entry in place and register no hook.\n if (target === null) return\n build.onResolve({ filter: REWRITABLE_ZOD_SPECIFIER_FILTER }, async (args) => {\n // Re-resolve the rewritten specifier so esbuild returns a real\n // path. Both matched specifiers (bare `attaform` and\n // `attaform/zod`) rewrite to the same detected adapter; the filter\n // is anchored so resolving `attaform/zod-v4` does not re-enter\n // this callback.\n const result = await build.resolve(target, {\n kind: args.kind,\n importer: args.importer,\n resolveDir: args.resolveDir,\n })\n if (result.errors.length > 0) return { errors: result.errors }\n return { path: result.path, external: result.external, namespace: result.namespace }\n })\n },\n }\n}\n"],"names":["resolveZodAliasTarget","REWRITABLE_ZOD_SPECIFIER_FILTER"],"mappings":";;;;AAoFO,SAAS,QAAA,CAAS,OAAA,GAAwC,EAAC,EAA0B;AAC1F,EAAA,MAAM,eAAA,GAAkB,QAAQ,eAAA,KAAoB,KAAA;AACpD,EAAA,MAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,EAAM;AAClC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,MAAM,KAAA,EAAO;AACX,MAAA,MAAM,OAAO,KAAA,CAAM,cAAA,CAAe,iBAAiB,OAAA,CAAQ,IAAA,IAAQ,QAAQ,GAAA,EAAI;AAC/E,MAAA,MAAM,MAAA,GAASA,oCAAA,CAAsB,IAAA,EAAM,kBAAA,EAAoB,iBAAiB,SAAS,CAAA;AAGzF,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,KAAA,CAAM,UAAU,EAAE,MAAA,EAAQC,8CAAA,EAAgC,EAAG,OAAO,IAAA,KAAS;AAM3E,QAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ;AAAA,UACzC,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,YAAY,IAAA,CAAK;AAAA,SAClB,CAAA;AACD,QAAA,IAAI,MAAA,CAAO,OAAO,MAAA,GAAS,CAAA,SAAU,EAAE,MAAA,EAAQ,OAAO,MAAA,EAAO;AAC7D,QAAA,OAAO,EAAE,MAAM,MAAA,CAAO,IAAA,EAAM,UAAU,MAAA,CAAO,QAAA,EAAU,SAAA,EAAW,MAAA,CAAO,SAAA,EAAU;AAAA,MACrF,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF;;;;"}
@@ -1,56 +0,0 @@
1
- /** Options for the esbuild `attaform()` plugin. */
2
- interface AttaformEsbuildPluginOptions {
3
- /**
4
- * Rewrite `attaform` and `attaform/zod` imports at build time to the
5
- * matching adapter subpath. Default `true`. Set to `false` to keep the
6
- * runtime-dispatch unified entry (ships both adapters).
7
- */
8
- resolveZodAlias?: boolean;
9
- /**
10
- * Project root to resolve the installed Zod from. Defaults to the
11
- * build's `absWorkingDir`, falling back to `process.cwd()`. Set this
12
- * when the build runs from a directory other than the project that owns
13
- * the Zod dependency.
14
- */
15
- root?: string;
16
- }
17
- interface EsbuildOnResolveArgs {
18
- path: string;
19
- importer: string;
20
- resolveDir: string;
21
- kind: string;
22
- }
23
- interface EsbuildResolveResult {
24
- path: string;
25
- external: boolean;
26
- namespace: string;
27
- errors: unknown[];
28
- }
29
- interface EsbuildOnResolveResult {
30
- path?: string;
31
- external?: boolean;
32
- namespace?: string;
33
- errors?: unknown[];
34
- }
35
- interface EsbuildPluginBuild {
36
- initialOptions: {
37
- absWorkingDir?: string;
38
- };
39
- onResolve(options: {
40
- filter: RegExp;
41
- }, callback: (args: EsbuildOnResolveArgs) => Promise<EsbuildOnResolveResult>): void;
42
- resolve(path: string, options: {
43
- kind: string;
44
- importer?: string;
45
- resolveDir?: string;
46
- }): Promise<EsbuildResolveResult>;
47
- }
48
- /** The structural shape esbuild requires of the plugin. */
49
- interface AttaformEsbuildPlugin {
50
- name: string;
51
- setup(build: EsbuildPluginBuild): void;
52
- }
53
- declare function attaform(options?: AttaformEsbuildPluginOptions): AttaformEsbuildPlugin;
54
-
55
- export { attaform };
56
- export type { AttaformEsbuildPlugin, AttaformEsbuildPluginOptions };
package/dist/esbuild.d.ts DELETED
@@ -1,56 +0,0 @@
1
- /** Options for the esbuild `attaform()` plugin. */
2
- interface AttaformEsbuildPluginOptions {
3
- /**
4
- * Rewrite `attaform` and `attaform/zod` imports at build time to the
5
- * matching adapter subpath. Default `true`. Set to `false` to keep the
6
- * runtime-dispatch unified entry (ships both adapters).
7
- */
8
- resolveZodAlias?: boolean;
9
- /**
10
- * Project root to resolve the installed Zod from. Defaults to the
11
- * build's `absWorkingDir`, falling back to `process.cwd()`. Set this
12
- * when the build runs from a directory other than the project that owns
13
- * the Zod dependency.
14
- */
15
- root?: string;
16
- }
17
- interface EsbuildOnResolveArgs {
18
- path: string;
19
- importer: string;
20
- resolveDir: string;
21
- kind: string;
22
- }
23
- interface EsbuildResolveResult {
24
- path: string;
25
- external: boolean;
26
- namespace: string;
27
- errors: unknown[];
28
- }
29
- interface EsbuildOnResolveResult {
30
- path?: string;
31
- external?: boolean;
32
- namespace?: string;
33
- errors?: unknown[];
34
- }
35
- interface EsbuildPluginBuild {
36
- initialOptions: {
37
- absWorkingDir?: string;
38
- };
39
- onResolve(options: {
40
- filter: RegExp;
41
- }, callback: (args: EsbuildOnResolveArgs) => Promise<EsbuildOnResolveResult>): void;
42
- resolve(path: string, options: {
43
- kind: string;
44
- importer?: string;
45
- resolveDir?: string;
46
- }): Promise<EsbuildResolveResult>;
47
- }
48
- /** The structural shape esbuild requires of the plugin. */
49
- interface AttaformEsbuildPlugin {
50
- name: string;
51
- setup(build: EsbuildPluginBuild): void;
52
- }
53
- declare function attaform(options?: AttaformEsbuildPluginOptions): AttaformEsbuildPlugin;
54
-
55
- export { attaform };
56
- export type { AttaformEsbuildPlugin, AttaformEsbuildPluginOptions };
@@ -1 +0,0 @@
1
- {"version":3,"file":"esbuild.mjs","sources":["../src/esbuild.ts"],"sourcesContent":["/**\n * `attaform/esbuild` — esbuild plugin that rewrites `attaform` and\n * `attaform/zod` imports to the single matching adapter subpath\n * (`attaform/zod-v3` or `attaform/zod-v4`) at build time, based on the\n * consumer's installed Zod major. Without it, esbuild ships both adapters\n * because those entries import both for runtime dispatch.\n *\n * Usage:\n *\n * // build.mjs\n * import { build } from 'esbuild'\n * import { attaform } from 'attaform/esbuild'\n *\n * await build({\n * entryPoints: ['src/main.ts'],\n * bundle: true,\n * plugins: [attaform()],\n * })\n *\n * This plugin only does the adapter rewrite. The Vue SFC `v-register`\n * transforms that `attaform/vite` wires (load-bearing for SSR initial\n * render) are `@vitejs/plugin-vue`-specific and do not transfer; a\n * non-Vite consumer that needs them wires `attaform/transforms` into\n * their Vue compiler separately.\n *\n * Zero-dep: the plugin imports nothing from `esbuild` (the bundler injects\n * its plugin API at the consumer's build); the structural types below are\n * all it needs to compile.\n */\nimport { resolveZodAliasTarget, REWRITABLE_ZOD_SPECIFIER_FILTER } from './core/detect-zod-major'\n\n/** Options for the esbuild `attaform()` plugin. */\nexport interface AttaformEsbuildPluginOptions {\n /**\n * Rewrite `attaform` and `attaform/zod` imports at build time to the\n * matching adapter subpath. Default `true`. Set to `false` to keep the\n * runtime-dispatch unified entry (ships both adapters).\n */\n resolveZodAlias?: boolean\n /**\n * Project root to resolve the installed Zod from. Defaults to the\n * build's `absWorkingDir`, falling back to `process.cwd()`. Set this\n * when the build runs from a directory other than the project that owns\n * the Zod dependency.\n */\n root?: string\n}\n\ninterface EsbuildOnResolveArgs {\n path: string\n importer: string\n resolveDir: string\n kind: string\n}\ninterface EsbuildResolveResult {\n path: string\n external: boolean\n namespace: string\n errors: unknown[]\n}\ninterface EsbuildOnResolveResult {\n path?: string\n external?: boolean\n namespace?: string\n errors?: unknown[]\n}\ninterface EsbuildPluginBuild {\n initialOptions: { absWorkingDir?: string }\n onResolve(\n options: { filter: RegExp },\n callback: (args: EsbuildOnResolveArgs) => Promise<EsbuildOnResolveResult>\n ): void\n resolve(\n path: string,\n options: { kind: string; importer?: string; resolveDir?: string }\n ): Promise<EsbuildResolveResult>\n}\n\n/** The structural shape esbuild requires of the plugin. */\nexport interface AttaformEsbuildPlugin {\n name: string\n setup(build: EsbuildPluginBuild): void\n}\n\nexport function attaform(options: AttaformEsbuildPluginOptions = {}): AttaformEsbuildPlugin {\n const resolveZodAlias = options.resolveZodAlias !== false\n const warnState = { warned: false }\n return {\n name: 'attaform',\n setup(build) {\n const root = build.initialOptions.absWorkingDir ?? options.root ?? process.cwd()\n const target = resolveZodAliasTarget(root, 'attaform/esbuild', resolveZodAlias, warnState)\n // Nothing to rewrite (opt-out, or unclassifiable version): leave the\n // unified entry in place and register no hook.\n if (target === null) return\n build.onResolve({ filter: REWRITABLE_ZOD_SPECIFIER_FILTER }, async (args) => {\n // Re-resolve the rewritten specifier so esbuild returns a real\n // path. Both matched specifiers (bare `attaform` and\n // `attaform/zod`) rewrite to the same detected adapter; the filter\n // is anchored so resolving `attaform/zod-v4` does not re-enter\n // this callback.\n const result = await build.resolve(target, {\n kind: args.kind,\n importer: args.importer,\n resolveDir: args.resolveDir,\n })\n if (result.errors.length > 0) return { errors: result.errors }\n return { path: result.path, external: result.external, namespace: result.namespace }\n })\n },\n }\n}\n"],"names":[],"mappings":";;AAoFO,SAAS,QAAA,CAAS,OAAA,GAAwC,EAAC,EAA0B;AAC1F,EAAA,MAAM,eAAA,GAAkB,QAAQ,eAAA,KAAoB,KAAA;AACpD,EAAA,MAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,EAAM;AAClC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,MAAM,KAAA,EAAO;AACX,MAAA,MAAM,OAAO,KAAA,CAAM,cAAA,CAAe,iBAAiB,OAAA,CAAQ,IAAA,IAAQ,QAAQ,GAAA,EAAI;AAC/E,MAAA,MAAM,MAAA,GAAS,qBAAA,CAAsB,IAAA,EAAM,kBAAA,EAAoB,iBAAiB,SAAS,CAAA;AAGzF,MAAA,IAAI,WAAW,IAAA,EAAM;AACrB,MAAA,KAAA,CAAM,UAAU,EAAE,MAAA,EAAQ,+BAAA,EAAgC,EAAG,OAAO,IAAA,KAAS;AAM3E,QAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ;AAAA,UACzC,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,YAAY,IAAA,CAAK;AAAA,SAClB,CAAA;AACD,QAAA,IAAI,MAAA,CAAO,OAAO,MAAA,GAAS,CAAA,SAAU,EAAE,MAAA,EAAQ,OAAO,MAAA,EAAO;AAC7D,QAAA,OAAO,EAAE,MAAM,MAAA,CAAO,IAAA,EAAM,UAAU,MAAA,CAAO,QAAA,EAAU,SAAA,EAAW,MAAA,CAAO,SAAA,EAAU;AAAA,MACrF,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF;;;;"}