attaform 0.17.1 → 0.18.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 (115) hide show
  1. package/README.md +77 -36
  2. package/dist/chunks/devtools.cjs +10 -37
  3. package/dist/chunks/devtools.cjs.map +1 -1
  4. package/dist/chunks/devtools.mjs +10 -37
  5. package/dist/chunks/devtools.mjs.map +1 -1
  6. package/dist/chunks/indexeddb.cjs +4 -4
  7. package/dist/chunks/indexeddb.cjs.map +1 -1
  8. package/dist/chunks/indexeddb.mjs +1 -1
  9. package/dist/chunks/local-storage.cjs +2 -2
  10. package/dist/chunks/local-storage.cjs.map +1 -1
  11. package/dist/chunks/local-storage.mjs +1 -1
  12. package/dist/chunks/session-storage.cjs +2 -2
  13. package/dist/chunks/session-storage.cjs.map +1 -1
  14. package/dist/chunks/session-storage.mjs +1 -1
  15. package/dist/index.cjs +42 -37
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +159 -196
  18. package/dist/index.d.mts +159 -196
  19. package/dist/index.d.ts +159 -196
  20. package/dist/index.mjs +5 -7
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/nuxt.cjs +31 -40
  23. package/dist/nuxt.cjs.map +1 -1
  24. package/dist/nuxt.d.cts +8 -1
  25. package/dist/nuxt.d.mts +8 -1
  26. package/dist/nuxt.d.ts +8 -1
  27. package/dist/nuxt.mjs +32 -41
  28. package/dist/nuxt.mjs.map +1 -1
  29. package/dist/runtime/components/AttaformDevtoolsPanel.d.vue.ts +7 -0
  30. package/dist/runtime/components/AttaformDevtoolsPanel.vue +453 -0
  31. package/dist/runtime/components/AttaformDevtoolsPanel.vue.d.ts +7 -0
  32. package/dist/runtime/components/DevtoolsValueTree.d.vue.ts +37 -0
  33. package/dist/runtime/components/DevtoolsValueTree.vue +192 -0
  34. package/dist/runtime/components/DevtoolsValueTree.vue.d.ts +37 -0
  35. package/dist/runtime/plugins/attaform.cjs +17 -6
  36. package/dist/runtime/plugins/attaform.cjs.map +1 -1
  37. package/dist/runtime/plugins/attaform.mjs +15 -4
  38. package/dist/runtime/plugins/attaform.mjs.map +1 -1
  39. package/dist/shared/attaform.5UhpSVFI.cjs +63 -0
  40. package/dist/shared/attaform.5UhpSVFI.cjs.map +1 -0
  41. package/dist/shared/attaform.BDdFdjeX.mjs +57 -0
  42. package/dist/shared/attaform.BDdFdjeX.mjs.map +1 -0
  43. package/dist/shared/attaform.Bgu9l6OG.d.cts +1651 -0
  44. package/dist/shared/attaform.BmDBu4ql.d.ts +1651 -0
  45. package/dist/shared/{attaform.Dee2rU1P.cjs → attaform.BqK_L4gK.cjs} +310 -24
  46. package/dist/shared/attaform.BqK_L4gK.cjs.map +1 -0
  47. package/dist/shared/{attaform.C_5aB6EQ.d.mts → attaform.BsMdl-35.d.cts} +754 -146
  48. package/dist/shared/{attaform.C_5aB6EQ.d.ts → attaform.BsMdl-35.d.mts} +754 -146
  49. package/dist/shared/{attaform.C_5aB6EQ.d.cts → attaform.BsMdl-35.d.ts} +754 -146
  50. package/dist/shared/attaform.Bubm_slq.cjs.map +1 -1
  51. package/dist/shared/attaform.C3x1hKJC.d.mts +53 -0
  52. package/dist/shared/{attaform.CuE-bS1C.d.mts → attaform.CWs1Z3p7.d.ts} +57 -23
  53. package/dist/shared/attaform.CXpzmj38.mjs.map +1 -1
  54. package/dist/shared/attaform.CjmJpfLH.d.ts +53 -0
  55. package/dist/shared/{attaform.CVCmBKZX.mjs → attaform.CtNUB9nf.mjs} +74 -72
  56. package/dist/shared/attaform.CtNUB9nf.mjs.map +1 -0
  57. package/dist/shared/{attaform.C0iFnTN0.d.ts → attaform.D-hDvb98.d.cts} +57 -23
  58. package/dist/shared/attaform.DAH3kvav.d.mts +1651 -0
  59. package/dist/shared/{attaform.B5qiXQwN.cjs → attaform.DUHru0OF.cjs} +83 -81
  60. package/dist/shared/attaform.DUHru0OF.cjs.map +1 -0
  61. package/dist/shared/{attaform.BV40t5y2.cjs → attaform.Dlk1jMuv.cjs} +245 -108
  62. package/dist/shared/attaform.Dlk1jMuv.cjs.map +1 -0
  63. package/dist/shared/{attaform.B3ZaPIzS.mjs → attaform.DsC3rZHG.mjs} +1804 -219
  64. package/dist/shared/attaform.DsC3rZHG.mjs.map +1 -0
  65. package/dist/shared/attaform.Dzi89x8N.d.cts +53 -0
  66. package/dist/shared/{attaform.Cer8JO_P.cjs → attaform.II89Pcf4.cjs} +1860 -272
  67. package/dist/shared/attaform.II89Pcf4.cjs.map +1 -0
  68. package/dist/shared/{attaform.CIEQgJnM.mjs → attaform.Xhg0AYNa.mjs} +300 -26
  69. package/dist/shared/attaform.Xhg0AYNa.mjs.map +1 -0
  70. package/dist/shared/{attaform.CpERWz3u.mjs → attaform.Xt0A3QUd.mjs} +232 -95
  71. package/dist/shared/attaform.Xt0A3QUd.mjs.map +1 -0
  72. package/dist/shared/{attaform.CHorcsIU.d.cts → attaform.bH7WvNad.d.mts} +57 -23
  73. package/dist/vite.cjs +270 -2
  74. package/dist/vite.cjs.map +1 -1
  75. package/dist/vite.mjs +266 -2
  76. package/dist/vite.mjs.map +1 -1
  77. package/dist/zod-v3.cjs +11 -8
  78. package/dist/zod-v3.cjs.map +1 -1
  79. package/dist/zod-v3.d.cts +36 -84
  80. package/dist/zod-v3.d.mts +36 -84
  81. package/dist/zod-v3.d.ts +36 -84
  82. package/dist/zod-v3.mjs +3 -3
  83. package/dist/zod-v4.cjs +11 -8
  84. package/dist/zod-v4.cjs.map +1 -1
  85. package/dist/zod-v4.d.cts +5 -5
  86. package/dist/zod-v4.d.mts +5 -5
  87. package/dist/zod-v4.d.ts +5 -5
  88. package/dist/zod-v4.mjs +3 -3
  89. package/dist/zod.cjs +13 -10
  90. package/dist/zod.cjs.map +1 -1
  91. package/dist/zod.d.cts +127 -15
  92. package/dist/zod.d.mts +127 -15
  93. package/dist/zod.d.ts +127 -15
  94. package/dist/zod.mjs +5 -5
  95. package/dist/zod.mjs.map +1 -1
  96. package/package.json +19 -5
  97. package/dist/shared/attaform.B1jvxsOF.d.mts +0 -156
  98. package/dist/shared/attaform.B3ZaPIzS.mjs.map +0 -1
  99. package/dist/shared/attaform.B5qiXQwN.cjs.map +0 -1
  100. package/dist/shared/attaform.BBM2muQ9.cjs +0 -101
  101. package/dist/shared/attaform.BBM2muQ9.cjs.map +0 -1
  102. package/dist/shared/attaform.BV40t5y2.cjs.map +0 -1
  103. package/dist/shared/attaform.C6qzEdIM.d.cts +0 -156
  104. package/dist/shared/attaform.C8LVFVVe.cjs +0 -32
  105. package/dist/shared/attaform.C8LVFVVe.cjs.map +0 -1
  106. package/dist/shared/attaform.CIEQgJnM.mjs.map +0 -1
  107. package/dist/shared/attaform.CTwNcpLE.d.ts +0 -156
  108. package/dist/shared/attaform.CVCmBKZX.mjs.map +0 -1
  109. package/dist/shared/attaform.Cer8JO_P.cjs.map +0 -1
  110. package/dist/shared/attaform.CpERWz3u.mjs.map +0 -1
  111. package/dist/shared/attaform.Dee2rU1P.cjs.map +0 -1
  112. package/dist/shared/attaform.Vo-Kft0t.mjs +0 -29
  113. package/dist/shared/attaform.Vo-Kft0t.mjs.map +0 -1
  114. package/dist/shared/attaform.h1sq3BFu.mjs +0 -92
  115. package/dist/shared/attaform.h1sq3BFu.mjs.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "attaform",
