attaform 0.29.0 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abstract.d.mts +15 -21
- package/dist/abstract.mjs +4 -4
- package/dist/dev/abstract.mjs +4 -4
- package/dist/dev/chunks/dev-key-collision-warnings.mjs +47 -8
- package/dist/dev/chunks/devtools.mjs +2 -2
- package/dist/dev/directive.mjs +1 -1
- package/dist/dev/history.mjs +1 -2
- package/dist/dev/index.mjs +5 -5
- package/dist/dev/runtime/plugins/attaform.mjs +3 -3
- package/dist/dev/shared/{attaform-dev.BO-71R54.mjs → attaform-dev.BJK1kqHY.mjs} +44 -198
- package/dist/dev/shared/{attaform-dev.D8aoKb89.mjs → attaform-dev.BMQ3GcgD.mjs} +51 -64
- package/dist/dev/shared/{attaform-dev.BgM6FdtA.mjs → attaform-dev.BUIFcTYf.mjs} +94 -62
- package/dist/dev/shared/{attaform-dev.q6UutkCx.mjs → attaform-dev.CT7MDjPy.mjs} +92 -152
- package/dist/dev/shared/{attaform-dev.ButTkwHd.mjs → attaform-dev.CZz4GYZ6.mjs} +26 -15
- package/dist/dev/shared/{attaform-dev.DD5m2W51.mjs → attaform-dev.Chm4D6SJ.mjs} +2 -4
- package/dist/dev/shared/{attaform-dev.DrzObAZo.mjs → attaform-dev.DuEE4GU1.mjs} +4 -4
- package/dist/dev/shared/{attaform-dev.DHuydLAC.mjs → attaform-dev.DxHdkkPG.mjs} +674 -734
- package/dist/dev/shared/{attaform-dev.A-TpJW0B.mjs → attaform-dev.zlvDr0WB.mjs} +3 -21
- package/dist/dev/zod-v3.mjs +6 -6
- package/dist/dev/zod-v4.mjs +6 -6
- package/dist/dev/zod.mjs +5 -5
- package/dist/directive.d.mts +4 -4
- package/dist/directive.mjs +1 -1
- package/dist/esbuild.d.mts +11 -0
- package/dist/esbuild.mjs +1 -1
- package/dist/history.d.mts +3 -32
- package/dist/history.mjs +1 -2
- package/dist/index.d.mts +67 -70
- package/dist/index.mjs +5 -5
- package/dist/nuxt.d.mts +6 -14
- package/dist/nuxt.mjs +3 -7
- package/dist/rollup.d.mts +11 -0
- package/dist/rollup.mjs +1 -1
- package/dist/rspack.d.mts +19 -11
- package/dist/rspack.mjs +1 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +12 -12
- package/dist/runtime/components/DevtoolsValueTree.vue +2 -2
- package/dist/runtime/plugins/attaform.mjs +3 -3
- package/dist/shared/{attaform.CIWLMY-R.d.mts → attaform.2FslhB9R.d.mts} +83 -95
- package/dist/shared/{attaform.Cvao8bW5.mjs → attaform.8mfKZCwH.mjs} +7 -7
- package/dist/shared/{attaform.DRUT703x.d.mts → attaform.B-Tb62qV.d.mts} +12 -12
- package/dist/shared/{attaform.v0fQtWyA.mjs → attaform.B1rH9ht6.mjs} +1 -1
- package/dist/shared/{attaform.BndjUUYX.mjs → attaform.B2iebkPA.mjs} +4 -4
- package/dist/shared/{attaform.DhnPb6nK.mjs → attaform.BAf3UNn4.mjs} +1 -1
- package/dist/shared/{attaform.CZMAYwSK.mjs → attaform.BIWicztt.mjs} +651 -678
- package/dist/shared/attaform.BcQwgWaq.d.mts +2153 -0
- package/dist/shared/attaform.Br8EBn5B.d.mts +4553 -0
- package/dist/shared/{attaform.C2MVyuxC.mjs → attaform.CO918TdU.mjs} +44 -198
- package/dist/shared/{attaform.CZYt_5N_.mjs → attaform.CdZIEf7_.mjs} +1 -19
- package/dist/shared/{attaform.B0dKL8ST.mjs → attaform.DRsANMok.mjs} +94 -62
- package/dist/shared/{attaform.DffRL5pP.mjs → attaform.D_f1WgYf.mjs} +46 -59
- package/dist/shared/{attaform.D1fnTifF.mjs → attaform.D_pt1gOj.mjs} +92 -150
- package/dist/shared/attaform.L0kUn3vL.d.mts +42 -0
- package/dist/shared/{attaform.D0x-qSXm.mjs → attaform.WiGdIqgx.mjs} +1 -3
- package/dist/shared/{attaform.BK0cgu2K.mjs → attaform.ZYn2ahzJ.mjs} +3 -3
- package/dist/transforms.d.mts +153 -26
- package/dist/transforms.mjs +1 -1
- package/dist/vite.d.mts +29 -52
- package/dist/vite.mjs +8 -3
- package/dist/webpack.d.mts +20 -12
- package/dist/webpack.mjs +1 -1
- package/dist/zod-v3.d.mts +90 -96
- package/dist/zod-v3.mjs +6 -6
- package/dist/zod-v4.d.mts +119 -119
- package/dist/zod-v4.mjs +6 -6
- package/dist/zod.d.mts +5 -5
- package/dist/zod.mjs +5 -5
- package/package.json +9 -7
- package/skills/attaform/SKILL.md +1 -1
- package/skills/attaform/references/custom-components.md +1 -1
- package/dist/chunks/fingerprint.mjs +0 -183
- package/dist/chunks/fingerprint2.mjs +0 -159
- package/dist/dev/chunks/fingerprint.mjs +0 -183
- package/dist/dev/chunks/fingerprint2.mjs +0 -159
- package/dist/dev/shared/attaform-dev.BxfsuwBR.mjs +0 -44
- package/dist/shared/attaform.BxfsuwBR.mjs +0 -44
- package/dist/shared/attaform.CsoeRi3P.d.mts +0 -5155
- package/dist/shared/attaform.DDtqHYv1.d.mts +0 -2465
- package/dist/shared/attaform.axHXVQO7.d.mts +0 -44
package/dist/transforms.d.mts
CHANGED
|
@@ -1,50 +1,177 @@
|
|
|
1
1
|
import { NodeTransform } from '@vue/compiler-core';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Vue compiler node transform that bridges `v-register` into the binding
|
|
5
|
+
* shapes its consumers expect, on two kinds of host.
|
|
6
|
+
*
|
|
7
|
+
* - `<select v-register>` gets `:value` on a single-select plus a
|
|
8
|
+
* per-`<option>` `:selected`, so the runtime directive can pre-mark
|
|
9
|
+
* selected options at SSR time.
|
|
10
|
+
* - `<MyComponent v-register>`, and a kebab-case custom-element host,
|
|
11
|
+
* gets a `:registerValue` bridge prop, so `useRegister` inside the
|
|
12
|
+
* child sees the parent's RegisterValue. Any parent-authored slotted
|
|
13
|
+
* `<option>` is marked exactly as the native path marks it, so a
|
|
14
|
+
* `<select>` wrapped in a styled component keeps its SSR-selected
|
|
15
|
+
* option (#394).
|
|
16
|
+
*
|
|
17
|
+
* `attaform/vite` and `attaform/nuxt` wire it for you; reach for it
|
|
18
|
+
* directly only when integrating a custom bundler.
|
|
19
|
+
*/
|
|
20
|
+
|
|
3
21
|
declare const componentBridgeTransform: NodeTransform;
|
|
4
22
|
|
|
5
23
|
/**
|
|
6
|
-
* Vue compiler node transform for `<input v-register>` and
|
|
7
|
-
*
|
|
8
|
-
*
|
|
24
|
+
* Vue compiler node transform for `<input v-register>` and `<textarea
|
|
25
|
+
* v-register>`, injecting the `:value` and `:checked` bindings an
|
|
26
|
+
* SSR-correct initial render needs.
|
|
9
27
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* a custom bundler.
|
|
28
|
+
* `attaform/vite` and `attaform/nuxt` wire it for you; reach for it
|
|
29
|
+
* directly only when integrating a custom bundler.
|
|
13
30
|
*/
|
|
14
31
|
declare const inputTextAreaNodeTransform: NodeTransform;
|
|
15
32
|
|
|
16
33
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
34
|
+
* The compile-time half of the redundant-binding guard (#464). On every
|
|
35
|
+
* element carrying `v-register` it does two things.
|
|
36
|
+
*
|
|
37
|
+
* 1. Warns at build time when a `v-model` sits beside `v-register` on
|
|
38
|
+
* a native `<input>`, `<select>` or `<textarea>`, which installs
|
|
39
|
+
* Vue's own model directive next to Attaform's: two writers driving
|
|
40
|
+
* one element with no fallback story between them.
|
|
41
|
+
* `findRedundantStateBinding` below carries the full reasoning for
|
|
42
|
+
* what does and does not count.
|
|
43
|
+
*
|
|
44
|
+
* 2. Stamps `V_REGISTER_COMPILED_MODIFIER` on the directive so the
|
|
45
|
+
* runtime diagnostic in `core/directive.ts` stands down. This
|
|
46
|
+
* transform runs BEFORE `inputTextAreaNodeTransform` and
|
|
47
|
+
* `componentBridgeTransform` strip and inject the value channel, so
|
|
48
|
+
* it sees the author's props verbatim where the runtime, seeing
|
|
49
|
+
* only the post-injection props, cannot. Exactly one layer fires
|
|
50
|
+
* per consumer.
|
|
51
|
+
*
|
|
52
|
+
* The carve-out: a `:value`, or a static `value=`, is the legitimate
|
|
53
|
+
* IDENTITY channel for a radio and an `<option>`, and `v-register` READS
|
|
54
|
+
* it. Those never warn; only the STATE attrs do.
|
|
55
|
+
*
|
|
56
|
+
* A dynamic `:type` cannot be classified at compile time, so that input
|
|
57
|
+
* is skipped for the warn, best-effort as in `inputTextAreaNodeTransform`
|
|
58
|
+
* and the runtime `resolveDynamicModel`. The marker is still stamped, so
|
|
59
|
+
* the runtime layer, which sees the resolved type, does not double-report.
|
|
60
|
+
*
|
|
61
|
+
* It is deliberately NOT `__DEV__`-gated: firing on every compile,
|
|
62
|
+
* production and CI included, is what lets a consumer retire a bespoke
|
|
63
|
+
* SFC-lint gate. Warnings only. A redundant binding never fails the
|
|
64
|
+
* build, the Vue compiler giving transforms no error channel and a
|
|
65
|
+
* library having no business nuking a consumer's build over a
|
|
66
|
+
* lint-level issue.
|
|
67
|
+
*
|
|
68
|
+
* `attaform/vite` and `attaform/nuxt` wire it first in `nodeTransforms`;
|
|
69
|
+
* reach for it directly only when integrating a custom bundler.
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Vue compiler node transform that warns about a redundant state binding
|
|
74
|
+
* sitting beside `v-register`, and stamps the compile-active marker so
|
|
75
|
+
* the runtime diagnostic stands down.
|
|
20
76
|
*
|
|
21
|
-
*
|
|
22
|
-
* `componentBridgeTransform
|
|
23
|
-
* are stripped
|
|
24
|
-
*
|
|
77
|
+
* It MUST run before `inputTextAreaNodeTransform` and
|
|
78
|
+
* `componentBridgeTransform`, so it reads the author's props before they
|
|
79
|
+
* are stripped and injected. `attaform/vite` and `attaform/nuxt` wire it
|
|
80
|
+
* first.
|
|
25
81
|
*/
|
|
26
82
|
declare const redundantBindingWarnTransform: NodeTransform;
|
|
27
83
|
|
|
28
84
|
/**
|
|
29
|
-
*
|
|
30
|
-
* expression in
|
|
31
|
-
*
|
|
32
|
-
*
|
|
85
|
+
* Rewrites every `<element v-register="<expr>">` so the binding
|
|
86
|
+
* expression wraps `<expr>` in an IIFE that calls
|
|
87
|
+
* `markConnectedOptimistically()` on the resulting `RegisterValue` and
|
|
88
|
+
* hands back the same object:
|
|
89
|
+
*
|
|
90
|
+
* ((__attaRv) => (__attaRv?.markConnectedOptimistically?.(), __attaRv))(<expr>)
|
|
91
|
+
*
|
|
92
|
+
* Vue deliberately skips directive lifecycle hooks during SSR (see the
|
|
93
|
+
* header of `core/directive.ts`), so the `v-register` directive's
|
|
94
|
+
* `created` hook, the one that flips `connected: true`, never fires on
|
|
95
|
+
* the server. Every SSR'd FieldState therefore serialises `connected:
|
|
96
|
+
* false`, then flickers to `true` when the directive runs on hydration,
|
|
97
|
+
* and anything reading `getFieldState(path).connected` in a
|
|
98
|
+
* server-rendered template sees the stale value baked into the HTML.
|
|
33
99
|
*
|
|
34
|
-
*
|
|
35
|
-
* by `
|
|
100
|
+
* The IIFE captures the `RegisterValue` `<expr>` produced, fires the
|
|
101
|
+
* optimistic mark, itself guarded by `state.ssr` so it is a free no-op
|
|
102
|
+
* on the client, and returns the same object, so the directive receives
|
|
103
|
+
* exactly what the author wrote.
|
|
104
|
+
*
|
|
105
|
+
* It is agnostic to the shape of `<expr>`, inline, hoisted into a
|
|
106
|
+
* variable, or dynamically built: all three produce a `RegisterValue` at
|
|
107
|
+
* runtime and the wrapper never needs the path string. A setup-time
|
|
108
|
+
* `register()` call NEVER bound to `v-register` gets no wrapper, no
|
|
109
|
+
* mark, and stays `connected: false` after hydration, which is correct:
|
|
110
|
+
* it represents no rendered DOM element.
|
|
111
|
+
*
|
|
112
|
+
* Idempotent. Running twice on one AST, as some bundler configurations
|
|
113
|
+
* do, detects the marker on the second pass and skips re-wrapping.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Vue compiler node transform that wraps every `v-register` expression
|
|
118
|
+
* in a small IIFE, so the directive can flag a field connected during
|
|
119
|
+
* SSR and `getFieldState(path).connected` does not flicker after
|
|
120
|
+
* hydration.
|
|
121
|
+
*
|
|
122
|
+
* It must run after `vRegisterPreambleTransform`. `attaform/vite` and
|
|
123
|
+
* `attaform/nuxt` wire both.
|
|
36
124
|
*/
|
|
37
125
|
declare const vRegisterHintTransform: NodeTransform;
|
|
38
126
|
|
|
39
127
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
128
|
+
* Closes the render-order edge `vRegisterHintTransform` alone leaves
|
|
129
|
+
* open.
|
|
130
|
+
*
|
|
131
|
+
* The hint transform wraps each `v-register` expression in an IIFE that
|
|
132
|
+
* calls `markConnectedOptimistically()` when the element's vnode is
|
|
133
|
+
* created, which covers any expression evaluated AT or AFTER the input
|
|
134
|
+
* in render order. Vue's SSR is single-pass top to bottom, though, so in
|
|
135
|
+
*
|
|
136
|
+
* <pre>{{ form.fields.password.connected }}</pre>
|
|
137
|
+
* <input v-register="form.register('password')" />
|
|
138
|
+
*
|
|
139
|
+
* the `<pre>` evaluates BEFORE the wrapper has fired. The serialized
|
|
140
|
+
* HTML carries `connected: false`, the post-hydration steady state says
|
|
141
|
+
* `true`, and the user sees a one-tick flicker.
|
|
142
|
+
*
|
|
143
|
+
* So the marks hoist one level up. The walk collects every static
|
|
144
|
+
* `v-register` binding, skipping `v-for` descendants, whose expressions
|
|
145
|
+
* reference loop locals unavailable at root scope, and prepends a
|
|
146
|
+
* synthetic `:data-atta-pre-mark` directive to the first root element.
|
|
147
|
+
* Vue evaluates an element's prop bindings before recursing into its
|
|
148
|
+
* children, so that IIFE fires every collected mark before any
|
|
149
|
+
* descendant expression runs. Its own expression resolves to
|
|
150
|
+
* `undefined`, which the SSR renderer drops, so no attribute appears and
|
|
151
|
+
* the marks are the only output.
|
|
152
|
+
*
|
|
153
|
+
* Register it BEFORE `vRegisterHintTransform`. The pre-order pass here
|
|
154
|
+
* captures each expression's original, un-wrapped text into a
|
|
155
|
+
* per-template state map, the hint transform then wraps the in-place
|
|
156
|
+
* directive expression, and the exit hook on the first root element
|
|
157
|
+
* builds the preamble from the captured originals. An element's exit
|
|
158
|
+
* hooks fire before `transformElement`'s codegen exit, so the injected
|
|
159
|
+
* prop lands in the rendered output.
|
|
160
|
+
*
|
|
161
|
+
* For a `v-for` descendant the hint transform's per-element wrapper
|
|
162
|
+
* stays load-bearing: those bindings cannot hoist, their path
|
|
163
|
+
* expressions referencing loop-scoped identifiers.
|
|
164
|
+
*/
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Vue compiler node transform that hoists `v-register`'s SSR connection
|
|
168
|
+
* marks to the root of the template. With `vRegisterHintTransform`, it
|
|
169
|
+
* is what lets an expression EARLIER in the template read
|
|
170
|
+
* `getFieldState(path).connected` correctly during the server's
|
|
171
|
+
* single-pass render.
|
|
45
172
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
173
|
+
* It must run before `vRegisterHintTransform`. `attaform/vite` and
|
|
174
|
+
* `attaform/nuxt` wire both.
|
|
48
175
|
*/
|
|
49
176
|
declare const vRegisterPreambleTransform: NodeTransform;
|
|
50
177
|
|
package/dist/transforms.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { c as componentBridgeTransform, i as inputTextAreaNodeTransform, r as redundantBindingWarnTransform, v as vRegisterHintTransform, a as vRegisterPreambleTransform } from './shared/attaform.
|
|
1
|
+
export { c as componentBridgeTransform, i as inputTextAreaNodeTransform, r as redundantBindingWarnTransform, v as vRegisterHintTransform, a as vRegisterPreambleTransform } from './shared/attaform.ZYn2ahzJ.mjs';
|
package/dist/vite.d.mts
CHANGED
|
@@ -28,9 +28,9 @@ import { Plugin } from 'vite';
|
|
|
28
28
|
* can be called at all.
|
|
29
29
|
*
|
|
30
30
|
* Deliberately absent (reach for these with an explicit import):
|
|
31
|
-
* - `useAbstractForm
|
|
32
|
-
* `attaform/abstract
|
|
33
|
-
* - `createAttaform
|
|
31
|
+
* - `useAbstractForm`, the schema-agnostic escape hatch on
|
|
32
|
+
* `attaform/abstract`: an advanced surface, not the default form.
|
|
33
|
+
* - `createAttaform`, the plugin install, a setup-level one-liner that
|
|
34
34
|
* belongs beside the app bootstrap, not in every component's scope.
|
|
35
35
|
* - `unset` / `isUnset` and the serialize helpers: plain values and
|
|
36
36
|
* functions with no component affinity, equally at home in a store, a
|
|
@@ -63,41 +63,14 @@ declare const attaformAutoImports: AttaformAutoImport[];
|
|
|
63
63
|
declare const attaformAutoImportsMap: Record<string, string[]>;
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
|
-
* `attaform/vite
|
|
67
|
-
*
|
|
68
|
-
* compiled template that uses it (so no app-level directive
|
|
69
|
-
* registration exists or is needed), AND rewrites `attaform` and
|
|
70
|
-
* `attaform/zod` imports to either `attaform/zod-v3` or `attaform/zod-v4`
|
|
71
|
-
* at build time, based on the consumer's installed Zod major. The result
|
|
72
|
-
* is one Zod adapter shipped per bundle, with no manual subpath choice.
|
|
66
|
+
* `attaform/vite`, the Vite plugin. See {@link attaform} for what it
|
|
67
|
+
* does and how to register it.
|
|
73
68
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* export default defineConfig({
|
|
81
|
-
* plugins: [vue(), attaform()],
|
|
82
|
-
* })
|
|
83
|
-
*
|
|
84
|
-
* The transforms inject `:value`, `:checked`, and `:selected` bindings
|
|
85
|
-
* into elements that use the `v-register` directive — load-bearing for
|
|
86
|
-
* SSR initial-render correctness. Omitting this plugin under CSR is
|
|
87
|
-
* tolerable (one-frame flash on mount); omitting it under SSR produces
|
|
88
|
-
* visibly wrong initial HTML.
|
|
89
|
-
*
|
|
90
|
-
* The `resolveZodAlias` option (default `true`) controls the build-time
|
|
91
|
-
* rewrite of `attaform` / `attaform/zod`. Set to `false` if your project
|
|
92
|
-
* intentionally mixes Zod versions or has a non-standard Zod resolution;
|
|
93
|
-
* the unified entry's runtime dispatch covers that case at the cost of
|
|
94
|
-
* bundling both adapters.
|
|
95
|
-
*
|
|
96
|
-
* Implementation note: this plugin mutates @vitejs/plugin-vue's options
|
|
97
|
-
* via the documented but somewhat informal `api.options` surface used
|
|
98
|
-
* by VueUse, Vite PWA, and other Vue ecosystem plugins. If you're
|
|
99
|
-
* using a custom Vue plugin wrapper, fall back to `attaform/transforms`
|
|
100
|
-
* and wire them yourself.
|
|
69
|
+
* It mutates @vitejs/plugin-vue's options through the documented but
|
|
70
|
+
* somewhat informal `api.options` surface that VueUse, Vite PWA and
|
|
71
|
+
* other Vue ecosystem plugins also use. Behind a custom Vue plugin
|
|
72
|
+
* wrapper, fall back to `attaform/transforms` and wire the transforms
|
|
73
|
+
* yourself.
|
|
101
74
|
*/
|
|
102
75
|
|
|
103
76
|
/** Options for `attaform()`. */
|
|
@@ -105,8 +78,8 @@ interface AttaformVitePluginOptions {
|
|
|
105
78
|
/**
|
|
106
79
|
* Rewrite `attaform` and `attaform/zod` imports at build time to
|
|
107
80
|
* either `attaform/zod-v3` or `attaform/zod-v4`, based on the
|
|
108
|
-
* consumer's installed Zod major. Default `true
|
|
109
|
-
* bundle for the common case of one Zod version per project.
|
|
81
|
+
* consumer's installed Zod major. Default `true`, which produces a
|
|
82
|
+
* leaner bundle for the common case of one Zod version per project.
|
|
110
83
|
*
|
|
111
84
|
* Set to `false` to fall through to the unified entry's runtime
|
|
112
85
|
* dispatch. Useful when:
|
|
@@ -120,12 +93,10 @@ interface AttaformVitePluginOptions {
|
|
|
120
93
|
resolveZodAlias?: boolean;
|
|
121
94
|
}
|
|
122
95
|
/**
|
|
123
|
-
* Vite plugin that wires
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* matching adapter subpath. Required for SSR and for hydration
|
|
128
|
-
* accuracy under bare Vue 3.
|
|
96
|
+
* Vite plugin that wires Attaform's compile-time template transforms
|
|
97
|
+
* into `@vitejs/plugin-vue`, binds `v-register` into each compiled
|
|
98
|
+
* template that uses it, and rewrites the bare `attaform` barrel and
|
|
99
|
+
* the unified `attaform/zod` import to the matching adapter subpath.
|
|
129
100
|
*
|
|
130
101
|
* ```ts
|
|
131
102
|
* // vite.config.ts
|
|
@@ -137,14 +108,20 @@ interface AttaformVitePluginOptions {
|
|
|
137
108
|
* })
|
|
138
109
|
* ```
|
|
139
110
|
*
|
|
140
|
-
* Place the call after `vue()
|
|
141
|
-
*
|
|
111
|
+
* Place the call after `vue()`. Nuxt projects do not need it;
|
|
112
|
+
* `attaform/nuxt` handles this.
|
|
113
|
+
*
|
|
114
|
+
* The transforms inject `:value`, `:checked` and `:selected` onto
|
|
115
|
+
* elements using `v-register`, which is load-bearing for SSR
|
|
116
|
+
* initial-render correctness. Omitting the plugin under CSR costs a
|
|
117
|
+
* one-frame flash on mount; omitting it under SSR produces visibly
|
|
118
|
+
* wrong initial HTML.
|
|
142
119
|
*
|
|
143
|
-
* Returns a two-plugin array
|
|
144
|
-
* main pre-plugin
|
|
145
|
-
*
|
|
146
|
-
* `attaform/directive`.
|
|
147
|
-
* registration
|
|
120
|
+
* Returns a two-plugin array, since Vite flattens nested plugin arrays:
|
|
121
|
+
* the main pre-plugin, plus a post-plugin rewriting each compiled SFC's
|
|
122
|
+
* `resolveDirective("register")` to a static import from
|
|
123
|
+
* `attaform/directive`. That rewrite is why no app-level directive
|
|
124
|
+
* registration is needed here; see
|
|
148
125
|
* `runtime/lib/core/transforms/directive-delivery-transform.ts` for the
|
|
149
126
|
* mechanism and its scope.
|
|
150
127
|
*/
|
package/dist/vite.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as resolveZodAliasTarget, i as isRewritableZodSpecifier } from './shared/attaform.
|
|
2
|
-
import { a as vRegisterPreambleTransform, r as redundantBindingWarnTransform, c as componentBridgeTransform, i as inputTextAreaNodeTransform, v as vRegisterHintTransform } from './shared/attaform.
|
|
1
|
+
import { r as resolveZodAliasTarget, i as isRewritableZodSpecifier } from './shared/attaform.BAf3UNn4.mjs';
|
|
2
|
+
import { a as vRegisterPreambleTransform, r as redundantBindingWarnTransform, c as componentBridgeTransform, i as inputTextAreaNodeTransform, v as vRegisterHintTransform } from './shared/attaform.ZYn2ahzJ.mjs';
|
|
3
3
|
import { parse, babelParse } from '@vue/compiler-sfc';
|
|
4
4
|
import { NodeTypes } from '@vue/compiler-core';
|
|
5
5
|
|
|
@@ -60,8 +60,13 @@ class SourceEditor {
|
|
|
60
60
|
return out;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
function canPossiblyInject(code) {
|
|
64
|
+
if (!code.includes("attaform")) return false;
|
|
65
|
+
return code.includes("useForm") || code.includes("injectForm");
|
|
66
|
+
}
|
|
63
67
|
function transformSsrAccessed(code, id) {
|
|
64
68
|
if (!id.endsWith(".vue")) return null;
|
|
69
|
+
if (!canPossiblyInject(code)) return null;
|
|
65
70
|
const { descriptor } = parse(code, { filename: id });
|
|
66
71
|
if (descriptor.scriptSetup === null || descriptor.template === null) return null;
|
|
67
72
|
const scriptSource = descriptor.scriptSetup.content;
|
|
@@ -303,7 +308,7 @@ function attaform(options = {}) {
|
|
|
303
308
|
|
|
304
309
|
// The panel runs inside Nuxt DevTools' overlay iframe, which itself
|
|
305
310
|
// is nested in the consumer's main page. \`window.parent\` only
|
|
306
|
-
// crosses one frame boundary
|
|
311
|
+
// crosses one frame boundary (the overlay UI), which doesn't have
|
|
307
312
|
// the bridge attached. The bridge lives on the consumer's main
|
|
308
313
|
// page, which sits at the top of the frame hierarchy. Walk the
|
|
309
314
|
// chain checking each ancestor frame so the same code works whether
|
package/dist/webpack.d.mts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { W as WebpackFamilyPlugin, a as WebpackFamilyPluginOptions } from './shared/attaform.C9fPTxjB.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* `attaform/webpack
|
|
4
|
+
* `attaform/webpack`, the webpack plugin that rewrites `attaform/zod`
|
|
5
5
|
* imports to the single matching adapter subpath (`attaform/zod-v3` or
|
|
6
6
|
* `attaform/zod-v4`) at build time, based on the consumer's installed Zod
|
|
7
7
|
* major. Without it, webpack ships both adapters because the unified
|
|
8
8
|
* `attaform/zod` entry imports both for runtime dispatch.
|
|
9
9
|
*
|
|
10
|
-
* Usage
|
|
10
|
+
* Usage, in an ESM config, since the plugin is ESM-only like the rest of
|
|
11
|
+
* the package:
|
|
11
12
|
*
|
|
12
13
|
* // webpack.config.mjs
|
|
13
14
|
* import { attaform } from 'attaform/webpack'
|
|
@@ -16,16 +17,12 @@ import { W as WebpackFamilyPlugin, a as WebpackFamilyPluginOptions } from './sha
|
|
|
16
17
|
* plugins: [attaform()],
|
|
17
18
|
* }
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* that pipeline register it once per app:
|
|
26
|
-
*
|
|
27
|
-
* import { installVRegister } from 'attaform/directive'
|
|
28
|
-
* installVRegister(app)
|
|
20
|
+
* The adapter rewrite is all this plugin does. Two things
|
|
21
|
+
* `attaform/vite` also provides do NOT transfer, because both are
|
|
22
|
+
* `@vitejs/plugin-vue`-specific: wire `attaform/transforms` into your
|
|
23
|
+
* Vue compiler for the SSR-critical template transforms, and register
|
|
24
|
+
* the directive once per app with `installVRegister(app)` from
|
|
25
|
+
* `attaform/directive`.
|
|
29
26
|
*
|
|
30
27
|
* Zero-dep: the plugin imports nothing from `webpack` (it taps the resolve
|
|
31
28
|
* hook the compiler injects at the consumer's build). Shares its body with
|
|
@@ -36,6 +33,17 @@ import { W as WebpackFamilyPlugin, a as WebpackFamilyPluginOptions } from './sha
|
|
|
36
33
|
type AttaformWebpackPluginOptions = WebpackFamilyPluginOptions;
|
|
37
34
|
/** The structural shape webpack requires of the plugin. */
|
|
38
35
|
type AttaformWebpackPlugin = WebpackFamilyPlugin;
|
|
36
|
+
/**
|
|
37
|
+
* webpack plugin that resolves `attaform/zod` to the one adapter subpath
|
|
38
|
+
* matching the installed Zod major, so the build ships a single adapter
|
|
39
|
+
* instead of both.
|
|
40
|
+
*
|
|
41
|
+
* ```js
|
|
42
|
+
* const { attaform } = require('attaform/webpack')
|
|
43
|
+
*
|
|
44
|
+
* module.exports = { plugins: [attaform()] }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
39
47
|
declare function attaform(options?: AttaformWebpackPluginOptions): AttaformWebpackPlugin;
|
|
40
48
|
|
|
41
49
|
export { attaform };
|
package/dist/webpack.mjs
CHANGED