@teamnovu/kit-vue-forms 0.1.16 → 0.1.17

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.
@@ -11,7 +11,7 @@ declare const _default: <TData extends object, TPath extends EntityPaths<TData>>
11
11
  attrs: any;
12
12
  slots: {
13
13
  default?(_: {
14
- subform: Form< PickEntity<TData, TPath>>;
14
+ subform: Omit<Form< PickEntity<TData, TPath>>, "submitHandler">;
15
15
  }): any;
16
16
  };
17
17
  emit: {};
@@ -1,11 +1,11 @@
1
+ import { Awaitable } from '@vueuse/core';
1
2
  import { MaybeRef, ComputedRef } from 'vue';
2
3
  import { FieldsTuple, FormDataDefault, FormField } from '../types/form';
3
4
  import { Paths, PickProps } from '../types/util';
4
5
  import { UseFieldOptions } from './useField';
5
6
  import { ValidationState } from './useValidation';
6
- import { Awaitable } from '@vueuse/core';
7
7
  export type ResolvedFormField<T, K extends Paths<T>> = FormField<PickProps<T, K>, K>;
8
- export type DefineFieldOptions<F, K extends string> = Pick<UseFieldOptions<F, K>, 'path'> & {
8
+ export type DefineFieldOptions<F, K extends string> = Pick<UseFieldOptions<F, K>, "path"> & {
9
9
  onBlur?: () => void;
10
10
  onFocus?: () => void;
11
11
  };
@@ -2,4 +2,4 @@ import { Form, FormDataDefault } from '../types/form';
2
2
  import { EntityPaths, PickEntity } from '../types/util';
3
3
  export interface SubformOptions<_T extends FormDataDefault> {
4
4
  }
5
- export declare function createSubformInterface<T extends FormDataDefault, K extends EntityPaths<T>>(mainForm: Form<T>, path: K, _options?: SubformOptions<PickEntity<T, K>>): Form<PickEntity<T, K>>;
5
+ export declare function createSubformInterface<T extends FormDataDefault, K extends EntityPaths<T>>(mainForm: Form<T>, path: K, _options?: SubformOptions<PickEntity<T, K>>): Omit<Form<PickEntity<T, K>>, 'submitHandler'>;
package/dist/index.js CHANGED
@@ -1,28 +1,28 @@
1
1
  var H = Object.defineProperty;
2
2
  var Z = (t, e, r) => e in t ? H(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
3
  var S = (t, e, r) => Z(t, typeof e != "symbol" ? e + "" : e, r);
4
- import { toValue as q, toRaw as Q, computed as p, unref as d, isRef as U, shallowRef as B, reactive as $, watch as P, toRefs as J, shallowReactive as X, toRef as O, onScopeDispose as Y, watchEffect as ee, triggerRef as re, ref as L, getCurrentScope as te, onBeforeUnmount as ae, defineComponent as k, renderSlot as b, normalizeProps as M, guardReactiveProps as z, resolveComponent as se, createBlock as K, openBlock as T, withCtx as j, resolveDynamicComponent as ne, mergeProps as oe, createSlots as ie, renderList as le } from "vue";
5
- import { cloneDeep as ce } from "lodash-es";
4
+ import { toValue as q, toRaw as Q, computed as v, unref as d, isRef as U, shallowRef as j, reactive as _, watch as P, toRefs as T, shallowReactive as X, toRef as O, onScopeDispose as Y, triggerRef as ee, ref as J, getCurrentScope as re, onBeforeUnmount as te, defineComponent as k, renderSlot as b, normalizeProps as x, guardReactiveProps as M, resolveComponent as ae, createBlock as z, openBlock as K, withCtx as A, resolveDynamicComponent as se, mergeProps as ne, createSlots as ie, renderList as oe } from "vue";
5
+ import { cloneDeep as le } from "lodash-es";
6
6
  import "zod";
7
7
  function g(t) {
8
8
  const e = q(t), r = Q(e);
9
- return ce(r);
9
+ return le(r);
10
10
  }
11
- function W(t) {
11
+ function N(t) {
12
12
  return t === "" ? [] : t.split(/\s*\.\s*/).filter(Boolean);
13
13
  }
14
- function ue(t, e) {
15
- const r = Array.isArray(e) ? e : W(e);
14
+ function ce(t, e) {
15
+ const r = Array.isArray(e) ? e : N(e);
16
16
  return !!D(t, r.slice(0, -1));
17
17
  }
18
18
  function D(t, e) {
19
- return (Array.isArray(e) ? e : W(e)).reduce(
19
+ return (Array.isArray(e) ? e : N(e)).reduce(
20
20
  (a, s) => a == null ? void 0 : a[s],
21
21
  t
22
22
  );
23
23
  }
24
- function de(t, e, r) {
25
- const a = Array.isArray(e) ? e : W(e), s = a.at(-1);
24
+ function ue(t, e, r) {
25
+ const a = Array.isArray(e) ? e : N(e), s = a.at(-1);
26
26
  if (s) {
27
27
  const n = a.slice(0, -1).reduce(
28
28
  (f, m) => ((f == null ? void 0 : f[m]) === void 0 && (f[m] = {}), f == null ? void 0 : f[m]),
@@ -36,18 +36,18 @@ function de(t, e, r) {
36
36
  t.value = r;
37
37
  }
38
38
  }
39
- const x = (t, e) => p({
39
+ const L = (t, e) => v({
40
40
  get() {
41
41
  return D(d(t), d(e));
42
42
  },
43
43
  set(r) {
44
- de(t, d(e), r);
44
+ ue(t, d(e), r);
45
45
  }
46
46
  });
47
- function _(t, e) {
47
+ function $(t, e) {
48
48
  return !t && !e ? "" : !t && e ? e : !e && t ? t : `${t}.${e}`;
49
49
  }
50
- function fe(t, e) {
50
+ function de(t, e) {
51
51
  if (!e)
52
52
  return t;
53
53
  const r = `${e}.`, a = Object.fromEntries(
@@ -62,7 +62,7 @@ function fe(t, e) {
62
62
  propertyErrors: a
63
63
  };
64
64
  }
65
- class he {
65
+ class fe {
66
66
  constructor(e) {
67
67
  S(this, "rc", 1);
68
68
  this.drop = e;
@@ -74,13 +74,13 @@ class he {
74
74
  this.rc > 0 && (this.rc -= 1, this.rc === 0 && this.drop && this.drop());
75
75
  }
76
76
  }
77
- function pe(t) {
77
+ function he(t) {
78
78
  const r = {
79
79
  ...{
80
80
  existsInForm: !0
81
81
  },
82
82
  ...t
83
- }, a = B(Object.freeze(g(r.initialValue))), s = $({
83
+ }, a = j(Object.freeze(g(r.initialValue))), s = _({
84
84
  value: r.value,
85
85
  path: r.path,
86
86
  initialValue: a,
@@ -88,13 +88,13 @@ function pe(t) {
88
88
  touched: !1
89
89
  });
90
90
  P(
91
- B(r.initialValue),
91
+ j(r.initialValue),
92
92
  () => {
93
93
  a.value = Object.freeze(g(r.initialValue)), s.value = g(r.initialValue);
94
94
  },
95
95
  { flush: "sync" }
96
96
  );
97
- const n = p(() => JSON.stringify(s.value) !== JSON.stringify(s.initialValue)), f = (h) => {
97
+ const n = v(() => JSON.stringify(s.value) !== JSON.stringify(s.initialValue)), f = (h) => {
98
98
  s.value = h;
99
99
  }, m = () => {
100
100
  var h;
@@ -109,15 +109,15 @@ function pe(t) {
109
109
  n.value || f(g(h)), s.initialValue = h;
110
110
  }, c = (h) => {
111
111
  s.errors = h;
112
- }, i = () => {
112
+ }, o = () => {
113
113
  s.errors = [];
114
- }, o = J(s);
114
+ }, i = T(s);
115
115
  return {
116
- data: o.value,
117
- path: o.path,
118
- initialValue: o.initialValue,
119
- errors: o.errors,
120
- touched: o.touched,
116
+ data: i.value,
117
+ path: i.path,
118
+ initialValue: i.initialValue,
119
+ errors: i.errors,
120
+ touched: i.touched,
121
121
  dirty: n,
122
122
  setData: f,
123
123
  setInitialData: l,
@@ -125,95 +125,92 @@ function pe(t) {
125
125
  onFocus: y,
126
126
  reset: V,
127
127
  setErrors: c,
128
- clearErrors: i
128
+ clearErrors: o
129
129
  };
130
130
  }
131
131
  const ve = {
132
132
  keepValuesOnUnmount: !0
133
133
  };
134
- function me(t) {
135
- const e = B(t());
136
- return ee(
134
+ function pe(t, e) {
135
+ const r = () => D(t.initialData, e), a = j(r());
136
+ return P(
137
+ () => t.initialData,
137
138
  () => {
138
- e.value = t(), re(e);
139
+ a.value = r(), ee(a);
139
140
  },
140
141
  { flush: "sync" }
141
- ), e;
142
+ ), a;
142
143
  }
143
- function Ve(t, e, r) {
144
+ function me(t, e, r) {
144
145
  const a = /* @__PURE__ */ new Map(), s = X(/* @__PURE__ */ new Map()), n = {
145
146
  ...ve,
146
147
  ...r
147
- }, f = (i) => {
148
- const o = d(i.path);
149
- s.set(o, i);
150
- }, m = (i) => {
151
- var o;
152
- n != null && n.keepValuesOnUnmount || (o = s.get(i)) == null || o.reset(), s.delete(i);
153
- }, y = (i) => {
154
- var o;
155
- a.has(i) ? (o = a.get(i)) == null || o.inc() : a.set(i, new he(() => m(i)));
156
- }, V = (i) => {
157
- var o;
158
- a.has(i) && ((o = a.get(i)) == null || o.dec());
159
- }, l = (i) => {
160
- const { path: o } = i;
161
- if (!s.has(o)) {
162
- const N = pe({
163
- path: o,
164
- value: x(O(t, "data"), o),
165
- initialValue: me(() => D(t.initialData, o)),
166
- existsInForm: p(() => ue(t.data, d(o))),
167
- errors: p({
148
+ }, f = (o) => {
149
+ const i = d(o.path);
150
+ s.set(i, o);
151
+ }, m = (o) => {
152
+ var i;
153
+ n != null && n.keepValuesOnUnmount || (i = s.get(o)) == null || i.reset(), s.delete(o);
154
+ }, y = (o) => {
155
+ var i;
156
+ a.has(o) ? (i = a.get(o)) == null || i.inc() : a.set(o, new fe(() => m(o)));
157
+ }, V = (o) => {
158
+ var i;
159
+ a.has(o) && ((i = a.get(o)) == null || i.dec());
160
+ }, l = (o) => {
161
+ const { path: i } = o;
162
+ if (!s.has(i)) {
163
+ const W = he({
164
+ path: i,
165
+ value: L(O(t, "data"), i),
166
+ initialValue: pe(t, i),
167
+ existsInForm: v(() => ce(t.data, d(i))),
168
+ errors: v({
168
169
  get() {
169
- return e.errors.value.propertyErrors[o] || [];
170
+ return e.errors.value.propertyErrors[i] || [];
170
171
  },
171
172
  set(E) {
172
- e.errors.value.propertyErrors[o] = E;
173
+ e.errors.value.propertyErrors[i] = E;
173
174
  }
174
175
  }),
175
176
  onBlur: async () => {
176
177
  var E, R;
177
- await Promise.all(
178
- [
179
- (E = n == null ? void 0 : n.onBlur) == null ? void 0 : E.call(n, d(o)),
180
- (R = i.onBlur) == null ? void 0 : R.call(i)
181
- ]
182
- );
178
+ await Promise.all([
179
+ (E = n == null ? void 0 : n.onBlur) == null ? void 0 : E.call(n, d(i)),
180
+ (R = o.onBlur) == null ? void 0 : R.call(o)
181
+ ]);
183
182
  },
184
183
  onFocus: async () => {
185
184
  var E, R;
186
- await Promise.all(
187
- [
188
- (E = n == null ? void 0 : n.onFocus) == null ? void 0 : E.call(n, d(o)),
189
- (R = i.onFocus) == null ? void 0 : R.call(i)
190
- ]
191
- );
185
+ await Promise.all([
186
+ (E = n == null ? void 0 : n.onFocus) == null ? void 0 : E.call(n, d(i)),
187
+ (R = o.onFocus) == null ? void 0 : R.call(o)
188
+ ]);
192
189
  }
193
190
  });
194
- f(N);
191
+ f(W);
195
192
  }
196
- const h = s.get(o);
197
- return y(o), Y(() => {
198
- V(o);
193
+ const h = s.get(i);
194
+ return y(i), Y(() => {
195
+ V(i);
199
196
  }), h;
200
- }, c = (i) => l(i);
197
+ }, c = (o) => l(o);
201
198
  return {
202
- fields: p(() => [...s.values()]),
203
- getField: (i) => l({ path: i }),
199
+ fields: v(() => [...s.values()]),
200
+ getField: (o) => l({ path: o }),
204
201
  registerField: f,
205
202
  deregisterField: m,
206
203
  defineField: c
207
204
  };
208
205
  }
209
- function ye(t) {
210
- const e = p(() => t.fields.value.some((a) => d(a.dirty))), r = p(() => t.fields.value.some((a) => d(a.touched)));
206
+ function Ve(t) {
207
+ const e = v(() => t.fields.value.some((a) => d(a.dirty))), r = v(() => t.fields.value.some((a) => d(a.touched)));
211
208
  return {
212
209
  isDirty: e,
213
210
  isTouched: r
214
211
  };
215
212
  }
216
- function Fe(t) {
213
+ function ye(t) {
217
214
  return t.filter(
218
215
  (e, r, a) => a.indexOf(e) === r
219
216
  );
@@ -228,10 +225,10 @@ function G(...t) {
228
225
  if (!a)
229
226
  return e;
230
227
  const s = (e ?? []).concat(r);
231
- return Fe(s);
228
+ return ye(s);
232
229
  }, t[0]);
233
230
  }
234
- function ge(...t) {
231
+ function Fe(...t) {
235
232
  return t.map((r) => Object.keys(r)).flat().reduce((r, a) => {
236
233
  const s = t.map((n) => n[a]).filter(Boolean);
237
234
  return {
@@ -250,17 +247,17 @@ function C(...t) {
250
247
  return t.length === 1 ? e : t.slice(1).reduce(
251
248
  (r, a) => ({
252
249
  general: G(r.general, a.general),
253
- propertyErrors: ge(r.propertyErrors ?? {}, a.propertyErrors ?? {})
250
+ propertyErrors: Fe(r.propertyErrors ?? {}, a.propertyErrors ?? {})
254
251
  }),
255
252
  e
256
253
  );
257
254
  }
258
- function A(t) {
255
+ function B(t) {
259
256
  var a;
260
257
  const e = (((a = t.general) == null ? void 0 : a.length) ?? 0) > 0, r = Object.entries(t.propertyErrors).filter(([, s]) => s == null ? void 0 : s.length).length > 0;
261
258
  return e || r;
262
259
  }
263
- function Ee(t) {
260
+ function ge(t) {
264
261
  const e = t.issues.filter((a) => a.path.length === 0).map((a) => a.message), r = t.issues.filter((a) => a.path.length > 0).reduce((a, s) => {
265
262
  const n = s.path.join(".");
266
263
  return {
@@ -280,7 +277,7 @@ const F = {
280
277
  propertyErrors: {}
281
278
  }
282
279
  };
283
- class we {
280
+ class Ee {
284
281
  constructor(e) {
285
282
  this.schema = e;
286
283
  }
@@ -290,7 +287,7 @@ class we {
290
287
  const r = await this.schema.safeParseAsync(e);
291
288
  if (r.success)
292
289
  return F;
293
- const a = Ee(r.error);
290
+ const a = ge(r.error);
294
291
  return {
295
292
  isValid: !1,
296
293
  errors: {
@@ -300,7 +297,7 @@ class we {
300
297
  };
301
298
  }
302
299
  }
303
- class Re {
300
+ class we {
304
301
  constructor(e) {
305
302
  this.validateFn = e;
306
303
  }
@@ -321,11 +318,11 @@ class Re {
321
318
  }
322
319
  }
323
320
  }
324
- class Pe {
321
+ class Re {
325
322
  constructor(e, r) {
326
323
  S(this, "schemaValidator");
327
324
  S(this, "functionValidator");
328
- this.schema = e, this.validateFn = r, this.schemaValidator = new we(this.schema), this.functionValidator = new Re(this.validateFn);
325
+ this.schema = e, this.validateFn = r, this.schemaValidator = new Ee(this.schema), this.functionValidator = new we(this.validateFn);
329
326
  }
330
327
  async validate(e) {
331
328
  const [r, a] = await Promise.all([
@@ -339,14 +336,14 @@ class Pe {
339
336
  }
340
337
  }
341
338
  function I(t) {
342
- return p(() => new Pe(
339
+ return v(() => new Re(
343
340
  d(t.schema),
344
341
  d(t.validateFn)
345
342
  ));
346
343
  }
347
- function De(t, e) {
348
- const r = $({
349
- validators: L([I(e)]),
344
+ function Pe(t, e) {
345
+ const r = _({
346
+ validators: J([I(e)]),
350
347
  isValidated: !1,
351
348
  errors: d(e.errors) ?? F.errors
352
349
  }), a = (l = F.errors) => {
@@ -374,30 +371,30 @@ function De(t, e) {
374
371
  });
375
372
  const s = (l) => {
376
373
  const c = U(l) ? l : I(l);
377
- return r.validators.push(c), te() && ae(() => {
374
+ return r.validators.push(c), re() && te(() => {
378
375
  r.validators = r.validators.filter(
379
- (i) => i !== c
376
+ (o) => o !== c
380
377
  );
381
378
  }), c;
382
379
  };
383
380
  async function n() {
384
381
  const l = await Promise.all(
385
- r.validators.filter((o) => d(o) !== void 0).map((o) => d(o).validate(t.data))
386
- ), c = l.every((o) => o.isValid);
387
- let { errors: i } = F;
382
+ r.validators.filter((i) => d(i) !== void 0).map((i) => d(i).validate(t.data))
383
+ ), c = l.every((i) => i.isValid);
384
+ let { errors: o } = F;
388
385
  if (!c) {
389
- const o = l.map((h) => h.errors);
390
- i = C(...o);
386
+ const i = l.map((h) => h.errors);
387
+ o = C(...i);
391
388
  }
392
389
  return {
393
- errors: i,
390
+ errors: o,
394
391
  isValid: c
395
392
  };
396
393
  }
397
394
  const f = async () => {
398
395
  const l = await n();
399
396
  return a(l.errors), r.isValidated = !0, {
400
- isValid: !A(l.errors),
397
+ isValid: !B(l.errors),
401
398
  errors: r.errors
402
399
  };
403
400
  }, m = async (l) => {
@@ -408,14 +405,14 @@ function De(t, e) {
408
405
  [l]: c.errors.propertyErrors[l]
409
406
  }
410
407
  }), {
411
- isValid: !A(c.errors),
408
+ isValid: !B(c.errors),
412
409
  errors: r.errors
413
410
  };
414
- }, y = p(() => !A(r.errors)), V = () => {
411
+ }, y = v(() => !B(r.errors)), V = () => {
415
412
  r.isValidated = !1, r.errors = d(e.errors) ?? F.errors;
416
413
  };
417
414
  return {
418
- ...J(r),
415
+ ...T(r),
419
416
  validateForm: f,
420
417
  validateField: m,
421
418
  defineValidator: s,
@@ -423,7 +420,7 @@ function De(t, e) {
423
420
  reset: V
424
421
  };
425
422
  }
426
- class Se {
423
+ class De {
427
424
  constructor(e, r) {
428
425
  this.path = e, this.validator = r;
429
426
  }
@@ -438,7 +435,7 @@ class Se {
438
435
  general: a.errors.general || [],
439
436
  propertyErrors: a.errors.propertyErrors ? Object.fromEntries(
440
437
  Object.entries(a.errors.propertyErrors).map(([s, n]) => [
441
- _(this.path, s),
438
+ $(this.path, s),
442
439
  n
443
440
  ])
444
441
  ) : {}
@@ -446,29 +443,29 @@ class Se {
446
443
  };
447
444
  }
448
445
  }
449
- function _e(t, e, r) {
450
- const a = x(t.data, e), s = p(() => D(t.initialData.value, e)), n = (u) => ({
446
+ function Se(t, e, r) {
447
+ const a = L(t.data, e), s = v(() => D(t.initialData.value, e)), n = (u) => ({
451
448
  ...u,
452
- path: p(() => d(u.path).replace(e + ".", "")),
453
- setData: (v) => {
454
- u.setData(v);
449
+ path: v(() => d(u.path).replace(e + ".", "")),
450
+ setData: (p) => {
451
+ u.setData(p);
455
452
  }
456
453
  }), f = (u) => {
457
- const v = _(e, u), w = t.getField(v);
454
+ const p = $(e, u), w = t.getField(p);
458
455
  return w ? n(w) : {};
459
456
  }, m = (u) => {
460
- const v = _(e, u.path), w = t.defineField({
457
+ const p = $(e, u.path), w = t.defineField({
461
458
  ...u,
462
- path: v
459
+ path: p
463
460
  });
464
461
  return n(w);
465
- }, y = p(() => t.fields.value.filter((u) => {
466
- const v = u.path.value;
467
- return v.startsWith(e + ".") || v === e;
462
+ }, y = v(() => t.fields.value.filter((u) => {
463
+ const p = u.path.value;
464
+ return p.startsWith(e + ".") || p === e;
468
465
  }).map((u) => n(u))), V = () => t.fields.value.filter((u) => {
469
- const v = u.path.value;
470
- return v.startsWith(e + ".") || v === e;
471
- }), l = p(() => V().some((u) => u.dirty.value)), c = p(() => V().some((u) => u.touched.value)), i = p(() => t.isValid.value), o = p(() => t.isValidated.value), h = p(() => fe(d(t.errors), e));
466
+ const p = u.path.value;
467
+ return p.startsWith(e + ".") || p === e;
468
+ }), l = v(() => V().some((u) => u.dirty.value)), c = v(() => V().some((u) => u.touched.value)), o = v(() => t.isValid.value), i = v(() => t.isValidated.value), h = v(() => de(d(t.errors), e));
472
469
  return {
473
470
  data: a,
474
471
  fields: y,
@@ -477,30 +474,28 @@ function _e(t, e, r) {
477
474
  getField: f,
478
475
  isDirty: l,
479
476
  isTouched: c,
480
- isValid: i,
481
- isValidated: o,
477
+ isValid: o,
478
+ isValidated: i,
482
479
  errors: h,
483
480
  defineValidator: (u) => {
484
- const v = U(u) ? u : I(u), w = p(
485
- () => new Se(e, d(v))
481
+ const p = U(u) ? u : I(u), w = v(
482
+ () => new De(e, d(p))
486
483
  );
487
- return t.defineValidator(w), v;
484
+ return t.defineValidator(w), p;
488
485
  },
489
486
  reset: () => V().forEach((u) => u.reset()),
490
487
  validateForm: () => t.validateForm(),
491
- getSubForm: (u, v) => {
492
- const w = _(e, u);
488
+ getSubForm: (u, p) => {
489
+ const w = $(e, u);
493
490
  return t.getSubForm(
494
491
  w,
495
- v
492
+ p
496
493
  );
497
494
  }
498
495
  };
499
496
  }
500
- function Oe(t) {
501
- const e = p(
502
- () => Object.freeze(g(t.initialData))
503
- ), r = L(g(e)), a = $({
497
+ function je(t) {
498
+ const e = v(() => g(t.initialData)), r = J(g(e)), a = _({
504
499
  initialData: e,
505
500
  data: r
506
501
  });
@@ -511,20 +506,20 @@ function Oe(t) {
511
506
  },
512
507
  { flush: "sync" }
513
508
  );
514
- const s = De(a, t), n = Ve(a, s, {
509
+ const s = Pe(a, t), n = me(a, s, {
515
510
  keepValuesOnUnmount: t.keepValuesOnUnmount,
516
511
  onBlur: async (c) => {
517
512
  d(t.validationStrategy) === "onTouch" && s.validateField(c);
518
513
  }
519
- }), f = ye(n), m = (c) => async (i) => {
520
- i.preventDefault(), d(t.validationStrategy) !== "none" && await s.validateForm(), s.isValid.value && await c(a.data);
514
+ }), f = Ve(n), m = (c) => async (o) => {
515
+ o.preventDefault(), d(t.validationStrategy) !== "none" && await s.validateForm(), s.isValid.value && await c(a.data);
521
516
  }, y = () => {
522
517
  r.value = g(e), s.reset();
523
518
  for (const c of n.fields.value)
524
519
  c.reset();
525
520
  };
526
- function V(c, i) {
527
- return _e(l, c);
521
+ function V(c, o) {
522
+ return Se(l, c);
528
523
  }
529
524
  const l = {
530
525
  ...n,
@@ -538,7 +533,7 @@ function Oe(t) {
538
533
  };
539
534
  return d(t.validationStrategy) === "onFormOpen" && s.validateForm(), l;
540
535
  }
541
- const Ce = /* @__PURE__ */ k({
536
+ const Oe = /* @__PURE__ */ k({
542
537
  __name: "Field",
543
538
  props: {
544
539
  form: {},
@@ -553,10 +548,10 @@ const Ce = /* @__PURE__ */ k({
553
548
  setup(t) {
554
549
  const e = t, r = e.form.defineField({
555
550
  path: e.path
556
- }), a = $(r);
557
- return (s, n) => b(s.$slots, "default", M(z(a)));
551
+ }), a = _(r);
552
+ return (s, n) => b(s.$slots, "default", x(M(a)));
558
553
  }
559
- }), Ie = /* @__PURE__ */ k({
554
+ }), Ce = /* @__PURE__ */ k({
560
555
  inheritAttrs: !1,
561
556
  __name: "FormFieldWrapper",
562
557
  props: {
@@ -567,27 +562,27 @@ const Ce = /* @__PURE__ */ k({
567
562
  },
568
563
  setup(t) {
569
564
  return (e, r) => {
570
- const a = se("Field");
571
- return T(), K(a, {
572
- form: e.form,
573
- path: e.path
565
+ const a = ae("Field");
566
+ return K(), z(a, {
567
+ form: t.form,
568
+ path: t.path
574
569
  }, {
575
- default: j(({ errors: s, data: n, setData: f }) => [
576
- (T(), K(ne(e.component), oe({ ...e.componentProps, ...e.$attrs }, {
570
+ default: A(({ errors: s, data: n, setData: f }) => [
571
+ (K(), z(se(t.component), ne({ ...t.componentProps, ...e.$attrs }, {
577
572
  "model-value": n,
578
573
  errors: s,
579
- name: e.path,
574
+ name: t.path,
580
575
  "onUpdate:modelValue": f
581
576
  }), ie({
582
- default: j(() => [
577
+ default: A(() => [
583
578
  b(e.$slots, "default")
584
579
  ]),
585
580
  _: 2
586
581
  }, [
587
- le(e.$slots, (m, y) => ({
582
+ oe(e.$slots, (m, y) => ({
588
583
  name: y,
589
- fn: j((V) => [
590
- b(e.$slots, y, M(z(V ?? {})))
584
+ fn: A((V) => [
585
+ b(e.$slots, y, x(M(V ?? {})))
591
586
  ])
592
587
  }))
593
588
  ]), 1040, ["model-value", "errors", "name", "onUpdate:modelValue"]))
@@ -596,20 +591,20 @@ const Ce = /* @__PURE__ */ k({
596
591
  }, 8, ["form", "path"]);
597
592
  };
598
593
  }
599
- }), Ue = /* @__PURE__ */ k({
594
+ }), Ie = /* @__PURE__ */ k({
600
595
  __name: "FormPart",
601
596
  props: {
602
597
  form: {},
603
598
  path: {}
604
599
  },
605
600
  setup(t) {
606
- const e = t, r = p(() => e.form.getSubForm(e.path));
607
- return (a, s) => b(a.$slots, "default", M(z({ subform: r.value })));
601
+ const e = t, r = v(() => e.form.getSubForm(e.path));
602
+ return (a, s) => b(a.$slots, "default", x(M({ subform: r.value })));
608
603
  }
609
604
  });
610
605
  export {
611
- Ce as Field,
612
- Ie as FormFieldWrapper,
613
- Ue as FormPart,
614
- Oe as useForm
606
+ Oe as Field,
607
+ Ce as FormFieldWrapper,
608
+ Ie as FormPart,
609
+ je as useForm
615
610
  };
@@ -44,5 +44,5 @@ export interface Form<T extends FormDataDefault> {
44
44
  reset: () => void;
45
45
  validateForm: () => Promise<ValidationResult>;
46
46
  submitHandler: (onSubmit: (data: T) => Awaitable<void>) => (event: SubmitEvent) => Promise<void>;
47
- getSubForm: <P extends EntityPaths<T>>(path: P, options?: SubformOptions<PickEntity<T, P>>) => Form<PickEntity<T, P>>;
47
+ getSubForm: <P extends EntityPaths<T>>(path: P, options?: SubformOptions<PickEntity<T, P>>) => Omit<Form<PickEntity<T, P>>, 'submitHandler'>;
48
48
  }
@@ -8,7 +8,7 @@ export declare function existsFieldPath<T, K extends Paths<T>>(field: FormField<
8
8
  export declare function getNestedValue<T, K extends Paths<T>>(obj: T, path: K | SplitPath<K>): PickProps<T, K>;
9
9
  export declare function setNestedValue<T, K extends Paths<T>>(obj: MaybeRef<T>, path: K | SplitPath<K>, value: PickProps<T, K>): void;
10
10
  export declare const getLens: <T, K extends Paths<T>>(data: MaybeRef<T>, key: MaybeRef<K | SplitPath<K>>) => WritableComputedRef<PickProps<T, K>, PickProps<T, K>>;
11
- type JoinPath<Base extends string, Sub extends string> = `${Base}${Base extends "" ? "" : Sub extends "" ? "" : "."}${Sub}`;
11
+ type JoinPath<Base extends string, Sub extends string> = `${Base}${Base extends '' ? '' : Sub extends '' ? '' : '.'}${Sub}`;
12
12
  export declare function joinPath<Base extends string, Sub extends string>(basePath: Base, subPath: Sub): JoinPath<Base, Sub>;
13
13
  export declare function filterErrorsForPath(errors: ErrorBag, path: string): ErrorBag;
14
14
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamnovu/kit-vue-forms",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "@vitest/ui": "^2.0.0",
27
27
  "happy-dom": "^12.0.0",
28
28
  "vitest": "^2.0.0",
29
- "vue": "^3.5.13"
29
+ "vue": "^3.5.25"
30
30
  },
31
31
  "dependencies": {
32
32
  "@vueuse/core": "^13.5.0",
@@ -1,3 +1,4 @@
1
+ import type { Awaitable } from "@vueuse/core";
1
2
  import {
2
3
  computed,
3
4
  onScopeDispose,
@@ -6,65 +7,69 @@ import {
6
7
  toRef,
7
8
  triggerRef,
8
9
  unref,
9
- watchEffect,
10
+ watch,
10
11
  type MaybeRef,
11
- } from 'vue'
12
- import type { FieldsTuple, FormDataDefault, FormField } from '../types/form'
13
- import type { Paths, PickProps } from '../types/util'
14
- import { existsPath, getLens, getNestedValue } from '../utils/path'
15
- import { Rc } from '../utils/rc'
16
- import { useField, type UseFieldOptions } from './useField'
17
- import type { ValidationState } from './useValidation'
18
- import type { Awaitable } from '@vueuse/core'
12
+ } from "vue";
13
+ import type { FieldsTuple, FormDataDefault, FormField } from "../types/form";
14
+ import type { Paths, PickProps } from "../types/util";
15
+ import { existsPath, getLens, getNestedValue } from "../utils/path";
16
+ import { Rc } from "../utils/rc";
17
+ import { useField, type UseFieldOptions } from "./useField";
18
+ import type { ValidationState } from "./useValidation";
19
19
 
20
20
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- type FieldRegistryCache<T> = Map<Paths<T>, FormField<any, string>>
21
+ type FieldRegistryCache<T> = Map<Paths<T>, FormField<any, string>>;
22
22
 
23
23
  export type ResolvedFormField<T, K extends Paths<T>> = FormField<
24
24
  PickProps<T, K>,
25
25
  K
26
- >
26
+ >;
27
27
 
28
28
  export type DefineFieldOptions<F, K extends string> = Pick<
29
29
  UseFieldOptions<F, K>,
30
- 'path'
30
+ "path"
31
31
  > & {
32
- onBlur?: () => void
33
- onFocus?: () => void
34
- }
32
+ onBlur?: () => void;
33
+ onFocus?: () => void;
34
+ };
35
35
 
36
36
  interface FormState<
37
37
  T extends FormDataDefault,
38
38
  TIn extends FormDataDefault = T,
39
39
  > {
40
- data: T
41
- initialData: TIn
40
+ data: T;
41
+ initialData: TIn;
42
42
  }
43
43
 
44
44
  interface FieldRegistryOptions {
45
- keepValuesOnUnmount?: MaybeRef<boolean>
46
- onBlur?: (path: string) => Awaitable<void>
47
- onFocus?: (path: string) => Awaitable<void>
45
+ keepValuesOnUnmount?: MaybeRef<boolean>;
46
+ onBlur?: (path: string) => Awaitable<void>;
47
+ onFocus?: (path: string) => Awaitable<void>;
48
48
  }
49
49
 
50
50
  const optionDefaults = {
51
51
  keepValuesOnUnmount: true,
52
- }
52
+ };
53
53
 
54
54
  // A computed that always reflects the latest value from the getter
55
55
  // This computed forces updates even if the value is the same (to trigger watchers)
56
- function alwaysComputed<T>(getter: () => T) {
57
- const initialValueRef = shallowRef(getter())
56
+ function initialDataSync<T extends FormDataDefault>(
57
+ formState: FormState<T>,
58
+ path: Paths<T>,
59
+ ) {
60
+ const getNewValue = () => getNestedValue(formState.initialData, path);
61
+ const initialValueRef = shallowRef(getNewValue());
58
62
 
59
- watchEffect(
63
+ watch(
64
+ () => formState.initialData,
60
65
  () => {
61
- initialValueRef.value = getter()
62
- triggerRef(initialValueRef)
66
+ initialValueRef.value = getNewValue();
67
+ triggerRef(initialValueRef);
63
68
  },
64
- { flush: 'sync' },
65
- )
69
+ { flush: "sync" },
70
+ );
66
71
 
67
- return initialValueRef
72
+ return initialValueRef;
68
73
  }
69
74
 
70
75
  export function useFieldRegistry<T extends FormDataDefault>(
@@ -72,104 +77,99 @@ export function useFieldRegistry<T extends FormDataDefault>(
72
77
  validationState: ValidationState<T>,
73
78
  fieldRegistryOptions?: FieldRegistryOptions,
74
79
  ) {
75
- const fieldReferenceCounter = new Map<Paths<T>, Rc>()
76
- const fields = shallowReactive(new Map()) as FieldRegistryCache<T>
80
+ const fieldReferenceCounter = new Map<Paths<T>, Rc>();
81
+ const fields = shallowReactive(new Map()) as FieldRegistryCache<T>;
77
82
  const registryOptions = {
78
83
  ...optionDefaults,
79
84
  ...fieldRegistryOptions,
80
- }
85
+ };
81
86
 
82
87
  const registerField = <K extends Paths<T>>(
83
88
  field: ResolvedFormField<T, K>,
84
89
  ) => {
85
- const path = unref(field.path) as Paths<T>
86
- fields.set(path, field)
87
- }
90
+ const path = unref(field.path) as Paths<T>;
91
+ fields.set(path, field);
92
+ };
88
93
 
89
94
  const deregisterField = (path: Paths<T>) => {
90
95
  if (!registryOptions?.keepValuesOnUnmount) {
91
- fields.get(path)?.reset()
96
+ fields.get(path)?.reset();
92
97
  }
93
- fields.delete(path)
94
- }
98
+ fields.delete(path);
99
+ };
95
100
 
96
101
  const track = (path: Paths<T>) => {
97
102
  if (!fieldReferenceCounter.has(path)) {
98
- fieldReferenceCounter.set(path, new Rc(() => deregisterField(path)))
103
+ fieldReferenceCounter.set(path, new Rc(() => deregisterField(path)));
99
104
  } else {
100
- fieldReferenceCounter.get(path)?.inc()
105
+ fieldReferenceCounter.get(path)?.inc();
101
106
  }
102
- }
107
+ };
103
108
 
104
109
  const untrack = (path: Paths<T>) => {
105
110
  if (fieldReferenceCounter.has(path)) {
106
- fieldReferenceCounter.get(path)?.dec()
111
+ fieldReferenceCounter.get(path)?.dec();
107
112
  }
108
- }
113
+ };
109
114
 
110
115
  const getField = <K extends Paths<T>>(
111
116
  options: DefineFieldOptions<PickProps<T, K>, K>,
112
117
  ): ResolvedFormField<T, K> => {
113
- const { path } = options
118
+ const { path } = options;
114
119
 
115
120
  if (!fields.has(path)) {
116
121
  const field = useField({
117
122
  path,
118
- value: getLens(toRef(formState, 'data'), path),
119
- initialValue: alwaysComputed(() =>
120
- getNestedValue(formState.initialData, path)),
123
+ value: getLens(toRef(formState, "data"), path),
124
+ initialValue: initialDataSync(formState, path),
121
125
  existsInForm: computed(() => existsPath(formState.data, unref(path))),
122
126
  errors: computed({
123
127
  get() {
124
- return validationState.errors.value.propertyErrors[path] || []
128
+ return validationState.errors.value.propertyErrors[path] || [];
125
129
  },
126
130
  set(newErrors) {
127
- validationState.errors.value.propertyErrors[path] = newErrors
131
+ validationState.errors.value.propertyErrors[path] = newErrors;
128
132
  },
129
133
  }),
130
134
  onBlur: async () => {
131
- await Promise.all(
132
- [
133
- registryOptions?.onBlur?.(unref(path)),
134
- options.onBlur?.(),
135
- ],
136
- )
135
+ await Promise.all([
136
+ registryOptions?.onBlur?.(unref(path)),
137
+ options.onBlur?.(),
138
+ ]);
137
139
  },
138
140
  onFocus: async () => {
139
- await Promise.all(
140
- [
141
- registryOptions?.onFocus?.(unref(path)),
142
- options.onFocus?.(),
143
- ],
144
- )
141
+ await Promise.all([
142
+ registryOptions?.onFocus?.(unref(path)),
143
+ options.onFocus?.(),
144
+ ]);
145
145
  },
146
- })
146
+ });
147
147
 
148
- registerField(field)
148
+ registerField(field);
149
149
  }
150
150
 
151
- const field = fields.get(path) as ResolvedFormField<T, K>
151
+ const field = fields.get(path) as ResolvedFormField<T, K>;
152
152
 
153
- track(path)
153
+ track(path);
154
154
 
155
155
  // Clean up field on unmount
156
156
  onScopeDispose(() => {
157
- untrack(path)
158
- })
157
+ untrack(path);
158
+ });
159
159
 
160
- return field
161
- }
160
+ return field;
161
+ };
162
162
 
163
163
  const defineField = <K extends Paths<T>>(
164
164
  options: DefineFieldOptions<PickProps<T, K>, K>,
165
165
  ): ResolvedFormField<T, K> => {
166
- const field = getField(options)
166
+ const field = getField(options);
167
167
 
168
168
  // TODO: If more options are ever needed than only the path we have to update the field
169
169
  // here with the new options
170
170
 
171
- return field
172
- }
171
+ return field;
172
+ };
173
173
 
174
174
  return {
175
175
  fields: computed(() => [...fields.values()] as FieldsTuple<T>),
@@ -177,9 +177,9 @@ export function useFieldRegistry<T extends FormDataDefault>(
177
177
  registerField,
178
178
  deregisterField,
179
179
  defineField,
180
- }
180
+ };
181
181
  }
182
182
 
183
183
  export type FieldRegistry<T extends FormDataDefault> = ReturnType<
184
184
  typeof useFieldRegistry<T>
185
- >
185
+ >;
@@ -1,4 +1,4 @@
1
- import type { Awaitable } from "@vueuse/core";
1
+ import type { Awaitable } from '@vueuse/core'
2
2
  import {
3
3
  computed,
4
4
  reactive,
@@ -9,86 +9,81 @@ import {
9
9
  type MaybeRef,
10
10
  type MaybeRefOrGetter,
11
11
  type Ref,
12
- } from "vue";
13
- import type { Form, FormDataDefault } from "../types/form";
14
- import type { EntityPaths, PickEntity } from "../types/util";
15
- import type { ValidationStrategy } from "../types/validation";
16
- import { cloneRefValue } from "../utils/general";
17
- import { useFieldRegistry } from "./useFieldRegistry";
18
- import { useFormState } from "./useFormState";
19
- import { createSubformInterface, type SubformOptions } from "./useSubform";
20
- import { useValidation, type ValidationOptions } from "./useValidation";
21
-
22
- // TODO @Elias implement validation strategy handling
12
+ } from 'vue'
13
+ import type { Form, FormDataDefault } from '../types/form'
14
+ import type { EntityPaths, PickEntity } from '../types/util'
15
+ import type { ValidationStrategy } from '../types/validation'
16
+ import { cloneRefValue } from '../utils/general'
17
+ import { useFieldRegistry } from './useFieldRegistry'
18
+ import { useFormState } from './useFormState'
19
+ import { createSubformInterface, type SubformOptions } from './useSubform'
20
+ import { useValidation, type ValidationOptions } from './useValidation'
23
21
 
24
22
  export interface UseFormOptions<T extends FormDataDefault>
25
23
  extends ValidationOptions<T> {
26
- initialData: MaybeRefOrGetter<T>;
27
- validationStrategy?: MaybeRef<ValidationStrategy>;
28
- keepValuesOnUnmount?: MaybeRef<boolean>;
24
+ initialData: MaybeRefOrGetter<T>
25
+ validationStrategy?: MaybeRef<ValidationStrategy>
26
+ keepValuesOnUnmount?: MaybeRef<boolean>
29
27
  }
30
28
 
31
29
  export function useForm<T extends FormDataDefault>(options: UseFormOptions<T>) {
32
- const initialData = computed(() =>
33
- Object.freeze(cloneRefValue(options.initialData)),
34
- );
30
+ const initialData = computed(() => cloneRefValue(options.initialData))
35
31
 
36
- const data = ref<T>(cloneRefValue(initialData)) as Ref<T>;
32
+ const data = ref<T>(cloneRefValue(initialData)) as Ref<T>
37
33
 
38
34
  const state = reactive({
39
35
  initialData,
40
36
  data,
41
- });
37
+ })
42
38
 
43
39
  watch(
44
40
  initialData,
45
41
  (newValue) => {
46
- state.data = cloneRefValue(newValue);
42
+ state.data = cloneRefValue(newValue)
47
43
  },
48
- { flush: "sync" },
49
- );
44
+ { flush: 'sync' },
45
+ )
50
46
 
51
- const validationState = useValidation(state, options);
47
+ const validationState = useValidation(state, options)
52
48
  const fieldRegistry = useFieldRegistry(state, validationState, {
53
49
  keepValuesOnUnmount: options.keepValuesOnUnmount,
54
50
  onBlur: async (path: string) => {
55
- if (unref(options.validationStrategy) === "onTouch") {
56
- // TODO: Only validate the specific field that was touched
57
- validationState.validateField(path);
51
+ if (unref(options.validationStrategy) === 'onTouch') {
52
+ validationState.validateField(path)
58
53
  }
59
54
  },
60
- });
61
- const formState = useFormState(fieldRegistry);
55
+ })
56
+ const formState = useFormState(fieldRegistry)
62
57
 
63
58
  const submitHandler = (onSubmit: (data: T) => Awaitable<void>) => {
64
59
  return async (event: SubmitEvent) => {
65
- event.preventDefault();
60
+ event.preventDefault()
66
61
 
67
- if (unref(options.validationStrategy) !== "none") {
68
- await validationState.validateForm();
62
+ if (unref(options.validationStrategy) !== 'none') {
63
+ await validationState.validateForm()
69
64
  }
70
65
 
71
66
  if (!validationState.isValid.value) {
72
- return;
67
+ return
73
68
  }
74
69
 
75
- await onSubmit(state.data);
76
- };
77
- };
70
+ await onSubmit(state.data)
71
+ }
72
+ }
78
73
 
79
74
  const reset = () => {
80
- data.value = cloneRefValue(initialData);
81
- validationState.reset();
75
+ data.value = cloneRefValue(initialData)
76
+ validationState.reset()
82
77
  for (const field of fieldRegistry.fields.value) {
83
- field.reset();
78
+ field.reset()
84
79
  }
85
- };
80
+ }
86
81
 
87
82
  function getSubForm<K extends EntityPaths<T>>(
88
83
  path: K,
89
84
  options?: SubformOptions<PickEntity<T, K>>,
90
- ): Form<PickEntity<T, K>> {
91
- return createSubformInterface(formInterface, path, options);
85
+ ): Omit<Form<PickEntity<T, K>>, 'submitHandler'> {
86
+ return createSubformInterface(formInterface, path, options)
92
87
  }
93
88
 
94
89
  const formInterface: Form<T> = {
@@ -98,13 +93,13 @@ export function useForm<T extends FormDataDefault>(options: UseFormOptions<T>) {
98
93
  reset,
99
94
  getSubForm,
100
95
  submitHandler,
101
- initialData: toRef(state, "initialData") as Form<T>["initialData"],
102
- data: toRef(state, "data") as Form<T>["data"],
103
- };
96
+ initialData: toRef(state, 'initialData') as Form<T>['initialData'],
97
+ data: toRef(state, 'data') as Form<T>['data'],
98
+ }
104
99
 
105
- if (unref(options.validationStrategy) === "onFormOpen") {
106
- validationState.validateForm();
100
+ if (unref(options.validationStrategy) === 'onFormOpen') {
101
+ validationState.validateForm()
107
102
  }
108
103
 
109
- return formInterface;
104
+ return formInterface
110
105
  }
@@ -50,7 +50,7 @@ export function createSubformInterface<
50
50
  mainForm: Form<T>,
51
51
  path: K,
52
52
  _options?: SubformOptions<PickEntity<T, K>>,
53
- ): Form<PickEntity<T, K>> {
53
+ ): Omit<Form<PickEntity<T, K>>, 'submitHandler'> {
54
54
  type ST = PickEntity<T, K>
55
55
  type SP = Paths<ST>
56
56
  type MP<P extends SP> = `${K}.${P}`
package/src/types/form.ts CHANGED
@@ -80,5 +80,5 @@ export interface Form<T extends FormDataDefault> {
80
80
  getSubForm: <P extends EntityPaths<T>>(
81
81
  path: P,
82
82
  options?: SubformOptions<PickEntity<T, P>>,
83
- ) => Form<PickEntity<T, P>>
83
+ ) => Omit<Form<PickEntity<T, P>>, 'submitHandler'>
84
84
  }
package/src/utils/path.ts CHANGED
@@ -1,21 +1,21 @@
1
- import { computed, isRef, unref, type MaybeRef } from "vue";
2
- import type { Paths, PickProps, SplitPath } from "../types/util";
3
- import type { ErrorBag, ValidationErrors } from "../types/validation";
4
- import type { FormField } from "../types/form";
1
+ import { computed, isRef, unref, type MaybeRef } from 'vue'
2
+ import type { Paths, PickProps, SplitPath } from '../types/util'
3
+ import type { ErrorBag, ValidationErrors } from '../types/validation'
4
+ import type { FormField } from '../types/form'
5
5
 
6
6
  export function splitPath(path: string): string[] {
7
- if (path === "") {
8
- return [];
7
+ if (path === '') {
8
+ return []
9
9
  }
10
- return path.split(/\s*\.\s*/).filter(Boolean);
10
+ return path.split(/\s*\.\s*/).filter(Boolean)
11
11
  }
12
12
 
13
13
  export function existsPath<T, K extends Paths<T>>(
14
14
  obj: T,
15
15
  path: K | SplitPath<K>,
16
16
  ): boolean {
17
- const splittedPath = Array.isArray(path) ? path : splitPath(path) as SplitPath<K>;
18
- return !!getNestedValue(obj, splittedPath.slice(0, -1) as SplitPath<K>);
17
+ const splittedPath = Array.isArray(path) ? path : splitPath(path) as SplitPath<K>
18
+ return !!getNestedValue(obj, splittedPath.slice(0, -1) as SplitPath<K>)
19
19
  }
20
20
 
21
21
  export function existsFieldPath<T, K extends Paths<T>>(field: FormField<T, K>) {
@@ -26,11 +26,11 @@ export function getNestedValue<T, K extends Paths<T>>(
26
26
  obj: T,
27
27
  path: K | SplitPath<K>,
28
28
  ) {
29
- const splittedPath = Array.isArray(path) ? path : splitPath(path);
29
+ const splittedPath = Array.isArray(path) ? path : splitPath(path)
30
30
  return splittedPath.reduce(
31
31
  (current, key) => current?.[key],
32
32
  obj as Record<string, never>,
33
- ) as PickProps<T, K>;
33
+ ) as PickProps<T, K>
34
34
  }
35
35
 
36
36
  export function setNestedValue<T, K extends Paths<T>>(
@@ -38,31 +38,31 @@ export function setNestedValue<T, K extends Paths<T>>(
38
38
  path: K | SplitPath<K>,
39
39
  value: PickProps<T, K>,
40
40
  ): void {
41
- const keys = Array.isArray(path) ? path : splitPath(path);
41
+ const keys = Array.isArray(path) ? path : splitPath(path)
42
42
 
43
- const lastKey = keys.at(-1)!;
43
+ const lastKey = keys.at(-1)!
44
44
 
45
45
  if (!lastKey) {
46
46
  if (!isRef(obj)) {
47
47
  // We cannot do anything here as we have nothing we can assign to
48
- return;
48
+ return
49
49
  }
50
50
 
51
- obj.value = value;
51
+ obj.value = value
52
52
  } else {
53
53
  const target = keys.slice(0, -1).reduce(
54
54
  (current, key) => {
55
55
  if (current?.[key] === undefined) {
56
56
  // Create the nested object if it doesn't exist
57
- current[key] = {};
57
+ current[key] = {}
58
58
  }
59
- return current?.[key];
59
+ return current?.[key]
60
60
  },
61
61
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
62
  unref(obj) as Record<string, any>,
63
- );
63
+ )
64
64
 
65
- target[lastKey] = value;
65
+ target[lastKey] = value
66
66
  }
67
67
  }
68
68
 
@@ -72,58 +72,57 @@ export const getLens = <T, K extends Paths<T>>(
72
72
  ) => {
73
73
  return computed({
74
74
  get() {
75
- return getNestedValue(unref(data), unref(key));
75
+ return getNestedValue(unref(data), unref(key))
76
76
  },
77
77
  set(value: PickProps<T, K>) {
78
- setNestedValue(data, unref(key), value);
78
+ setNestedValue(data, unref(key), value)
79
79
  },
80
- });
81
- };
80
+ })
81
+ }
82
82
 
83
83
  type JoinPath<
84
84
  Base extends string,
85
85
  Sub extends string,
86
- > = `${Base}${Base extends "" ? "" : Sub extends "" ? "" : "."}${Sub}`;
86
+ > = `${Base}${Base extends '' ? '' : Sub extends '' ? '' : '.'}${Sub}`
87
87
  export function joinPath<Base extends string, Sub extends string>(
88
88
  basePath: Base,
89
89
  subPath: Sub,
90
90
  ): JoinPath<Base, Sub> {
91
91
  if (!basePath && !subPath) {
92
- return "" as JoinPath<Base, Sub>;
92
+ return '' as JoinPath<Base, Sub>
93
93
  }
94
94
 
95
95
  if (!basePath && subPath) {
96
- return subPath as JoinPath<Base, Sub>;
96
+ return subPath as JoinPath<Base, Sub>
97
97
  }
98
98
 
99
99
  if (!subPath && basePath) {
100
- return basePath as JoinPath<Base, Sub>;
100
+ return basePath as JoinPath<Base, Sub>
101
101
  }
102
102
 
103
- return `${basePath}.${subPath}` as JoinPath<Base, Sub>;
103
+ return `${basePath}.${subPath}` as JoinPath<Base, Sub>
104
104
  }
105
105
 
106
106
  export function filterErrorsForPath(errors: ErrorBag, path: string): ErrorBag {
107
107
  // Handle empty path - return all errors
108
108
  if (!path) {
109
- return errors;
109
+ return errors
110
110
  }
111
111
 
112
- const pathPrefix = `${path}.`;
113
- const filteredPropertyErrors: Record<string, ValidationErrors> =
114
- Object.fromEntries(
115
- Object.entries(errors.propertyErrors)
116
- .filter(([errorPath]) => {
117
- return errorPath.startsWith(pathPrefix);
118
- })
119
- .map(([errorPath, errorMessages]) => [
120
- errorPath.slice(pathPrefix.length),
121
- errorMessages,
122
- ]),
123
- );
112
+ const pathPrefix = `${path}.`
113
+ const filteredPropertyErrors: Record<string, ValidationErrors> = Object.fromEntries(
114
+ Object.entries(errors.propertyErrors)
115
+ .filter(([errorPath]) => {
116
+ return errorPath.startsWith(pathPrefix)
117
+ })
118
+ .map(([errorPath, errorMessages]) => [
119
+ errorPath.slice(pathPrefix.length),
120
+ errorMessages,
121
+ ]),
122
+ )
124
123
 
125
124
  return {
126
125
  general: errors.general, // Keep general errors
127
126
  propertyErrors: filteredPropertyErrors,
128
- };
127
+ }
129
128
  }