3
- "version": "0.17.1",
3
+ "version": "0.18.0",
4
4
  "main": "./dist/index.mjs",
5
5
  "types": "./dist/index.d.mts",
6
6
  "files": [
@@ -41,6 +41,9 @@
41
41
  "types": "./dist/vite.d.mts",
42
42
  "import": "./dist/vite.mjs"
43
43
  },
44
+ "./devtools-panel": {
45
+ "default": "./dist/runtime/components/AttaformDevtoolsPanel.vue"
46
+ },
44
47
  "./transforms": {
45
48
  "types": "./dist/transforms.d.mts",
46
49
  "import": "./dist/transforms.mjs"
@@ -83,6 +86,9 @@
83
86
  ],
84
87
  "license": "MIT",
85
88
  "type": "module",
89
+ "dependencies": {
90
+ "magic-string": "^0.30.21"
91
+ },
86
92
  "devDependencies": {
87
93
  "@commitlint/cli": "^21.0.1",
88
94
  "@commitlint/config-conventional": "^21.0.1",
@@ -100,9 +106,11 @@
100
106
  "@types/node": "^25.6.0",
101
107
  "@typescript-eslint/eslint-plugin": "^8.59.0",
102
108
  "@typescript-eslint/parser": "^8.59.0",
109
+ "@nuxt/devtools-kit": "^3.2.0",
103
110
  "@vitejs/plugin-vue": "^6.0.6",
104
111
  "@vitest/coverage-v8": "^4.1.5",
105
112
  "@vue/compiler-core": "^3.5.33",
113
+ "@vue/compiler-sfc": "^3.5.33",
106
114
  "@vue/devtools-api": "^8.1.1",
107
115
  "@vue/language-server": "^3.2.7",
108
116
  "@vue/server-renderer": "^3.5.33",
@@ -139,7 +147,9 @@
139
147
  "zod-v3": "npm:zod@^3.24"
140
148
  },
