attaform 0.21.1 → 0.21.2

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 (108) hide show
  1. package/dist/chunks/dev-key-collision-warnings.cjs +1 -1
  2. package/dist/chunks/dev-key-collision-warnings.mjs +1 -1
  3. package/dist/chunks/devtools.cjs +1 -1
  4. package/dist/chunks/devtools.mjs +1 -1
  5. package/dist/chunks/fingerprint2.cjs +1 -1
  6. package/dist/chunks/fingerprint2.mjs +1 -1
  7. package/dist/chunks/indexeddb.cjs +1 -1
  8. package/dist/chunks/indexeddb.mjs +1 -1
  9. package/dist/chunks/local-storage.cjs +1 -1
  10. package/dist/chunks/local-storage.mjs +1 -1
  11. package/dist/chunks/multi-tab-sync.cjs +2 -2
  12. package/dist/chunks/multi-tab-sync.mjs +2 -2
  13. package/dist/chunks/session-storage.cjs +1 -1
  14. package/dist/chunks/session-storage.mjs +1 -1
  15. package/dist/chunks/wire-persistence.cjs +2 -2
  16. package/dist/chunks/wire-persistence.mjs +2 -2
  17. package/dist/index.cjs +37 -24
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +20 -18
  20. package/dist/index.d.mts +20 -18
  21. package/dist/index.d.ts +20 -18
  22. package/dist/index.mjs +38 -25
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/nuxt.d.cts +1 -1
  25. package/dist/nuxt.d.mts +1 -1
  26. package/dist/nuxt.d.ts +1 -1
  27. package/dist/runtime/components/AttaformDevtoolsPanel.vue +396 -216
  28. package/dist/runtime/components/DevtoolsValueTree.vue +176 -114
  29. package/dist/runtime/plugins/attaform.cjs +2 -2
  30. package/dist/runtime/plugins/attaform.mjs +2 -2
  31. package/dist/shared/{attaform.D32WwKk6.cjs → attaform.B5LNzqQh.cjs} +243 -352
  32. package/dist/shared/attaform.B5LNzqQh.cjs.map +1 -0
  33. package/dist/shared/{attaform.S-pYLSo4.cjs → attaform.BBDIKtKY.cjs} +13 -16
  34. package/dist/shared/attaform.BBDIKtKY.cjs.map +1 -0
  35. package/dist/shared/{attaform.Bv7dRDWK.d.ts → attaform.BCcrLApm.d.mts} +54 -63
  36. package/dist/shared/{attaform.BupwXkj_.mjs → attaform.BFWb6hDk.mjs} +29 -23
  37. package/dist/shared/attaform.BFWb6hDk.mjs.map +1 -0
  38. package/dist/shared/{attaform.BWfliRIK.d.cts → attaform.BGf_J22U.d.ts} +54 -63
  39. package/dist/shared/{attaform.DMEP_ENr.mjs → attaform.BVeLgfEh.mjs} +14 -17
  40. package/dist/shared/attaform.BVeLgfEh.mjs.map +1 -0
  41. package/dist/shared/{attaform.MtrpT6Ki.d.ts → attaform.BYgioWLF.d.ts} +1 -1
  42. package/dist/shared/{attaform.NQ8mybyW.d.mts → attaform.BkjJfMvJ.d.cts} +54 -63
  43. package/dist/shared/{attaform.Duecg2NO.d.mts → attaform.BoY6RZUl.d.cts} +1 -1
  44. package/dist/shared/{attaform.Bq5sX7TF.cjs → attaform.BwLp9KM7.cjs} +2 -2
  45. package/dist/shared/{attaform.Bq5sX7TF.cjs.map → attaform.BwLp9KM7.cjs.map} +1 -1
  46. package/dist/shared/{attaform.CICFZ1iS.cjs → attaform.BwrowMp2.cjs} +19 -45
  47. package/dist/shared/attaform.BwrowMp2.cjs.map +1 -0
  48. package/dist/shared/{attaform.Y1ZGhM4k.mjs → attaform.C41gjp-a.mjs} +2 -2
  49. package/dist/shared/{attaform.Y1ZGhM4k.mjs.map → attaform.C41gjp-a.mjs.map} +1 -1
  50. package/dist/shared/{attaform.BM6YD9kZ.cjs → attaform.CR6wGvNu.cjs} +29 -23
  51. package/dist/shared/attaform.CR6wGvNu.cjs.map +1 -0
  52. package/dist/shared/{attaform.DR6RmxWZ.mjs → attaform.CTheKoTc.mjs} +341 -221
  53. package/dist/shared/attaform.CTheKoTc.mjs.map +1 -0
  54. package/dist/shared/{attaform.BSkvn43g.cjs → attaform.CcnF1AKJ.cjs} +4 -4
  55. package/dist/shared/attaform.CcnF1AKJ.cjs.map +1 -0
  56. package/dist/shared/{attaform.FudOcHaa.d.cts → attaform.CnEl--PF.d.mts} +1 -1
  57. package/dist/shared/{attaform.DozgVlCE.mjs → attaform.CrD73S4m.mjs} +4 -4
  58. package/dist/shared/attaform.CrD73S4m.mjs.map +1 -0
  59. package/dist/shared/{attaform.ClXwitZj.cjs → attaform.D2ZuIOCf.cjs} +347 -226
  60. package/dist/shared/attaform.D2ZuIOCf.cjs.map +1 -0
  61. package/dist/shared/{attaform.Be8NZG9M.mjs → attaform.D6GYGshL.mjs} +19 -45
  62. package/dist/shared/attaform.D6GYGshL.mjs.map +1 -0
  63. package/dist/shared/{attaform.pmtahXKy.mjs → attaform.DP-u7_tk.mjs} +243 -352
  64. package/dist/shared/attaform.DP-u7_tk.mjs.map +1 -0
  65. package/dist/shared/{attaform.D0dWZsJt.d.mts → attaform.ory-3WhV.d.cts} +128 -129
  66. package/dist/shared/{attaform.D0dWZsJt.d.cts → attaform.ory-3WhV.d.mts} +128 -129
  67. package/dist/shared/{attaform.D0dWZsJt.d.ts → attaform.ory-3WhV.d.ts} +128 -129
  68. package/dist/transforms.cjs +1 -1
  69. package/dist/transforms.mjs +1 -1
  70. package/dist/vite.cjs +1 -1
  71. package/dist/vite.mjs +1 -1
  72. package/dist/zod-v3.cjs +3 -4
  73. package/dist/zod-v3.cjs.map +1 -1
  74. package/dist/zod-v3.d.cts +4 -4
  75. package/dist/zod-v3.d.mts +4 -4
  76. package/dist/zod-v3.d.ts +4 -4
  77. package/dist/zod-v3.mjs +2 -3
  78. package/dist/zod-v3.mjs.map +1 -1
  79. package/dist/zod-v4.cjs +3 -4
  80. package/dist/zod-v4.cjs.map +1 -1
  81. package/dist/zod-v4.d.cts +4 -4
  82. package/dist/zod-v4.d.mts +4 -4
  83. package/dist/zod-v4.d.ts +4 -4
  84. package/dist/zod-v4.mjs +2 -3
  85. package/dist/zod-v4.mjs.map +1 -1
  86. package/dist/zod.cjs +6 -6
  87. package/dist/zod.cjs.map +1 -1
  88. package/dist/zod.d.cts +31 -22
  89. package/dist/zod.d.mts +31 -22
  90. package/dist/zod.d.ts +31 -22
  91. package/dist/zod.mjs +5 -6
  92. package/dist/zod.mjs.map +1 -1
  93. package/package.json +3 -11
  94. package/dist/shared/attaform.BM6YD9kZ.cjs.map +0 -1
  95. package/dist/shared/attaform.BSkvn43g.cjs.map +0 -1
  96. package/dist/shared/attaform.Be8NZG9M.mjs.map +0 -1
  97. package/dist/shared/attaform.BupwXkj_.mjs.map +0 -1
  98. package/dist/shared/attaform.CICFZ1iS.cjs.map +0 -1
  99. package/dist/shared/attaform.ClXwitZj.cjs.map +0 -1
  100. package/dist/shared/attaform.D32WwKk6.cjs.map +0 -1
  101. package/dist/shared/attaform.DMEP_ENr.mjs.map +0 -1
  102. package/dist/shared/attaform.DR6RmxWZ.mjs.map +0 -1
  103. package/dist/shared/attaform.DozgVlCE.mjs.map +0 -1
  104. package/dist/shared/attaform.S-pYLSo4.cjs.map +0 -1
  105. package/dist/shared/attaform.pmtahXKy.mjs.map +0 -1
  106. package/dist/shared/{attaform.DSD85fHb.d.cts → attaform.nf83TIR5.d.cts} +10 -10
  107. package/dist/shared/{attaform.DSD85fHb.d.mts → attaform.nf83TIR5.d.mts} +10 -10
  108. package/dist/shared/{attaform.DSD85fHb.d.ts → attaform.nf83TIR5.d.ts} +10 -10
