attaform 0.15.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -11
- package/dist/chunks/devtools.cjs +4 -4
- package/dist/chunks/devtools.cjs.map +1 -1
- package/dist/chunks/devtools.mjs +2 -2
- package/dist/chunks/indexeddb.cjs +4 -4
- package/dist/chunks/indexeddb.cjs.map +1 -1
- package/dist/chunks/indexeddb.mjs +1 -1
- package/dist/chunks/local-storage.cjs +2 -2
- package/dist/chunks/local-storage.cjs.map +1 -1
- package/dist/chunks/local-storage.mjs +1 -1
- package/dist/chunks/session-storage.cjs +2 -2
- package/dist/chunks/session-storage.cjs.map +1 -1
- package/dist/chunks/session-storage.mjs +1 -1
- package/dist/index.cjs +23 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -70
- package/dist/index.d.mts +75 -70
- package/dist/index.d.ts +75 -70
- package/dist/index.mjs +6 -6
- package/dist/nuxt.cjs +5 -11
- package/dist/nuxt.cjs.map +1 -1
- package/dist/nuxt.d.cts +8 -0
- package/dist/nuxt.d.mts +8 -0
- package/dist/nuxt.d.ts +8 -0
- package/dist/nuxt.mjs +6 -12
- package/dist/nuxt.mjs.map +1 -1
- package/dist/runtime/plugins/attaform.cjs +3 -2
- package/dist/runtime/plugins/attaform.cjs.map +1 -1
- package/dist/runtime/plugins/attaform.mjs +2 -1
- package/dist/runtime/plugins/attaform.mjs.map +1 -1
- package/dist/shared/{attaform.BwaYWtMs.d.cts → attaform.B7rzpK1U.d.cts} +34 -5
- package/dist/shared/{attaform.BwaYWtMs.d.mts → attaform.B7rzpK1U.d.mts} +34 -5
- package/dist/shared/{attaform.BwaYWtMs.d.ts → attaform.B7rzpK1U.d.ts} +34 -5
- package/dist/shared/attaform.BAuJTWuT.d.mts +84 -0
- package/dist/shared/{attaform.CRk8NhlD.mjs → attaform.BfMxsfmE.mjs} +428 -49
- package/dist/shared/attaform.BfMxsfmE.mjs.map +1 -0
- package/dist/shared/attaform.Bp1c-uGF.cjs +1561 -0
- package/dist/shared/attaform.Bp1c-uGF.cjs.map +1 -0
- package/dist/shared/{attaform.CDJVeoJU.cjs → attaform.C9Ph2SMx.cjs} +49 -42
- package/dist/shared/{attaform.qxyip_aN.mjs.map → attaform.C9Ph2SMx.cjs.map} +1 -1
- package/dist/shared/attaform.CINUMjPq.mjs +29 -0
- package/dist/shared/attaform.CINUMjPq.mjs.map +1 -0
- package/dist/shared/attaform.CJttVxRj.cjs +32 -0
- package/dist/shared/attaform.CJttVxRj.cjs.map +1 -0
- package/dist/shared/attaform.CvOXSpCb.mjs +1908 -0
- package/dist/shared/attaform.CvOXSpCb.mjs.map +1 -0
- package/dist/shared/{attaform.qxyip_aN.mjs → attaform.DILbdvfo.mjs} +12 -5
- package/dist/shared/{attaform.CDJVeoJU.cjs.map → attaform.DILbdvfo.mjs.map} +1 -1
- package/dist/shared/attaform.DdnithOf.mjs +1555 -0
- package/dist/shared/attaform.DdnithOf.mjs.map +1 -0
- package/dist/shared/attaform.DfrYByDj.cjs +1916 -0
- package/dist/shared/attaform.DfrYByDj.cjs.map +1 -0
- package/dist/shared/{attaform.BOi138GE.cjs → attaform.c_NzdRyc.cjs} +4 -4
- package/dist/shared/{attaform.BOi138GE.cjs.map → attaform.c_NzdRyc.cjs.map} +1 -1
- package/dist/shared/{attaform.DXye3JKf.mjs → attaform.jrxE_xZw.mjs} +2 -2
- package/dist/shared/{attaform.DXye3JKf.mjs.map → attaform.jrxE_xZw.mjs.map} +1 -1
- package/dist/shared/attaform.ls_7jBYc.d.ts +84 -0
- package/dist/shared/{attaform.BgYBU8gV.cjs → attaform.rIRYSUI1.cjs} +461 -61
- package/dist/shared/attaform.rIRYSUI1.cjs.map +1 -0
- package/dist/shared/attaform.xIcmqscx.d.cts +84 -0
- package/dist/vite.cjs +62 -9
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +23 -32
- package/dist/vite.d.mts +23 -32
- package/dist/vite.d.ts +23 -32
- package/dist/vite.mjs +62 -9
- package/dist/vite.mjs.map +1 -1
- package/dist/zod-v3.cjs +9 -1553
- package/dist/zod-v3.cjs.map +1 -1
- package/dist/zod-v3.mjs +3 -1553
- package/dist/zod-v3.mjs.map +1 -1
- package/dist/zod-v4.cjs +21 -0
- package/dist/zod-v4.cjs.map +1 -0
- package/dist/zod-v4.d.cts +104 -0
- package/dist/zod-v4.d.mts +104 -0
- package/dist/zod-v4.d.ts +104 -0
- package/dist/zod-v4.mjs +4 -0
- package/dist/zod-v4.mjs.map +1 -0
- package/dist/zod.cjs +19 -1900
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +27 -155
- package/dist/zod.d.mts +27 -155
- package/dist/zod.d.ts +27 -155
- package/dist/zod.mjs +19 -1896
- package/dist/zod.mjs.map +1 -1
- package/package.json +6 -2
- package/dist/shared/attaform.BgYBU8gV.cjs.map +0 -1
- package/dist/shared/attaform.CRk8NhlD.mjs.map +0 -1
- package/dist/shared/attaform.RypIkgVy.cjs +0 -417
- package/dist/shared/attaform.RypIkgVy.cjs.map +0 -1
- package/dist/shared/attaform.a99dQV7Q.mjs +0 -392
- package/dist/shared/attaform.a99dQV7Q.mjs.map +0 -1
|
@@ -1,5 +1,141 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { shallowReactive, getCurrentInstance, inject, shallowRef, onBeforeMount, onBeforeUpdate, onMounted, nextTick, warn, isRef } from 'vue';
|
|
2
|
+
|
|
3
|
+
const __DEV__ = typeof process !== "undefined" && process.env["NODE_ENV"] !== "production";
|
|
4
|
+
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
8
|
+
class AttaformError extends Error {
|
|
9
|
+
constructor(message, options) {
|
|
10
|
+
super(message, options);
|
|
11
|
+
this.name = new.target.name;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
class InvalidPathError extends AttaformError {
|
|
15
|
+
}
|
|
16
|
+
class InvalidUseFormConfigError extends AttaformError {
|
|
17
|
+
constructor() {
|
|
18
|
+
super(
|
|
19
|
+
"[attaform] useForm received an invalid configuration (a schema directly, no argument, or no `schema` field). Pass it as `useForm({ schema })` \u2014 the schema is one of several configuration options. See https://attaform.com/docs/api/use-form-return for the full configuration shape."
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
class SubmitErrorHandlerError extends AttaformError {
|
|
24
|
+
}
|
|
25
|
+
class RegistryNotInstalledError extends AttaformError {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(
|
|
28
|
+
"[attaform] No registry attached to this Vue app. Component-level useForm / injectForm / useRegister auto-install the registry, but SSR helpers (renderAttaformState, hydrateAttaformState) run outside setup and require an explicit `app.use(createAttaform())` at server-render time. Add it to your SSR entry, before `renderToString`."
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class OutsideSetupError extends AttaformError {
|
|
33
|
+
constructor() {
|
|
34
|
+
super(
|
|
35
|
+
"[attaform] useForm / injectForm called outside Vue setup(). Move into setup or mount a child component to trigger from an event."
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
class ReservedFormKeyError extends AttaformError {
|
|
40
|
+
constructor(key) {
|
|
41
|
+
super(
|
|
42
|
+
`[attaform] Form key "${key}" uses the reserved "__atta:" namespace. Use a different prefix \u2014 "__atta:" is for library-internal synthetic keys (anonymous useForm() calls without an explicit key).`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
class SensitivePersistFieldError extends AttaformError {
|
|
47
|
+
constructor(path) {
|
|
48
|
+
const display = Array.isArray(path) ? path.join(".") : String(path);
|
|
49
|
+
super(
|
|
50
|
+
`[attaform] Refusing to persist "${display}" \u2014 this path matches a sensitive-name pattern (password / cvv / ssn / token / etc.). Storing sensitive data in client-side storage is a compliance risk (HIPAA / PII / PCI-DSS / SOC2). Fix: persist this server-side, OR pass \`acknowledgeSensitive: true\` to register() (or form.persist()) if the client-side persistence is intentional.`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
class AnonPersistError extends AttaformError {
|
|
55
|
+
constructor(opts) {
|
|
56
|
+
super(formatAnonPersistMessage(opts));
|
|
57
|
+
__publicField(this, "schemaFields");
|
|
58
|
+
__publicField(this, "callSite");
|
|
59
|
+
__publicField(this, "cause");
|
|
60
|
+
this.schemaFields = opts.schemaFields;
|
|
61
|
+
this.callSite = opts.callSite;
|
|
62
|
+
this.cause = opts.cause;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function formatAnonPersistMessage(opts) {
|
|
66
|
+
const head = opts.cause === "no-key" ? `useForm({ persist: ... }) requires an explicit \`key:\`. Anonymous synthetic keys (\`__atta:anon:*\`) drift across mounts and can collide between unrelated forms \u2014 refusing to persist to a non-deterministic location.` : `register(_, { persist: true }) declared on a form whose useForm() options have no \`persist:\` configured. The opt-in is recorded but nothing would ever land in storage.`;
|
|
67
|
+
const fields = opts.schemaFields !== void 0 && opts.schemaFields.length > 0 ? ` Form fields: { ${opts.schemaFields.join(", ")} }.` : "";
|
|
68
|
+
const fix = opts.cause === "no-key" ? ` Fix: add \`key: '<stable-id>'\` to useForm().` : ` Fix: add \`persist: 'session'\` (or 'local') and \`key:\` to useForm(), or remove \`{ persist: true }\` from this register() call.`;
|
|
69
|
+
const where = opts.callSite !== void 0 ? ` ${opts.callSite}` : "";
|
|
70
|
+
return `[attaform] ${head}${fields}${fix}${where}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function detectSSR(options = {}) {
|
|
74
|
+
if (options.override !== void 0) return options.override;
|
|
75
|
+
return typeof window === "undefined" && typeof document === "undefined";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const kAttaformRegistry = Symbol.for("attaform:registry");
|
|
79
|
+
const kFormContext = Symbol.for("attaform:form-context");
|
|
80
|
+
const kFormInstanceId = Symbol.for("attaform:form-instance-id");
|
|
81
|
+
function createRegistry(options = {}) {
|
|
82
|
+
const ssr = detectSSR(options);
|
|
83
|
+
const defaults = Object.freeze({ ...options.defaults ?? {} });
|
|
84
|
+
const forms = shallowReactive(/* @__PURE__ */ new Map());
|
|
85
|
+
const pendingHydration = shallowReactive(/* @__PURE__ */ new Map());
|
|
86
|
+
const consumers = /* @__PURE__ */ new Map();
|
|
87
|
+
const evicting = /* @__PURE__ */ new Set();
|
|
88
|
+
function trackConsumer(key) {
|
|
89
|
+
consumers.set(key, (consumers.get(key) ?? 0) + 1);
|
|
90
|
+
let disposed = false;
|
|
91
|
+
return () => {
|
|
92
|
+
if (disposed) return;
|
|
93
|
+
disposed = true;
|
|
94
|
+
const remaining = (consumers.get(key) ?? 1) - 1;
|
|
95
|
+
if (remaining <= 0) {
|
|
96
|
+
const state = forms.get(key);
|
|
97
|
+
consumers.delete(key);
|
|
98
|
+
forms.delete(key);
|
|
99
|
+
if (state !== void 0) {
|
|
100
|
+
evicting.add(state);
|
|
101
|
+
void state.awaitPendingWrites().catch(() => void 0).finally(() => {
|
|
102
|
+
evicting.delete(state);
|
|
103
|
+
state.dispose();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
consumers.set(key, remaining);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
async function shutdown() {
|
|
112
|
+
const states = [...forms.values(), ...evicting];
|
|
113
|
+
await Promise.allSettled(states.map((state) => state.awaitPendingWrites()));
|
|
114
|
+
}
|
|
115
|
+
return { forms, pendingHydration, ssr, defaults, trackConsumer, shutdown };
|
|
116
|
+
}
|
|
117
|
+
function useRegistry() {
|
|
118
|
+
const instance = getCurrentInstance();
|
|
119
|
+
if (instance === null) {
|
|
120
|
+
throw new OutsideSetupError();
|
|
121
|
+
}
|
|
122
|
+
const registry = inject(kAttaformRegistry, null);
|
|
123
|
+
if (registry === null) {
|
|
124
|
+
throw new RegistryNotInstalledError();
|
|
125
|
+
}
|
|
126
|
+
return registry;
|
|
127
|
+
}
|
|
128
|
+
function getRegistryFromApp(app) {
|
|
129
|
+
const registry = app._attaform;
|
|
130
|
+
if (registry === void 0) {
|
|
131
|
+
throw new RegistryNotInstalledError();
|
|
132
|
+
}
|
|
133
|
+
return registry;
|
|
134
|
+
}
|
|
135
|
+
function attachRegistryToApp(app, registry) {
|
|
136
|
+
app.provide(kAttaformRegistry, registry);
|
|
137
|
+
app._attaform = registry;
|
|
138
|
+
}
|
|
3
139
|
|
|
4
140
|
const isArray = Array.isArray;
|
|
5
141
|
function isFunction(value) {
|
|
@@ -72,6 +208,267 @@ function invokeArrayFns(fns, ...args) {
|
|
|
72
208
|
}
|
|
73
209
|
}
|
|
74
210
|
|
|
211
|
+
function captureUserCallSite() {
|
|
212
|
+
const raw = new Error().stack;
|
|
213
|
+
if (typeof raw !== "string") return void 0;
|
|
214
|
+
const lines = raw.split("\n");
|
|
215
|
+
for (let i = 1; i < lines.length; i++) {
|
|
216
|
+
const frame = lines[i];
|
|
217
|
+
if (frame === void 0) continue;
|
|
218
|
+
if (/attaform[/-]forms?/i.test(frame)) continue;
|
|
219
|
+
if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
|
|
220
|
+
const trimmed = frame.trim();
|
|
221
|
+
if (trimmed.length === 0) continue;
|
|
222
|
+
return shortenSourceFrame(trimmed);
|
|
223
|
+
}
|
|
224
|
+
return void 0;
|
|
225
|
+
}
|
|
226
|
+
function shortenSourceFrame(frame) {
|
|
227
|
+
const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
|
|
228
|
+
if (match === null) return frame;
|
|
229
|
+
const [, urlOrPath, line] = match;
|
|
230
|
+
if (urlOrPath === void 0 || line === void 0) return frame;
|
|
231
|
+
let path = urlOrPath;
|
|
232
|
+
path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
|
|
233
|
+
path = path.replace(/^_nuxt\//, "");
|
|
234
|
+
path = path.replace(/^\//, "");
|
|
235
|
+
return `(${path}:${line})`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const REGISTER_OWNER_MARKER = Symbol.for("attaform:register-owner-marker");
|
|
239
|
+
const warnedNoParentRV = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
240
|
+
let warnedOutsideSetup = false;
|
|
241
|
+
function makeRegisterValueProxy(capturedRegisterValue) {
|
|
242
|
+
return new Proxy({}, {
|
|
243
|
+
get(_target, prop) {
|
|
244
|
+
if (prop === "__v_isRef") return true;
|
|
245
|
+
if (prop === "value") return capturedRegisterValue.value;
|
|
246
|
+
const v = capturedRegisterValue.value;
|
|
247
|
+
if (v === void 0) return void 0;
|
|
248
|
+
return Reflect.get(v, prop);
|
|
249
|
+
},
|
|
250
|
+
has(_target, prop) {
|
|
251
|
+
if (prop === "__v_isRef" || prop === "value") return true;
|
|
252
|
+
const v = capturedRegisterValue.value;
|
|
253
|
+
if (v === void 0) return false;
|
|
254
|
+
return Reflect.has(v, prop);
|
|
255
|
+
},
|
|
256
|
+
ownKeys(_target) {
|
|
257
|
+
const v = capturedRegisterValue.value;
|
|
258
|
+
if (v === void 0) return [];
|
|
259
|
+
return Reflect.ownKeys(v);
|
|
260
|
+
},
|
|
261
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
262
|
+
const v = capturedRegisterValue.value;
|
|
263
|
+
if (v === void 0) return void 0;
|
|
264
|
+
const desc = Reflect.getOwnPropertyDescriptor(v, prop);
|
|
265
|
+
if (desc !== void 0) {
|
|
266
|
+
desc.configurable = true;
|
|
267
|
+
}
|
|
268
|
+
return desc;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
function useRegister() {
|
|
273
|
+
const instance = getCurrentInstance();
|
|
274
|
+
if (instance === null) {
|
|
275
|
+
warnOutsideSetup();
|
|
276
|
+
return makeRegisterValueProxy(shallowRef(void 0));
|
|
277
|
+
}
|
|
278
|
+
ensureAttaformInstalled(instance.appContext.app);
|
|
279
|
+
const capturedRegisterValue = shallowRef(void 0);
|
|
280
|
+
const refreshAndStripBridgeAttrs = () => {
|
|
281
|
+
const rawAttrs = instance.attrs;
|
|
282
|
+
if ("registerValue" in rawAttrs) {
|
|
283
|
+
capturedRegisterValue.value = rawAttrs["registerValue"];
|
|
284
|
+
delete rawAttrs["registerValue"];
|
|
285
|
+
}
|
|
286
|
+
if ("value" in rawAttrs) delete rawAttrs["value"];
|
|
287
|
+
};
|
|
288
|
+
refreshAndStripBridgeAttrs();
|
|
289
|
+
onBeforeMount(refreshAndStripBridgeAttrs);
|
|
290
|
+
onBeforeUpdate(refreshAndStripBridgeAttrs);
|
|
291
|
+
onMounted(() => {
|
|
292
|
+
const el = instance.vnode.el;
|
|
293
|
+
if (el !== null && el !== void 0 && typeof el === "object") {
|
|
294
|
+
el[REGISTER_OWNER_MARKER] = true;
|
|
295
|
+
}
|
|
296
|
+
if (capturedRegisterValue.value === void 0) {
|
|
297
|
+
warnNoParentRV(instance);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
return makeRegisterValueProxy(capturedRegisterValue);
|
|
301
|
+
}
|
|
302
|
+
function warnOutsideSetup() {
|
|
303
|
+
if (!__DEV__) return;
|
|
304
|
+
if (warnedOutsideSetup) return;
|
|
305
|
+
warnedOutsideSetup = true;
|
|
306
|
+
const frame = captureUserCallSite();
|
|
307
|
+
console.warn(
|
|
308
|
+
`[attaform] useRegister() called outside a component setup; returning an unbound RegisterValue proxy. Fix: call it inside <script setup> or a setup() function \u2014 not from an event handler or async callback.` + (frame !== void 0 ? ` ${frame}` : "")
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
function warnNoParentRV(instance) {
|
|
312
|
+
if (!__DEV__ || warnedNoParentRV === null) return;
|
|
313
|
+
if (warnedNoParentRV.has(instance)) return;
|
|
314
|
+
warnedNoParentRV.add(instance);
|
|
315
|
+
const frame = captureUserCallSite();
|
|
316
|
+
console.warn(
|
|
317
|
+
`[attaform] useRegister: no parent registerValue prop; RegisterValue fields will read as undefined. Pass v-register on the parent: \`<YourComponent v-register="form.register('field')" />\`.` + (frame !== void 0 ? ` ${frame}` : "")
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const idGenerator = /* @__PURE__ */ (() => {
|
|
322
|
+
let counter = 0;
|
|
323
|
+
return () => `el-${++counter}`;
|
|
324
|
+
})();
|
|
325
|
+
const elementIds = /* @__PURE__ */ new WeakMap();
|
|
326
|
+
function getOrAssignElementId(el) {
|
|
327
|
+
let id = elementIds.get(el);
|
|
328
|
+
if (id === void 0) {
|
|
329
|
+
id = idGenerator();
|
|
330
|
+
elementIds.set(el, id);
|
|
331
|
+
}
|
|
332
|
+
return id;
|
|
333
|
+
}
|
|
334
|
+
function createPersistOptInRegistry() {
|
|
335
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
336
|
+
function add(elementId, path) {
|
|
337
|
+
const existing = byPath.get(path);
|
|
338
|
+
if (existing === void 0) {
|
|
339
|
+
byPath.set(path, /* @__PURE__ */ new Set([elementId]));
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
existing.add(elementId);
|
|
343
|
+
}
|
|
344
|
+
function remove(elementId, path) {
|
|
345
|
+
const existing = byPath.get(path);
|
|
346
|
+
if (existing === void 0) return;
|
|
347
|
+
existing.delete(elementId);
|
|
348
|
+
if (existing.size === 0) byPath.delete(path);
|
|
349
|
+
}
|
|
350
|
+
function removeAllFor(elementId) {
|
|
351
|
+
for (const [path, ids] of byPath) {
|
|
352
|
+
if (!ids.delete(elementId)) continue;
|
|
353
|
+
if (ids.size === 0) byPath.delete(path);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function hasOptIn(elementId, path) {
|
|
357
|
+
return byPath.get(path)?.has(elementId) ?? false;
|
|
358
|
+
}
|
|
359
|
+
function hasAnyOptInForPath(path) {
|
|
360
|
+
const ids = byPath.get(path);
|
|
361
|
+
return ids !== void 0 && ids.size > 0;
|
|
362
|
+
}
|
|
363
|
+
function optedInPaths() {
|
|
364
|
+
return byPath.keys();
|
|
365
|
+
}
|
|
366
|
+
function isEmpty() {
|
|
367
|
+
return byPath.size === 0;
|
|
368
|
+
}
|
|
369
|
+
function clear() {
|
|
370
|
+
byPath.clear();
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
add,
|
|
374
|
+
remove,
|
|
375
|
+
removeAllFor,
|
|
376
|
+
hasOptIn,
|
|
377
|
+
hasAnyOptInForPath,
|
|
378
|
+
optedInPaths,
|
|
379
|
+
isEmpty,
|
|
380
|
+
clear
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const SENSITIVE_NAME_PATTERNS = [
|
|
385
|
+
// Passwords and PIN-like
|
|
386
|
+
/password/i,
|
|
387
|
+
/passwd/i,
|
|
388
|
+
/passwords/i,
|
|
389
|
+
/\bpwd\b/i,
|
|
390
|
+
/\bpin\b/i,
|
|
391
|
+
// Card / payment
|
|
392
|
+
/\bcvv\b/i,
|
|
393
|
+
/\bcvc\b/i,
|
|
394
|
+
/card[_\s-]?(?:number|num)/i,
|
|
395
|
+
/\bcard\b/i,
|
|
396
|
+
/\biban\b/i,
|
|
397
|
+
/routing[_\s-]?number/i,
|
|
398
|
+
/account[_\s-]?number/i,
|
|
399
|
+
// Government / identity
|
|
400
|
+
/\bssn\b/i,
|
|
401
|
+
/social[_\s-]?security/i,
|
|
402
|
+
/\bdob\b/i,
|
|
403
|
+
/date[_\s-]?of[_\s-]?birth/i,
|
|
404
|
+
/passport/i,
|
|
405
|
+
/driver[_\s-]?license/i,
|
|
406
|
+
// Tax IDs (US + international common variants)
|
|
407
|
+
/\btin\b/i,
|
|
408
|
+
/\bein\b/i,
|
|
409
|
+
/\bitin\b/i,
|
|
410
|
+
/tax[_\s-]?id/i,
|
|
411
|
+
// Tokens, secrets, API/auth credentials
|
|
412
|
+
/\btoken\b/i,
|
|
413
|
+
/\btokens\b/i,
|
|
414
|
+
/secret/i,
|
|
415
|
+
/secrets/i,
|
|
416
|
+
/api[_\s-]?key/i,
|
|
417
|
+
/api[_\s-]?secret/i,
|
|
418
|
+
/api[_\s-]?token/i,
|
|
419
|
+
/private[_\s-]?key/i,
|
|
420
|
+
/\bbearer\b/i,
|
|
421
|
+
/\boauth\b/i,
|
|
422
|
+
/auth[_\s-]?token/i,
|
|
423
|
+
/access[_\s-]?token/i,
|
|
424
|
+
/refresh[_\s-]?token/i,
|
|
425
|
+
/session[_\s-]?(?:id|key|token)/i,
|
|
426
|
+
// MFA / OTP
|
|
427
|
+
/\botp\b/i,
|
|
428
|
+
/one[_\s-]?time[_\s-]?(?:password|code)/i,
|
|
429
|
+
/mfa[_\s-]?(?:secret|seed|code|token)/i,
|
|
430
|
+
/two[_\s-]?factor[_\s-]?(?:code|token)/i,
|
|
431
|
+
/\b2fa[_\s-]?(?:code|token)?\b/i,
|
|
432
|
+
/recovery[_\s-]?code/i,
|
|
433
|
+
/backup[_\s-]?code/i
|
|
434
|
+
];
|
|
435
|
+
function segmentMatchesSensitive(segment) {
|
|
436
|
+
if (typeof segment !== "string") return false;
|
|
437
|
+
for (const pattern of SENSITIVE_NAME_PATTERNS) {
|
|
438
|
+
if (pattern.test(segment)) return true;
|
|
439
|
+
}
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
function isSensitivePath(path) {
|
|
443
|
+
if (typeof path !== "string") {
|
|
444
|
+
for (const segment of path) {
|
|
445
|
+
if (segmentMatchesSensitive(segment)) return true;
|
|
446
|
+
}
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
if (path.startsWith("[")) {
|
|
450
|
+
try {
|
|
451
|
+
const parsed = JSON.parse(path);
|
|
452
|
+
if (Array.isArray(parsed)) {
|
|
453
|
+
for (const segment of parsed) {
|
|
454
|
+
if (segmentMatchesSensitive(segment)) return true;
|
|
455
|
+
}
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
} catch {
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
for (const segment of path.split(".")) {
|
|
462
|
+
if (segmentMatchesSensitive(segment)) return true;
|
|
463
|
+
}
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
function enforceSensitiveCheck(path, acknowledged) {
|
|
467
|
+
if (acknowledged) return;
|
|
468
|
+
if (!isSensitivePath(path)) return;
|
|
469
|
+
throw new SensitivePersistFieldError(path);
|
|
470
|
+
}
|
|
471
|
+
|
|
75
472
|
const assignKey = Symbol.for("attaform:assign-key");
|
|
76
473
|
const listenersKey = Symbol.for("attaform:directive-listeners");
|
|
77
474
|
function isRegisterValue(val) {
|
|
@@ -733,58 +1130,40 @@ function callModelHook(el, binding, vnode, prevVNode, hook) {
|
|
|
733
1130
|
}
|
|
734
1131
|
const vRegister = vRegisterDynamic;
|
|
735
1132
|
|
|
1133
|
+
function installAttaformOnApp(app, options, source) {
|
|
1134
|
+
if (app._attaform !== void 0) {
|
|
1135
|
+
if (__DEV__ && source === "explicit") {
|
|
1136
|
+
console.warn(
|
|
1137
|
+
"[attaform] createAttaform() install was called twice on the same app; the second call is a no-op. Likely cause: registering the plugin via both the Nuxt module AND a manual `app.use(...)`."
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
return app._attaform;
|
|
1141
|
+
}
|
|
1142
|
+
const registry = createRegistry(options);
|
|
1143
|
+
attachRegistryToApp(app, registry);
|
|
1144
|
+
app.directive("register", vRegister);
|
|
1145
|
+
if (options.devtools !== false && !registry.ssr) {
|
|
1146
|
+
void (async () => {
|
|
1147
|
+
try {
|
|
1148
|
+
const { setupAttaformDevtools } = await import('../chunks/devtools.mjs');
|
|
1149
|
+
await setupAttaformDevtools(app, registry);
|
|
1150
|
+
} catch {
|
|
1151
|
+
}
|
|
1152
|
+
})();
|
|
1153
|
+
}
|
|
1154
|
+
return registry;
|
|
1155
|
+
}
|
|
1156
|
+
function ensureAttaformInstalled(app) {
|
|
1157
|
+
return installAttaformOnApp(app, {}, "lazy");
|
|
1158
|
+
}
|
|
736
1159
|
function createAttaform(options = {}) {
|
|
737
1160
|
const plugin = {
|
|
738
1161
|
install(app) {
|
|
739
|
-
|
|
740
|
-
if (__DEV__) {
|
|
741
|
-
console.warn(
|
|
742
|
-
"[attaform] createAttaform() install was called twice on the same app; the second call is a no-op. Likely cause: registering the plugin via both the Nuxt module AND a manual `app.use(...)`."
|
|
743
|
-
);
|
|
744
|
-
}
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
const registry = createRegistry(options);
|
|
748
|
-
attachRegistryToApp(app, registry);
|
|
749
|
-
app.directive("register", vRegister);
|
|
750
|
-
if (options.devtools !== false && !registry.ssr) {
|
|
751
|
-
void (async () => {
|
|
752
|
-
try {
|
|
753
|
-
const { setupAttaformDevtools } = await import('../chunks/devtools.mjs');
|
|
754
|
-
await setupAttaformDevtools(app, registry);
|
|
755
|
-
} catch {
|
|
756
|
-
}
|
|
757
|
-
})();
|
|
758
|
-
}
|
|
1162
|
+
installAttaformOnApp(app, options, "explicit");
|
|
759
1163
|
}
|
|
760
1164
|
};
|
|
761
1165
|
return plugin;
|
|
762
1166
|
}
|
|
763
1167
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
const forms = [];
|
|
767
|
-
for (const [key, state] of registry.forms) {
|
|
768
|
-
const transientList = Array.from(state.blankPaths);
|
|
769
|
-
forms.push([
|
|
770
|
-
key,
|
|
771
|
-
{
|
|
772
|
-
form: state.form.value,
|
|
773
|
-
schemaErrors: Array.from(state.schemaErrors.entries()),
|
|
774
|
-
userErrors: Array.from(state.userErrors.entries()),
|
|
775
|
-
fields: Array.from(state.fields.entries()),
|
|
776
|
-
...transientList.length > 0 ? { blankPaths: transientList } : {}
|
|
777
|
-
}
|
|
778
|
-
]);
|
|
779
|
-
}
|
|
780
|
-
return { forms };
|
|
781
|
-
}
|
|
782
|
-
function hydrateAttaformState(app, payload) {
|
|
783
|
-
const registry = getRegistryFromApp(app);
|
|
784
|
-
for (const [key, data] of payload.forms) {
|
|
785
|
-
registry.pendingHydration.set(key, data);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
export { assignKey as a, createAttaform as c, hydrateAttaformState as h, isRegisterValue as i, renderAttaformState as r, vRegister as v };
|
|
790
|
-
//# sourceMappingURL=attaform.CRk8NhlD.mjs.map
|
|
1168
|
+
export { AnonPersistError as A, InvalidPathError as I, OutsideSetupError as O, RegistryNotInstalledError as R, SensitivePersistFieldError as S, __DEV__ as _, AttaformError as a, InvalidUseFormConfigError as b, createAttaform as c, ReservedFormKeyError as d, SubmitErrorHandlerError as e, assignKey as f, getRegistryFromApp as g, createRegistry as h, isSensitivePath as i, isRegisterValue as j, kAttaformRegistry as k, useRegistry as l, captureUserCallSite as m, enforceSensitiveCheck as n, createPersistOptInRegistry as o, ensureAttaformInstalled as p, kFormContext as q, kFormInstanceId as r, segmentMatchesSensitive as s, useRegister as u, vRegister as v };
|
|
1169
|
+
//# sourceMappingURL=attaform.BfMxsfmE.mjs.map
|