141
149
  "peerDependencies": {
150
+ "@nuxt/devtools-kit": "^2.0.0 || ^3.0.0",
142
151
  "@vue/compiler-core": ">=3.5.0",
152
+ "@vue/compiler-sfc": ">=3.5.0",
143
153
  "@vue/devtools-api": "^6.6.0 || ^7.0.0",
144
154
  "lodash-es": ">= 4.0.0",
145
155
  "nuxt": ">=3.0.0",
@@ -148,6 +158,9 @@
148
158
  "zod": ">=3.0.0"
149
159
  },
150
160
  "peerDependenciesMeta": {
161
+ "@nuxt/devtools-kit": {
162
+ "optional": true
163
+ },
151
164
  "@vue/devtools-api": {
152
165
  "optional": true
153
166
  },
@@ -175,13 +188,14 @@
175
188
  "typecheck": "tsc --noEmit",
176
189
  "prepack:watch": "chokidar 'src/**/*' -c 'pnpm prepack' --initial",
177
190
  "release": "pnpm check && pnpm version patch && pnpm prepack && pnpm publish && git push --follow-tags",
178
- "test": "vitest run",
191
+ "test": "node scripts/run-with-webstorage-flag.mjs vitest run",
179
192
  "test:types": "pnpm dev:prepare && vue-tsc --noEmit && cd apps/site && vue-tsc --noEmit",
180
- "test:watch": "vitest watch",
181
- "bench": "vitest bench --run",
193
+ "test:watch": "node scripts/run-with-webstorage-flag.mjs vitest watch",
194
+ "bench": "node scripts/run-with-webstorage-flag.mjs vitest bench --run",
182
195
  "check:size": "pnpm prepack && size-limit",
183
- "check:coverage": "vitest run --coverage",
196
+ "check:coverage": "node scripts/run-with-webstorage-flag.mjs vitest run --coverage",
184
197
  "check:bench": "node scripts/check-bench.mjs",
198
+ "check:bundled-types": "node scripts/check-bundled-types.mjs",
185
199
  "check:site": "pnpm dev:prepare && pnpm --filter attaform-site typecheck",
186
200
  "version": "node scripts/promote-changelog.mjs && (node scripts/generate-release-notes.mjs || echo '[version] release-notes step failed; continuing') && git add CHANGELOG.md RELEASES.md"
187
201
  }