@@ -1,125 +1,187 @@
1
- <script setup>
2
- import { computed, nextTick, ref } from "vue";
3
- const props = defineProps({
4
- value: { type: null, required: true },
5
- label: { type: String, required: false },
6
- depth: { type: Number, required: false },
7
- path: { type: Array, required: false },
8
- editable: { type: Boolean, required: false, skipCheck: true },
9
- onEdit: { type: Function, required: false, skipCheck: true },
10
- selectedKey: { type: null, required: false },
11
- onSelectPath: { type: Function, required: false, skipCheck: true }
12
- });
13
- const depth = computed(() => props.depth ?? 0);
14
- const expanded = ref(depth.value < 2);
15
- const path = computed(() => props.path ?? []);
16
- const type = computed(() => {
17
- const v = props.value;
18
- if (v === null) return "null";
19
- if (v === void 0) return "undefined";
20
- if (typeof v === "string") return "string";
21
- if (typeof v === "number") return "number";
22
- if (typeof v === "boolean") return "boolean";
23
- if (Array.isArray(v)) return "array";
24
- if (typeof v === "object") return "object";
25
- return "other";
26
- });
27
- const isLeaf = computed(() => type.value !== "array" && type.value !== "object");
28
- const entries = computed(() => {
29
- const v = props.value;
30
- if (Array.isArray(v)) return v.map((item, i) => [String(i), item]);
31
- if (v !== null && typeof v === "object") {
32
- return Object.entries(v);
1
+ <script setup lang="ts">
2
+ import { computed, nextTick, ref } from 'vue'
3
+
4
+ const props = defineProps<{
5
+ value: unknown
6
+ label?: string
7
+ depth?: number
8
+ /**
9
+ * Path-from-root for this node. Used by edit-aware mounts so the
10
+ * commit handler knows which leaf the user just touched. Default
11
+ * `[]` for non-editable mounts; the panel passes the explicit path
12
+ * when it wires up `onEdit`.
13
+ */
14
+ path?: ReadonlyArray<string | number>
15
+ /**
16
+ * Edit-mode toggle. When `true` and `onEdit` is wired, leaf cells
17
+ * become click-to-edit. Values render raw (DevTools does not redact).
18
+ */
19
+ editable?: boolean | undefined
20
+ onEdit?: ((path: ReadonlyArray<string | number>, next: unknown) => void) | undefined
21
+ /**
22
+ * Canonical JSON-array key of the currently-selected path (`null`
23
+ * for no selection). Compared against this node's own key so the
24
+ * key label can render in a highlighted state. Plumbed as a key
25
+ * rather than a path array because string equality is cheap and
26
+ * cross-renders consistently.
27
+ */
28
+ selectedKey?: string | null | undefined
29
+ /**
30
+ * Click handler for the key label. Called with the node's current
31
+ * path-from-root; the panel toggles selection on identical paths.
32
+ * When omitted, the key label is plain text (no selection UX).
33
+ */
34
+ onSelectPath?: ((path: ReadonlyArray<string | number>) => void) | undefined
35
+ }>()
36
+
37
+ // Top-level expanded by default; deeper nodes collapsed past 2 levels
38
+ // so a deeply-nested form doesn't paint a wall of text on first render.
39
+ const depth = computed(() => props.depth ?? 0)
40
+ const expanded = ref(depth.value < 2)
41
+ const path = computed<ReadonlyArray<string | number>>(() => props.path ?? [])
42
+
43
+ const type = computed<
44
+ 'null' | 'undefined' | 'array' | 'object' | 'string' | 'number' | 'boolean' | 'other'
45
+ >(() => {
46
+ const v = props.value
47
+ if (v === null) return 'null'
48
+ if (v === undefined) return 'undefined'
49
+ if (typeof v === 'string') return 'string'
50
+ if (typeof v === 'number') return 'number'
51
+ if (typeof v === 'boolean') return 'boolean'
52
+ if (Array.isArray(v)) return 'array'
53
+ if (typeof v === 'object') return 'object'
54
+ return 'other'
55
+ })
56
+
57
+ const isLeaf = computed(() => type.value !== 'array' && type.value !== 'object')
58
+
59
+ const entries = computed<ReadonlyArray<readonly [string, unknown]>>(() => {
60
+ const v = props.value
61
+ if (Array.isArray(v)) return v.map((item, i) => [String(i), item] as const)
62
+ if (v !== null && typeof v === 'object') {
63
+ return Object.entries(v as Record<string, unknown>)
64
+ }
65
+ return []
66
+ })
67
+
68
+ const formatted = computed(() => {
69
+ const v = props.value
70
+ if (v === null) return 'null'
71
+ if (v === undefined) return 'undefined'
72
+ if (typeof v === 'string') return `"${v}"`
73
+ if (typeof v === 'boolean' || typeof v === 'number') return String(v)
74
+ return String(v)
75
+ })
76
+
77
+ const summary = computed(() => {
78
+ const v = props.value
79
+ if (Array.isArray(v)) return `Array(${v.length})`
80
+ if (v !== null && typeof v === 'object') {
81
+ const keys = Object.keys(v as Record<string, unknown>)
82
+ return `{${keys.length}}`
83
+ }
84
+ return ''
85
+ })
86
+
87
+ // Edit mode -----------------------------------------------------------
88
+
89
+ const isEditableLeaf = computed(() => {
90
+ if (!props.editable || props.onEdit === undefined) return false
91
+ return type.value === 'string' || type.value === 'number' || type.value === 'boolean'
92
+ })
93
+
94
+ const editing = ref(false)
95
+ const editValue = ref('')
96
+ const editInput = ref<HTMLInputElement | null>(null)
97
+ const editRejected = ref(false)
98
+
99
+ function childPath(rawKey: string): ReadonlyArray<string | number> {
100
+ // Array indices arrive as stringified numbers from `Object.entries` /
101
+ // `array.map`. Coerce back to numbers when the parent is an array
102
+ // so `canonicalizePath` on the consumer side gets a structured Path
103
+ // with the right shape — `["users", 0, "name"]`, not
104
+ // `["users", "0", "name"]`.
105
+ if (type.value === 'array') return [...path.value, Number(rawKey)]
106
+ return [...path.value, rawKey]
107
+ }
108
+
109
+ async function startEdit(): Promise<void> {
110
+ if (!isEditableLeaf.value) return
111
+ editValue.value =
112
+ type.value === 'boolean' || type.value === 'number'
113
+ ? String(props.value ?? '')
114
+ : (props.value as string)
115
+ editing.value = true
116
+ editRejected.value = false
117
+ await nextTick()
118
+ editInput.value?.focus()
119
+ editInput.value?.select?.()
33
120
  }
34
- return [];
35
- });
36
- const formatted = computed(() => {
37
- const v = props.value;
38
- if (v === null) return "null";
39
- if (v === void 0) return "undefined";
40
- if (typeof v === "string") return `"${v}"`;
41
- if (typeof v === "boolean" || typeof v === "number") return String(v);
42
- return String(v);
43
- });
44
- const summary = computed(() => {
45
- const v = props.value;
46
- if (Array.isArray(v)) return `Array(${v.length})`;
47
- if (v !== null && typeof v === "object") {
48
- const keys = Object.keys(v);
49
- return `{${keys.length}}`;
121
+
122
+ function flashRejected(): void {
123
+ editRejected.value = true
124
+ setTimeout(() => {
125
+ editRejected.value = false
126
+ }, 600)
50
127
  }
51
- return "";
52
- });
53
- const isEditableLeaf = computed(() => {
54
- if (!props.editable || props.onEdit === void 0) return false;
55
- return type.value === "string" || type.value === "number" || type.value === "boolean";
56
- });
57
- const editing = ref(false);
58
- const editValue = ref("");
59
- const editInput = ref(null);
60
- const editRejected = ref(false);
61
- function childPath(rawKey) {
62
- if (type.value === "array") return [...path.value, Number(rawKey)];
63
- return [...path.value, rawKey];
64
- }
65
- async function startEdit() {
66
- if (!isEditableLeaf.value) return;
67
- editValue.value = type.value === "boolean" || type.value === "number" ? String(props.value ?? "") : props.value;
68
- editing.value = true;
69
- editRejected.value = false;
70
- await nextTick();
71
- editInput.value?.focus();
72
- editInput.value?.select?.();
73
- }
74
- function flashRejected() {
75
- editRejected.value = true;
76
- setTimeout(() => {
77
- editRejected.value = false;
78
- }, 600);
79
- }
80
- function commitEdit() {
81
- if (!editing.value || props.onEdit === void 0) return;
82
- let next = editValue.value;
83
- if (type.value === "number") {
84
- const parsed = Number(editValue.value);
85
- if (!Number.isFinite(parsed)) {
86
- flashRejected();
87
- editing.value = false;
88
- return;
128
+
129
+ function commitEdit(): void {
130
+ if (!editing.value || props.onEdit === undefined) return
131
+ let next: unknown = editValue.value
132
+ if (type.value === 'number') {
133
+ const parsed = Number(editValue.value)
134
+ if (!Number.isFinite(parsed)) {
135
+ flashRejected()
136
+ editing.value = false
137
+ return
138
+ }
139
+ next = parsed
140
+ } else if (type.value === 'boolean') {
141
+ // Boolean leaves go through a checkbox commit path that calls the
142
+ // emitter directly; this branch is defensive in case a text-mode
143
+ // commit lands on a boolean leaf.
144
+ next = editValue.value === 'true'
89
145
  }
90
- next = parsed;
91
- } else if (type.value === "boolean") {
92
- next = editValue.value === "true";
146
+ if (next !== props.value) props.onEdit(path.value, next)
147
+ editing.value = false
148
+ }
149
+
150
+ function cancelEdit(): void {
151
+ editing.value = false
152
+ editRejected.value = false
153
+ }
154
+
155
+ function toggleBoolean(checked: boolean): void {
156
+ if (!isEditableLeaf.value || props.onEdit === undefined) return
157
+ props.onEdit(path.value, checked)
158
+ }
159
+
160
+ // Selection (Field-state inspector hook). Canonical key uses JSON-
161
+ // serialised path-array form so two arrays with the same shape produce
162
+ // the same string — direct equality check.
163
+ const ownKey = computed(() => JSON.stringify(path.value))
164
+ const isSelected = computed(
165
+ () =>
166
+ props.selectedKey !== null &&
167
+ props.selectedKey !== undefined &&
168
+ props.selectedKey === ownKey.value
169
+ )
170
+
171
+ function selectThisPath(): void {
172
+ if (props.onSelectPath === undefined) return
173
+ props.onSelectPath(path.value)
93
174
  }
94
- if (next !== props.value) props.onEdit(path.value, next);
95
- editing.value = false;
96
- }
97
- function cancelEdit() {
98
- editing.value = false;
99
- editRejected.value = false;
100
- }
101
- function toggleBoolean(checked) {
102
- if (!isEditableLeaf.value || props.onEdit === void 0) return;
103
- props.onEdit(path.value, checked);
104
- }
105
- const ownKey = computed(() => JSON.stringify(path.value));
106
- const isSelected = computed(
107
- () => props.selectedKey !== null && props.selectedKey !== void 0 && props.selectedKey === ownKey.value
108
- );
109
- function selectThisPath() {
110
- if (props.onSelectPath === void 0) return;
111
- props.onSelectPath(path.value);
112
- }
113
175
  </script>
114
176
 
115
177
  <template>
116
- <div class="tree-node">
178
+ <div class="tree-node">
117
179
  <template v-if="isLeaf">
118
180
  <div class="row" :class="{ 'edit-rejected': editRejected, 'row-selected': isSelected }">
119
181
  <span
120
182
  v-if="label"
121
183
  class="key"
122
- :class="{ 'key-selectable': onSelectPath !== void 0, 'key-selected': isSelected }"
184
+ :class="{ 'key-selectable': onSelectPath !== undefined, 'key-selected': isSelected }"
123
185
  @click.stop="selectThisPath"
124
186
  >{{ label }}:</span
125
187
  >
@@ -139,8 +201,8 @@ function selectThisPath() {
139
201
  <label class="leaf-bool">
140
202
  <input
141
203
  type="checkbox"
142
- :checked="value"
143
- @change="toggleBoolean($event.target.checked)"
204
+ :checked="value as boolean"
205
+ @change="toggleBoolean(($event.target as HTMLInputElement).checked)"
144
206
  />
145
207
  <span class="leaf leaf-boolean">{{ formatted }}</span>
146
208
  </label>
@@ -149,7 +211,7 @@ function selectThisPath() {
149
211
  <span
150
212
  class="leaf"
151
213
  :class="[`leaf-${type}`, { 'leaf-editable': isEditableLeaf }]"
152
- :title="isEditableLeaf ? 'Click to edit' : void 0"
214
+ :title="isEditableLeaf ? 'Click to edit' : undefined"
153
215
  @click="isEditableLeaf ? startEdit() : null"
154
216
  >
155
217
  {{ formatted }}
@@ -163,7 +225,7 @@ function selectThisPath() {
163
225
  <span
164
226
  v-if="label"
165
227
  class="key"
166
- :class="{ 'key-selectable': onSelectPath !== void 0, 'key-selected': isSelected }"
228
+ :class="{ 'key-selectable': onSelectPath !== undefined, 'key-selected': isSelected }"
167
229
  @click.stop="selectThisPath"
168
230
  >{{ label }}:</span
169
231
  >
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const app = require('nuxt/app');
4
- const devtoolsShared = require('../../shared/attaform.Bq5sX7TF.cjs');
5
- const paths = require('../../shared/attaform.D32WwKk6.cjs');
4
+ const devtoolsShared = require('../../shared/attaform.BwLp9KM7.cjs');
5
+ const paths = require('../../shared/attaform.B5LNzqQh.cjs');
6
6
 
7
7
  var attaform_default = app.defineNuxtPlugin({
8
8
  // `enforce: 'pre'` makes the "we run before any component's setup" claim
@@ -1,6 +1,6 @@
1
1
  import { defineNuxtPlugin, useRuntimeConfig, useRoute } from 'nuxt/app';
2
- import { r as renderAttaformState, h as hydrateAttaformState, D as DEVTOOLS_WINDOW_KEY } from '../../shared/attaform.Y1ZGhM4k.mjs';
3
- import { m as createAttaform, y as kAttaformWizardActiveStepResolver, s as getRegistryFromApp } from '../../shared/attaform.pmtahXKy.mjs';
2
+ import { r as renderAttaformState, h as hydrateAttaformState, D as DEVTOOLS_WINDOW_KEY } from '../../shared/attaform.C41gjp-a.mjs';
3
+ import { c as createAttaform, k as kAttaformWizardActiveStepResolver, g as getRegistryFromApp } from '../../shared/attaform.DP-u7_tk.mjs';
4
4
 
5
5
  var attaform_default = defineNuxtPlugin({
6
6
  // `enforce: 'pre'` makes the "we run before any component's setup" claim