@@ -1,156 +0,0 @@
1
- import { G as GenericForm, F as FormKey, d as UseFormReturnType, R as RegisterValue } from './attaform.C_5aB6EQ.mjs';
2
- import { Ref } from 'vue';
3
-
4
- /**
5
- * Access an existing form from a descendant component without passing
6
- * it through props. Counterpart to `useForm` — `useForm` creates and
7
- * provides; `injectForm` looks up via Vue's inject mechanism.
8
- *
9
- * Two ways to call it:
10
- *
11
- * ```ts
12
- * // Reach the nearest ancestor's anonymous useForm() call.
13
- * const form = injectForm<SignupShape>()
14
- *
15
- * // Reach a specific form by its key — works from anywhere in the app.
16
- * const cart = injectForm<CartShape>('cart')
17
- * ```
18
- *
19
- * Resolution rules (no-key form):
20
- * - Closest ambient ancestor wins.
21
- * - Only anonymous `useForm()` (no `key`) fills the ambient slot;
22
- * keyed forms are reachable only via `injectForm(key)`.
23
- * - Inherits the resolved ancestor's `formInstanceId`.
24
- *
25
- * Resolution rules (keyed form): registry lookup by string key,
26
- * independent of component-tree position.
27
- *
28
- * Returns `null` when no matching form exists (no ambient ancestor, or
29
- * the named key isn't registered). A dev-mode warning points at the
30
- * call site to help diagnose typos. Always narrow before using:
31
- *
32
- * ```ts
33
- * const form = injectForm<Shape>('signup')
34
- * if (!form) return
35
- * form.register('email')
36
- * ```
37
- *
38
- * Pass the `Form` generic explicitly — Vue's provide/inject erases
39
- * generics, so the library can't recover the shape automatically.
40
- *
41
- * The form is kept alive for this component's lifetime; once every
42
- * consumer unmounts, the form is cleaned up automatically.
43
- */
44
- declare function injectForm<Form extends GenericForm, GetValueFormType extends GenericForm = Form>(key?: FormKey): UseFormReturnType<Form, GetValueFormType> | null;
45
-
46
- /**
47
- * Re-bind a parent's `v-register` onto an inner native element. Use
48
- * inside a component that wraps a single form field whose root is
49
- * NOT the input itself (e.g. a labelled-row that renders `<label>`
50
- * around the input).
51
- *
52
- * ```vue
53
- * <!-- Parent -->
54
- * <MyInput v-register="form.register('email')" />
55
- *
56
- * <!-- MyInput.vue -->
57
- * <script setup lang="ts">
58
- * import { useRegister } from 'attaform'
59
- * const rv = useRegister()
60
- * // rv.path / rv.segments / rv.formKey / rv.formInstanceId / rv.innerRef
61
- * // are all reachable directly — no `.value` unwrap.
62
- * </script>
63
- *
64
- * <template>
65
- * <label class="field">
66
- * <span>Email</span>
67
- * <input v-register="rv" />
68
- * </label>
69
- * </template>
70
- * ```
71
- *
72
- * Returns a hybrid Proxy: it answers `__v_isRef` / `.value` like a
73
- * Vue `Ref<RegisterValue | undefined>` (so templates auto-unwrap
74
- * correctly and `v-register="rv"` feeds the underlying RV to the
75
- * directive — preserving the directive's path-migration diff across
76
- * renders), AND every other property read pierces to the captured
77
- * RV's field (so `rv.path` works directly in script setup). Reads
78
- * inside reactive scopes (`computed` / `watchEffect`) track the
79
- * underlying `shallowRef`, so `rv.path` re-runs when the parent
80
- * rebinds to a different path.
81
- *
82
- * Unbound state: when the parent didn't pass `v-register`, every
83
- * piercing read returns `undefined` at runtime, and the return type
84
- * surfaces this honestly as `UseRegisterReturn<V> | undefined`.
85
- * Consumers defend with optional chaining (`rv?.formKey`,
86
- * `rv?.segments`); the directive accepts `undefined` peacefully (its
87
- * binding value type is already `RegisterValue<V> | undefined`), so
88
- * `v-register="rv"` works whether or not a parent has bound. The
89
- * composable's `onMounted` warn fires once per instance to surface
90
- * the misuse case at runtime.
91
- *
92
- * Diagnostic: in dev mode, a single `console.warn` fires per instance
93
- * at `onMounted` if the captured value is still `undefined` — by then
94
- * the parent has had its full mount lifecycle to bind, so a missing
95
- * binding is conclusive misuse. The warn does NOT fire on every read
96
- * of the proxy, and is intentionally silent under SSR
97
- * (`renderToString` skips `onMounted`); the CSR hydration pass
98
- * surfaces the same diagnostic without double-counting through Nuxt's
99
- * `dev:ssr-logs` channel.
100
- *
101
- * When the wrapper's root IS the input itself, Vue's attribute
102
- * fallthrough handles the binding and `useRegister` is unnecessary.
103
- * For wrappers that bind multiple fields (compound forms), use
104
- * `injectForm<Form>(key?)` and call `ctx.register(...)` directly.
105
- */
106
-
107
- /**
108
- * Return type of `useRegister()`. Hybrid of `RegisterValue<V>` (so
109
- * `rv.path` / `rv.segments` / `rv.formKey` etc. work directly in
110
- * script setup) and `Ref<RegisterValue<V> | undefined>` (so Vue's
111
- * template auto-unwrap surfaces the underlying RV to `v-register`
112
- * and the directive's path-migration diff sees the real RV across
113
- * renders).
114
- *
115
- * The two surfaces don't clash at the type level: `RegisterValue`
116
- * doesn't carry a `value` field, and `Ref<T>`'s `value: T` becomes
117
- * the hybrid's only `.value`. Older code that read `rv.value?.path`
118
- * keeps working; new code can write `rv.path` directly.
119
- */
120
- type UseRegisterReturn<V = unknown> = RegisterValue<V> & Ref<RegisterValue<V> | undefined>;
121
- declare function useRegister<V = unknown>(): UseRegisterReturn<V> | undefined;
122
-
123
- /**
124
- * Stable identifiers for library-emitted `ValidationError` codes.
125
- *
126
- * Convention: `<scope>:<kebab-case-identifier>`. Three scopes are
127
- * recognised by the library:
128
- *
129
- * - `atta:` — emitted by the framework-agnostic core (this map).
130
- * - `zod:` — emitted by the Zod adapter; computed inline from
131
- * `issue.code` (e.g. `zod:too_small`). No enum here because
132
- * Zod's code list evolves.
133
- * - consumer-defined — anything the consumer's backend / app stamps
134
- * onto a `ValidationError` (via the `parseApiErrors` wire payload
135
- * or `setFieldErrors` directly). Pick a scope (`api:`, `auth:`,
136
- * etc.) and stay consistent.
137
- *
138
- * Use these constants in tests and error-routing UI:
139
- *
140
- * ```ts
141
- * if (error.code === AttaformErrorCode.NoValueSupplied) {
142
- * // user hasn't filled this field
143
- * }
144
- * ```
145
- */
146
- declare const AttaformErrorCode: {
147
- /** A required field is in the blank set — user hasn't supplied a value. */
148
- readonly NoValueSupplied: "atta:no-value-supplied";
149
- /** The schema adapter's `validateAtPath` threw synchronously. */
150
- readonly AdapterThrew: "atta:adapter-threw";
151
- /** The supplied path didn't resolve to any node in the schema. */
152
- readonly PathNotFound: "atta:path-not-found";
153
- };
154
- type AttaformErrorCode = (typeof AttaformErrorCode)[keyof typeof AttaformErrorCode];
155
-
156
- export { AttaformErrorCode as A, injectForm as i, useRegister as u };