@macrulez/vue-form-schema 0.1.7 → 0.2.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 (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +461 -180
  3. package/dist/MaskEngine-BEXwX4BK.js +144 -0
  4. package/dist/MaskEngine-CPr-fSPy.cjs +1 -0
  5. package/dist/ValidationEngine-BC4U1ef1.js +135 -0
  6. package/dist/ValidationEngine-Diz-qTFs.cjs +1 -0
  7. package/dist/_plugin-vue_export-helper-BHFhmbuH.cjs +1 -0
  8. package/dist/_plugin-vue_export-helper-CHgC5LLL.js +9 -0
  9. package/dist/core/ConditionEvaluator.d.ts.map +1 -1
  10. package/dist/core/MaskEngine.d.ts.map +1 -1
  11. package/dist/core/ValidationEngine.d.ts +13 -0
  12. package/dist/core/ValidationEngine.d.ts.map +1 -1
  13. package/dist/core/formRegistry.d.ts +33 -0
  14. package/dist/core/formRegistry.d.ts.map +1 -0
  15. package/dist/core/inferTypes.d.ts.map +1 -1
  16. package/dist/core/schemaUtils.d.ts +38 -0
  17. package/dist/core/schemaUtils.d.ts.map +1 -1
  18. package/dist/core/serverErrors.d.ts +69 -0
  19. package/dist/core/serverErrors.d.ts.map +1 -0
  20. package/dist/core/types.d.ts +22 -2
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/core/useForm.d.ts +4 -1
  23. package/dist/core/useForm.d.ts.map +1 -1
  24. package/dist/core/useMultiStepForm.d.ts.map +1 -1
  25. package/dist/devtools/index.d.ts +26 -0
  26. package/dist/devtools/index.d.ts.map +1 -0
  27. package/dist/devtools.cjs +1 -0
  28. package/dist/devtools.d.ts +6 -0
  29. package/dist/devtools.js +93 -0
  30. package/dist/formRegistry-Bv1eaWQ-.js +31 -0
  31. package/dist/formRegistry-DaDmXyYY.cjs +1 -0
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.d.ts +5 -3
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +392 -359
  36. package/dist/openapi.cjs +1 -0
  37. package/dist/openapi.d.ts +202 -0
  38. package/dist/openapi.js +118 -0
  39. package/dist/parsers/json.d.ts.map +1 -1
  40. package/dist/parsers/openapi.d.ts +139 -0
  41. package/dist/parsers/openapi.d.ts.map +1 -0
  42. package/dist/parsers/valibot.d.ts +13 -4
  43. package/dist/parsers/valibot.d.ts.map +1 -1
  44. package/dist/parsers/yup.d.ts +10 -4
  45. package/dist/parsers/yup.d.ts.map +1 -1
  46. package/dist/parsers/zod.d.ts +18 -4
  47. package/dist/parsers/zod.d.ts.map +1 -1
  48. package/dist/schemaUtils-Cc7CwGXB.cjs +1 -0
  49. package/dist/schemaUtils-Cvlsk24U.js +337 -0
  50. package/dist/style.css +1 -0
  51. package/dist/ui/index.d.ts +1 -0
  52. package/dist/ui/index.d.ts.map +1 -1
  53. package/dist/ui/naive/index.d.ts +11 -0
  54. package/dist/ui/naive/index.d.ts.map +1 -0
  55. package/dist/ui/primevue/index.d.ts +11 -0
  56. package/dist/ui/primevue/index.d.ts.map +1 -0
  57. package/dist/ui/shadcn/index.d.ts +11 -0
  58. package/dist/ui/shadcn/index.d.ts.map +1 -0
  59. package/dist/ui/tailwind/index.d.ts +11 -0
  60. package/dist/ui/tailwind/index.d.ts.map +1 -0
  61. package/dist/ui-naive.cjs +1 -0
  62. package/dist/ui-naive.d.ts +411 -0
  63. package/dist/ui-naive.js +667 -0
  64. package/dist/ui-primevue.cjs +1 -0
  65. package/dist/ui-primevue.d.ts +411 -0
  66. package/dist/ui-primevue.js +651 -0
  67. package/dist/ui-shadcn.cjs +1 -0
  68. package/dist/ui-shadcn.d.ts +411 -0
  69. package/dist/ui-shadcn.js +650 -0
  70. package/dist/ui-tailwind.cjs +1 -0
  71. package/dist/ui-tailwind.d.ts +411 -0
  72. package/dist/ui-tailwind.js +669 -0
  73. package/dist/ui.cjs +1 -1
  74. package/dist/ui.d.ts +61 -10
  75. package/dist/ui.js +434 -299
  76. package/dist/valibot.cjs +1 -1
  77. package/dist/valibot.d.ts +35 -4
  78. package/dist/valibot.js +47 -20
  79. package/dist/yup.cjs +1 -1
  80. package/dist/yup.d.ts +33 -5
  81. package/dist/yup.js +16 -15
  82. package/dist/zod.cjs +1 -1
  83. package/dist/zod.d.ts +41 -5
  84. package/dist/zod.js +58 -28
  85. package/package.json +99 -25
  86. package/dist/MaskEngine-BqJQYybS.js +0 -233
  87. package/dist/MaskEngine-BwAs2Zb0.cjs +0 -1
  88. package/dist/__tests__/ConditionEvaluator.test.d.ts +0 -2
  89. package/dist/__tests__/ConditionEvaluator.test.d.ts.map +0 -1
  90. package/dist/__tests__/MaskEngine.test.d.ts +0 -2
  91. package/dist/__tests__/MaskEngine.test.d.ts.map +0 -1
  92. package/dist/__tests__/ValidationEngine.test.d.ts +0 -2
  93. package/dist/__tests__/ValidationEngine.test.d.ts.map +0 -1
  94. package/dist/__tests__/parsers.test.d.ts +0 -2
  95. package/dist/__tests__/parsers.test.d.ts.map +0 -1
  96. package/dist/__tests__/phase3.test.d.ts +0 -2
  97. package/dist/__tests__/phase3.test.d.ts.map +0 -1
  98. package/dist/__tests__/phase4.test.d.ts +0 -2
  99. package/dist/__tests__/phase4.test.d.ts.map +0 -1
  100. package/dist/__tests__/useFieldArray.test.d.ts +0 -2
  101. package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
  102. package/dist/__tests__/useForm.test.d.ts +0 -2
  103. package/dist/__tests__/useForm.test.d.ts.map +0 -1
  104. package/dist/__tests__/useMultiStepForm.test.d.ts +0 -2
  105. package/dist/__tests__/useMultiStepForm.test.d.ts.map +0 -1
package/dist/valibot.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function p(t){if(!t||t.type!=="object"||!t.entries)throw new Error("[vue-form-schema] parseValibot expects a v.object() schema");return Object.entries(t.entries).map(([r,i])=>o(r,i))}function o(t,r){let i=!0,e=r;(e.type==="optional"||e.type==="nullable"||e.type==="nullish")&&(i=!1,e=e.wrapped??e);const a=u(e),s={type:a,name:t,required:i};return a==="select"&&(s.options=e.options.map(n=>({label:String(n),value:n}))),a==="group"&&e.entries&&(s.fields=Object.entries(e.entries).map(([n,l])=>o(n,l))),s}function u(t){const r=t.type;if(r==="string"&&Array.isArray(t.pipe)&&t.pipe.some(e=>e.type==="email"))return"email";switch(r){case"string":return"text";case"number":return"number";case"boolean":return"checkbox";case"picklist":case"enum":return"select";case"array":return"array";case"object":return"group";default:return"text"}}exports.parseValibot=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./schemaUtils-Cc7CwGXB.cjs");function b(r){const e=r;if((e==null?void 0:e.type)==="variant")return f(e);if(!e||e.type!=="object"||!e.entries)throw new Error("[vue-form-schema] parseValibot expects a v.object() or v.variant() schema");return Object.entries(e.entries).map(([i,t])=>l(i,t))}function f(r){const e=r.key,i=r.options;function t(n){var o;const s=n.entries??{};return String((o=s[e])==null?void 0:o.literal)}const c={type:"select",name:e,label:e,required:!0,options:i.map(n=>{const s=t(n);return{label:s,value:s}})},a={};for(const n of i){const s=n.entries??{};a[t(n)]=Object.entries(s).filter(([o])=>o!==e).map(([o,p])=>l(o,p))}return[c,...u.discriminatedFields(e,a)]}function l(r,e){let i=!0,t=e;(t.type==="optional"||t.type==="nullable"||t.type==="nullish")&&(i=!1,t=t.wrapped??t);const c=m(t),a={type:c,name:r,required:i};return c==="select"&&(a.options=t.options.map(n=>({label:String(n),value:n}))),c==="group"&&t.entries&&(a.fields=Object.entries(t.entries).map(([n,s])=>l(`${r}.${n}`,s))),a}function m(r){const e=r.type;if(e==="string"&&Array.isArray(r.pipe)&&r.pipe.some(t=>t.type==="email"))return"email";switch(e){case"string":return"text";case"number":return"number";case"boolean":return"checkbox";case"picklist":case"enum":return"select";case"array":return"array";case"object":return"group";default:return"text"}}exports.parseValibot=b;
package/dist/valibot.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { Component } from 'vue';
2
+ import { GenericSchema } from 'valibot';
3
+ import { InferOutput } from 'valibot';
2
4
 
3
5
  declare type AsyncValidatorFn = (value: unknown, values: Record<string, unknown>) => Promise<string | null>;
4
6
 
@@ -8,7 +10,7 @@ declare interface FieldDefinition {
8
10
  name: string;
9
11
  label?: string;
10
12
  placeholder?: string;
11
- defaultValue?: unknown;
13
+ defaultValue?: unknown | ((values: Record<string, unknown>) => unknown);
12
14
  required?: boolean;
13
15
  /** Static or dynamic disabled state */
14
16
  disabled?: boolean | ((values: Record<string, unknown>) => boolean);
@@ -43,6 +45,14 @@ declare interface FieldDefinition {
43
45
  * Receives FormFieldProps and must emit 'update:modelValue' and 'blur'.
44
46
  */
45
47
  component?: Component | string;
48
+ /** Accepted file types, e.g. "image/*,.pdf" — passed to <input accept> */
49
+ accept?: string;
50
+ /** Allow selecting multiple files */
51
+ multiple?: boolean;
52
+ /** Maximum file size in bytes */
53
+ maxSize?: number;
54
+ /** Maximum number of files (only relevant when multiple=true) */
55
+ maxFiles?: number;
46
56
  }
47
57
 
48
58
  declare interface FieldOption {
@@ -50,7 +60,7 @@ declare interface FieldOption {
50
60
  value: unknown;
51
61
  }
52
62
 
53
- declare type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group';
63
+ declare type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group' | 'file';
54
64
 
55
65
  declare interface MaskConfig {
56
66
  preset?: MaskPreset;
@@ -74,10 +84,31 @@ declare type MaskPreset = 'phone-ru' | 'phone-eu' | 'date' | 'inn' | 'iban';
74
84
  *
75
85
  * const schema = v.object({ email: v.pipe(v.string(), v.email()), age: v.number() })
76
86
  * const fields = parseValibot(schema)
87
+ *
88
+ * The return type carries the schema's inferred value type
89
+ * (`v.InferOutput<S>`), so `useForm({ schema: fields })` picks up fully
90
+ * typed `values`/`errors`/`onSubmit` without an explicit `useForm<Values>(...)`.
91
+ *
92
+ * Also accepts a `v.variant(key, [...])` schema — converted into a `select`
93
+ * field for the discriminator plus every variant's own fields, each only
94
+ * visible while the discriminator matches its variant (see
95
+ * `discriminatedFields`). Combine with `clearOnHide: true` on `useForm` so
96
+ * switching variants resets the now-hidden variant's values.
77
97
  */
78
- export declare function parseValibot(schema: ValibotSchema): FieldDefinition[];
98
+ export declare function parseValibot<S extends GenericSchema>(schema: S): TypedFieldDefinitions<InferOutput<S>>;
79
99
 
80
- declare type ValibotSchema = any;
100
+ /**
101
+ * A `FieldDefinition[]` returned by a schema adapter (`parseZod` / `parseYup`
102
+ * / `parseValibot`) that also carries the source schema's inferred value
103
+ * type at the type level. `useForm({ schema: parseZod(mySchema) })` then
104
+ * infers `T` automatically — no `useForm<Values>(...)` needed.
105
+ *
106
+ * `__inferredValues` does not exist at runtime; it is a type-only marker
107
+ * erased by the compiler.
108
+ */
109
+ declare type TypedFieldDefinitions<T> = FieldDefinition[] & {
110
+ readonly __inferredValues?: T;
111
+ };
81
112
 
82
113
  declare type ValidatorFn = (value: unknown, values: Record<string, unknown>) => string | null;
83
114
 
package/dist/valibot.js CHANGED
@@ -1,26 +1,53 @@
1
- function u(t) {
2
- if (!t || t.type !== "object" || !t.entries)
3
- throw new Error("[vue-form-schema] parseValibot expects a v.object() schema");
4
- return Object.entries(t.entries).map(
5
- ([r, n]) => o(r, n)
1
+ import { d as u } from "./schemaUtils-Cvlsk24U.js";
2
+ function y(r) {
3
+ const e = r;
4
+ if ((e == null ? void 0 : e.type) === "variant")
5
+ return f(e);
6
+ if (!e || e.type !== "object" || !e.entries)
7
+ throw new Error("[vue-form-schema] parseValibot expects a v.object() or v.variant() schema");
8
+ return Object.entries(e.entries).map(
9
+ ([i, t]) => l(i, t)
6
10
  );
7
11
  }
8
- function o(t, r) {
9
- let n = !0, e = r;
10
- (e.type === "optional" || e.type === "nullable" || e.type === "nullish") && (n = !1, e = e.wrapped ?? e);
11
- const a = l(e), s = { type: a, name: t, required: n };
12
- return a === "select" && (s.options = e.options.map((i) => ({
13
- label: String(i),
14
- value: i
15
- }))), a === "group" && e.entries && (s.fields = Object.entries(e.entries).map(
16
- ([i, p]) => o(i, p)
17
- )), s;
12
+ function f(r) {
13
+ const e = r.key, i = r.options;
14
+ function t(n) {
15
+ var o;
16
+ const s = n.entries ?? {};
17
+ return String((o = s[e]) == null ? void 0 : o.literal);
18
+ }
19
+ const c = {
20
+ type: "select",
21
+ name: e,
22
+ label: e,
23
+ required: !0,
24
+ options: i.map((n) => {
25
+ const s = t(n);
26
+ return { label: s, value: s };
27
+ })
28
+ }, a = {};
29
+ for (const n of i) {
30
+ const s = n.entries ?? {};
31
+ a[t(n)] = Object.entries(s).filter(([o]) => o !== e).map(([o, p]) => l(o, p));
32
+ }
33
+ return [c, ...u(e, a)];
34
+ }
35
+ function l(r, e) {
36
+ let i = !0, t = e;
37
+ (t.type === "optional" || t.type === "nullable" || t.type === "nullish") && (i = !1, t = t.wrapped ?? t);
38
+ const c = m(t), a = { type: c, name: r, required: i };
39
+ return c === "select" && (a.options = t.options.map((n) => ({
40
+ label: String(n),
41
+ value: n
42
+ }))), c === "group" && t.entries && (a.fields = Object.entries(t.entries).map(
43
+ ([n, s]) => l(`${r}.${n}`, s)
44
+ )), a;
18
45
  }
19
- function l(t) {
20
- const r = t.type;
21
- if (r === "string" && Array.isArray(t.pipe) && t.pipe.some((e) => e.type === "email"))
46
+ function m(r) {
47
+ const e = r.type;
48
+ if (e === "string" && Array.isArray(r.pipe) && r.pipe.some((t) => t.type === "email"))
22
49
  return "email";
23
- switch (r) {
50
+ switch (e) {
24
51
  case "string":
25
52
  return "text";
26
53
  case "number":
@@ -39,5 +66,5 @@ function l(t) {
39
66
  }
40
67
  }
41
68
  export {
42
- u as parseValibot
69
+ y as parseValibot
43
70
  };
package/dist/yup.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function s(r){switch(r){case"string":return"text";case"number":return"number";case"boolean":return"checkbox";case"array":return"array";case"object":return"group";default:return"text"}}function p(r,e){const t=[];return e&&t.push(u=>u==null||u===""?"This field is required":null),t.push(u=>{try{return r.validateSync(u,{abortEarly:!0}),null}catch(n){return n&&typeof n=="object"&&"message"in n?n.message:"Invalid value"}}),t}function i(r,e){const t=!e.spec.optional&&!e.spec.nullable,u=e.spec.label??r,n=s(e.type);return e.type==="object"&&e.fields?{type:"group",name:r,label:u,required:t,fields:Object.entries(e.fields).map(([o,l])=>i(`${r}.${o}`,l))}:{type:n,name:r,label:u,defaultValue:e.spec.default,required:t,validators:p(e,t)}}function a(r){if(r.type!=="object")throw new Error("[vue-form-schema] parseYup expects an object schema");return Object.entries(r.fields??{}).map(([e,t])=>i(e,t))}exports.parseYup=a;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function s(r){switch(r){case"string":return"text";case"number":return"number";case"boolean":return"checkbox";case"array":return"array";case"object":return"group";default:return"text"}}function p(r,e){const u=[];return e&&u.push(t=>t==null||t===""?"This field is required":null),u.push(t=>{try{return r.validateSync(t,{abortEarly:!0}),null}catch(n){return n&&typeof n=="object"&&"message"in n?n.message:"Invalid value"}}),u}function i(r,e){const u=!e.spec.optional&&!e.spec.nullable,t=e.spec.label??r,n=s(e.type);return e.type==="object"&&e.fields?{type:"group",name:r,label:t,required:u,fields:Object.entries(e.fields).map(([o,l])=>i(`${r}.${o}`,l))}:{type:n,name:r,label:t,defaultValue:e.spec.default,required:u,validators:p(e,u)}}function a(r){const e=r;if(e.type!=="object")throw new Error("[vue-form-schema] parseYup expects an object schema");return Object.entries(e.fields??{}).map(([u,t])=>i(u,t))}exports.parseYup=a;
package/dist/yup.d.ts CHANGED
@@ -1,4 +1,6 @@
1
+ import { AnySchema } from 'yup';
1
2
  import { Component } from 'vue';
3
+ import { InferType } from 'yup';
2
4
 
3
5
  declare type AsyncValidatorFn = (value: unknown, values: Record<string, unknown>) => Promise<string | null>;
4
6
 
@@ -8,7 +10,7 @@ declare interface FieldDefinition {
8
10
  name: string;
9
11
  label?: string;
10
12
  placeholder?: string;
11
- defaultValue?: unknown;
13
+ defaultValue?: unknown | ((values: Record<string, unknown>) => unknown);
12
14
  required?: boolean;
13
15
  /** Static or dynamic disabled state */
14
16
  disabled?: boolean | ((values: Record<string, unknown>) => boolean);
@@ -43,6 +45,14 @@ declare interface FieldDefinition {
43
45
  * Receives FormFieldProps and must emit 'update:modelValue' and 'blur'.
44
46
  */
45
47
  component?: Component | string;
48
+ /** Accepted file types, e.g. "image/*,.pdf" — passed to <input accept> */
49
+ accept?: string;
50
+ /** Allow selecting multiple files */
51
+ multiple?: boolean;
52
+ /** Maximum file size in bytes */
53
+ maxSize?: number;
54
+ /** Maximum number of files (only relevant when multiple=true) */
55
+ maxFiles?: number;
46
56
  }
47
57
 
48
58
  declare interface FieldOption {
@@ -50,7 +60,7 @@ declare interface FieldOption {
50
60
  value: unknown;
51
61
  }
52
62
 
53
- declare type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group';
63
+ declare type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group' | 'file';
54
64
 
55
65
  declare interface MaskConfig {
56
66
  preset?: MaskPreset;
@@ -60,10 +70,28 @@ declare interface MaskConfig {
60
70
 
61
71
  declare type MaskPreset = 'phone-ru' | 'phone-eu' | 'date' | 'inn' | 'iban';
62
72
 
63
- export declare function parseYup(schema: YupSchema): FieldDefinition[];
73
+ /**
74
+ * Parses a `yup.object({...})` schema into a `FieldDefinition[]`.
75
+ *
76
+ * The return type carries the schema's inferred value type (`InferType<S>`),
77
+ * so `useForm({ schema: parseYup(mySchema) })` picks up fully typed
78
+ * `values`/`errors`/`onSubmit` without an explicit `useForm<Values>(...)`.
79
+ */
80
+ export declare function parseYup<S extends AnySchema>(schema: S): TypedFieldDefinitions<InferType<S>>;
64
81
 
65
- declare type ValidatorFn = (value: unknown, values: Record<string, unknown>) => string | null;
82
+ /**
83
+ * A `FieldDefinition[]` returned by a schema adapter (`parseZod` / `parseYup`
84
+ * / `parseValibot`) that also carries the source schema's inferred value
85
+ * type at the type level. `useForm({ schema: parseZod(mySchema) })` then
86
+ * infers `T` automatically — no `useForm<Values>(...)` needed.
87
+ *
88
+ * `__inferredValues` does not exist at runtime; it is a type-only marker
89
+ * erased by the compiler.
90
+ */
91
+ declare type TypedFieldDefinitions<T> = FieldDefinition[] & {
92
+ readonly __inferredValues?: T;
93
+ };
66
94
 
67
- declare type YupSchema = any;
95
+ declare type ValidatorFn = (value: unknown, values: Record<string, unknown>) => string | null;
68
96
 
69
97
  export { }
package/dist/yup.js CHANGED
@@ -1,4 +1,4 @@
1
- function p(r) {
1
+ function s(r) {
2
2
  switch (r) {
3
3
  case "string":
4
4
  return "text";
@@ -14,40 +14,41 @@ function p(r) {
14
14
  return "text";
15
15
  }
16
16
  }
17
- function s(r, e) {
18
- const t = [];
19
- return e && t.push((u) => u == null || u === "" ? "This field is required" : null), t.push((u) => {
17
+ function p(r, e) {
18
+ const u = [];
19
+ return e && u.push((t) => t == null || t === "" ? "This field is required" : null), u.push((t) => {
20
20
  try {
21
- return r.validateSync(u, { abortEarly: !0 }), null;
21
+ return r.validateSync(t, { abortEarly: !0 }), null;
22
22
  } catch (n) {
23
23
  return n && typeof n == "object" && "message" in n ? n.message : "Invalid value";
24
24
  }
25
- }), t;
25
+ }), u;
26
26
  }
27
27
  function i(r, e) {
28
- const t = !e.spec.optional && !e.spec.nullable, u = e.spec.label ?? r, n = p(e.type);
28
+ const u = !e.spec.optional && !e.spec.nullable, t = e.spec.label ?? r, n = s(e.type);
29
29
  return e.type === "object" && e.fields ? {
30
30
  type: "group",
31
31
  name: r,
32
- label: u,
33
- required: t,
32
+ label: t,
33
+ required: u,
34
34
  fields: Object.entries(e.fields).map(
35
35
  ([o, l]) => i(`${r}.${o}`, l)
36
36
  )
37
37
  } : {
38
38
  type: n,
39
39
  name: r,
40
- label: u,
40
+ label: t,
41
41
  defaultValue: e.spec.default,
42
- required: t,
43
- validators: s(e, t)
42
+ required: u,
43
+ validators: p(e, u)
44
44
  };
45
45
  }
46
46
  function a(r) {
47
- if (r.type !== "object")
47
+ const e = r;
48
+ if (e.type !== "object")
48
49
  throw new Error("[vue-form-schema] parseYup expects an object schema");
49
- return Object.entries(r.fields ?? {}).map(
50
- ([e, t]) => i(e, t)
50
+ return Object.entries(e.fields ?? {}).map(
51
+ ([u, t]) => i(u, t)
51
52
  );
52
53
  }
53
54
  export {
package/dist/zod.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function i(s){var n;let e=s._def;for(;e.typeName==="ZodOptional"||e.typeName==="ZodNullable"||e.typeName==="ZodDefault";){e=((n=e.innerType)==null?void 0:n._def)??e;break}return e.typeName}function p(s){switch(i(s)){case"ZodString":return"text";case"ZodNumber":return"number";case"ZodBoolean":return"checkbox";case"ZodArray":return"array";case"ZodObject":return"group";case"ZodEnum":return"select";default:return"text"}}function o(s,e){const n=[],u=s._def;e&&n.push(t=>t==null||t===""?"This field is required":null);for(const t of u.checks??[])switch(t.kind){case"min":n.push(r=>typeof r!="string"||r.length>=Number(t.value)?null:t.message??`Minimum length is ${t.value}`);break;case"max":n.push(r=>typeof r!="string"||r.length<=Number(t.value)?null:t.message??`Maximum length is ${t.value}`);break;case"email":n.push(r=>r?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(r))?null:t.message??"Invalid email address":null);break;case"url":n.push(r=>{if(!r)return null;try{return new URL(String(r)),null}catch{return t.message??"Invalid URL"}});break;case"regex":n.push(r=>typeof r!="string"||t.regex.test(r)?null:t.message??"Invalid format");break}return n.push(t=>{var l,a;const r=s.safeParse(t);return r.success?null:((a=(l=r.error)==null?void 0:l.errors[0])==null?void 0:a.message)??"Invalid value"}),n}function d(s,e){const n=i(e),u=e.isOptional(),t=p(e),r=e._def.description??s;if(n==="ZodObject"&&e._def.shape){const l=e._def.shape();return{type:"group",name:s,label:r,required:!u,fields:Object.entries(l).map(([a,c])=>d(`${s}.${a}`,c))}}if(n==="ZodEnum"&&e._def.values){const l=e._def.values;return{type:"select",name:s,label:r,required:!u,options:Object.entries(l).map(([,a])=>({label:a,value:a})),validators:o(e,!u)}}return{type:t,name:s,label:r,required:!u,validators:o(e,!u)}}function f(s){var n,u;if(s._def.typeName!=="ZodObject")throw new Error("[vue-form-schema] parseZod expects a ZodObject schema");const e=((u=(n=s._def).shape)==null?void 0:u.call(n))??{};return Object.entries(e).map(([t,r])=>d(t,r))}exports.parseZod=f;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("./schemaUtils-Cc7CwGXB.cjs");function h(s){var n;let e=s._def;for(;e.typeName==="ZodOptional"||e.typeName==="ZodNullable"||e.typeName==="ZodDefault";){e=((n=e.innerType)==null?void 0:n._def)??e;break}return e.typeName}function g(s){switch(h(s)){case"ZodString":return"text";case"ZodNumber":return"number";case"ZodBoolean":return"checkbox";case"ZodArray":return"array";case"ZodObject":return"group";case"ZodEnum":return"select";default:return"text"}}function b(s,e){const n=[],i=s._def;e&&n.push(t=>t==null||t===""?"This field is required":null);for(const t of i.checks??[])switch(t.kind){case"min":n.push(r=>typeof r!="string"||r.length>=Number(t.value)?null:t.message??`Minimum length is ${t.value}`);break;case"max":n.push(r=>typeof r!="string"||r.length<=Number(t.value)?null:t.message??`Maximum length is ${t.value}`);break;case"email":n.push(r=>r?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(r))?null:t.message??"Invalid email address":null);break;case"url":n.push(r=>{if(!r)return null;try{return new URL(String(r)),null}catch{return t.message??"Invalid URL"}});break;case"regex":n.push(r=>typeof r!="string"||t.regex.test(r)?null:t.message??"Invalid format");break}return n.push(t=>{var o,a;const r=s.safeParse(t);return r.success?null:((a=(o=r.error)==null?void 0:o.errors[0])==null?void 0:a.message)??"Invalid value"}),n}function p(s,e){const n=h(e),i=e.isOptional(),t=g(e),r=e._def.description??s;if(n==="ZodObject"&&e._def.shape){const o=e._def.shape();return{type:"group",name:s,label:r,required:!i,fields:Object.entries(o).map(([a,u])=>p(`${s}.${a}`,u))}}if(n==="ZodEnum"&&e._def.values){const o=e._def.values;return{type:"select",name:s,label:r,required:!i,options:Object.entries(o).map(([,a])=>({label:a,value:a})),validators:b(e,!i)}}return{type:t,name:s,label:r,required:!i,validators:b(e,!i)}}function Z(s){var o,a;const e=s._def,n=e.discriminator;function i(u){var c,f,m;const l=(((f=(c=u._def).shape)==null?void 0:f.call(c))??{})[n];return String((m=l==null?void 0:l._def)==null?void 0:m.value)}const t={type:"select",name:n,label:n,required:!0,options:e.options.map(u=>{const d=i(u);return{label:d,value:d}})},r={};for(const u of e.options){const d=((a=(o=u._def).shape)==null?void 0:a.call(o))??{};r[i(u)]=Object.entries(d).filter(([l])=>l!==n).map(([l,c])=>p(l,c))}return[t,...y.discriminatedFields(n,r)]}function v(s){var i,t;const e=s;if(e._def.typeName==="ZodDiscriminatedUnion")return Z(e);if(e._def.typeName!=="ZodObject")throw new Error("[vue-form-schema] parseZod expects a ZodObject or ZodDiscriminatedUnion schema");const n=((t=(i=e._def).shape)==null?void 0:t.call(i))??{};return Object.entries(n).map(([r,o])=>p(r,o))}exports.parseZod=v;
package/dist/zod.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Component } from 'vue';
2
+ import { z } from 'zod';
2
3
 
3
4
  declare type AsyncValidatorFn = (value: unknown, values: Record<string, unknown>) => Promise<string | null>;
4
5
 
@@ -8,7 +9,7 @@ declare interface FieldDefinition {
8
9
  name: string;
9
10
  label?: string;
10
11
  placeholder?: string;
11
- defaultValue?: unknown;
12
+ defaultValue?: unknown | ((values: Record<string, unknown>) => unknown);
12
13
  required?: boolean;
13
14
  /** Static or dynamic disabled state */
14
15
  disabled?: boolean | ((values: Record<string, unknown>) => boolean);
@@ -43,6 +44,14 @@ declare interface FieldDefinition {
43
44
  * Receives FormFieldProps and must emit 'update:modelValue' and 'blur'.
44
45
  */
45
46
  component?: Component | string;
47
+ /** Accepted file types, e.g. "image/*,.pdf" — passed to <input accept> */
48
+ accept?: string;
49
+ /** Allow selecting multiple files */
50
+ multiple?: boolean;
51
+ /** Maximum file size in bytes */
52
+ maxSize?: number;
53
+ /** Maximum number of files (only relevant when multiple=true) */
54
+ maxFiles?: number;
46
55
  }
47
56
 
48
57
  declare interface FieldOption {
@@ -50,7 +59,7 @@ declare interface FieldOption {
50
59
  value: unknown;
51
60
  }
52
61
 
53
- declare type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group';
62
+ declare type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group' | 'file';
54
63
 
55
64
  declare interface MaskConfig {
56
65
  preset?: MaskPreset;
@@ -60,10 +69,37 @@ declare interface MaskConfig {
60
69
 
61
70
  declare type MaskPreset = 'phone-ru' | 'phone-eu' | 'date' | 'inn' | 'iban';
62
71
 
63
- export declare function parseZod(schema: ZodTypeAny): FieldDefinition[];
72
+ /**
73
+ * Parses a `z.object({...})` schema into a `FieldDefinition[]`.
74
+ *
75
+ * The return type carries the schema's inferred value type (`z.infer<S>`),
76
+ * so `useForm({ schema: parseZod(mySchema) })` picks up fully typed
77
+ * `values`/`errors`/`onSubmit` without an explicit `useForm<Values>(...)`.
78
+ */
79
+ export declare function parseZod<S extends z.ZodObject<z.ZodRawShape>>(schema: S): TypedFieldDefinitions<z.infer<S>>;
64
80
 
65
- declare type ValidatorFn = (value: unknown, values: Record<string, unknown>) => string | null;
81
+ /**
82
+ * Parses a `z.discriminatedUnion(key, [...])` schema into a `FieldDefinition[]`
83
+ * — a `select` for the discriminator plus every variant's fields, each only
84
+ * visible while the discriminator matches its variant (see
85
+ * `discriminatedFields`). Combine with `clearOnHide: true` on `useForm` so
86
+ * switching variants resets the now-hidden variant's values.
87
+ */
88
+ export declare function parseZod<Discriminator extends string, Options extends readonly z.ZodDiscriminatedUnionOption<Discriminator>[]>(schema: z.ZodDiscriminatedUnion<Discriminator, Options>): TypedFieldDefinitions<z.infer<z.ZodDiscriminatedUnion<Discriminator, Options>>>;
89
+
90
+ /**
91
+ * A `FieldDefinition[]` returned by a schema adapter (`parseZod` / `parseYup`
92
+ * / `parseValibot`) that also carries the source schema's inferred value
93
+ * type at the type level. `useForm({ schema: parseZod(mySchema) })` then
94
+ * infers `T` automatically — no `useForm<Values>(...)` needed.
95
+ *
96
+ * `__inferredValues` does not exist at runtime; it is a type-only marker
97
+ * erased by the compiler.
98
+ */
99
+ declare type TypedFieldDefinitions<T> = FieldDefinition[] & {
100
+ readonly __inferredValues?: T;
101
+ };
66
102
 
67
- declare type ZodTypeAny = any;
103
+ declare type ValidatorFn = (value: unknown, values: Record<string, unknown>) => string | null;
68
104
 
69
105
  export { }
package/dist/zod.js CHANGED
@@ -1,4 +1,5 @@
1
- function i(s) {
1
+ import { d as y } from "./schemaUtils-Cvlsk24U.js";
2
+ function h(s) {
2
3
  var n;
3
4
  let e = s._def;
4
5
  for (; e.typeName === "ZodOptional" || e.typeName === "ZodNullable" || e.typeName === "ZodDefault"; ) {
@@ -7,8 +8,8 @@ function i(s) {
7
8
  }
8
9
  return e.typeName;
9
10
  }
10
- function p(s) {
11
- switch (i(s)) {
11
+ function g(s) {
12
+ switch (h(s)) {
12
13
  case "ZodString":
13
14
  return "text";
14
15
  case "ZodNumber":
@@ -25,10 +26,10 @@ function p(s) {
25
26
  return "text";
26
27
  }
27
28
  }
28
- function o(s, e) {
29
- const n = [], u = s._def;
29
+ function b(s, e) {
30
+ const n = [], i = s._def;
30
31
  e && n.push((t) => t == null || t === "" ? "This field is required" : null);
31
- for (const t of u.checks ?? [])
32
+ for (const t of i.checks ?? [])
32
33
  switch (t.kind) {
33
34
  case "min":
34
35
  n.push((r) => typeof r != "string" || r.length >= Number(t.value) ? null : t.message ?? `Minimum length is ${t.value}`);
@@ -54,51 +55,80 @@ function o(s, e) {
54
55
  break;
55
56
  }
56
57
  return n.push((t) => {
57
- var l, a;
58
+ var o, a;
58
59
  const r = s.safeParse(t);
59
- return r.success ? null : ((a = (l = r.error) == null ? void 0 : l.errors[0]) == null ? void 0 : a.message) ?? "Invalid value";
60
+ return r.success ? null : ((a = (o = r.error) == null ? void 0 : o.errors[0]) == null ? void 0 : a.message) ?? "Invalid value";
60
61
  }), n;
61
62
  }
62
- function d(s, e) {
63
- const n = i(e), u = e.isOptional(), t = p(e), r = e._def.description ?? s;
63
+ function p(s, e) {
64
+ const n = h(e), i = e.isOptional(), t = g(e), r = e._def.description ?? s;
64
65
  if (n === "ZodObject" && e._def.shape) {
65
- const l = e._def.shape();
66
+ const o = e._def.shape();
66
67
  return {
67
68
  type: "group",
68
69
  name: s,
69
70
  label: r,
70
- required: !u,
71
- fields: Object.entries(l).map(
72
- ([a, c]) => d(`${s}.${a}`, c)
73
- )
71
+ required: !i,
72
+ fields: Object.entries(o).map(([a, u]) => p(`${s}.${a}`, u))
74
73
  };
75
74
  }
76
75
  if (n === "ZodEnum" && e._def.values) {
77
- const l = e._def.values;
76
+ const o = e._def.values;
78
77
  return {
79
78
  type: "select",
80
79
  name: s,
81
80
  label: r,
82
- required: !u,
83
- options: Object.entries(l).map(([, a]) => ({ label: a, value: a })),
84
- validators: o(e, !u)
81
+ required: !i,
82
+ options: Object.entries(o).map(([, a]) => ({ label: a, value: a })),
83
+ validators: b(e, !i)
85
84
  };
86
85
  }
87
86
  return {
88
87
  type: t,
89
88
  name: s,
90
89
  label: r,
91
- required: !u,
92
- validators: o(e, !u)
90
+ required: !i,
91
+ validators: b(e, !i)
93
92
  };
94
93
  }
95
- function f(s) {
96
- var n, u;
97
- if (s._def.typeName !== "ZodObject")
98
- throw new Error("[vue-form-schema] parseZod expects a ZodObject schema");
99
- const e = ((u = (n = s._def).shape) == null ? void 0 : u.call(n)) ?? {};
100
- return Object.entries(e).map(([t, r]) => d(t, r));
94
+ function Z(s) {
95
+ var o, a;
96
+ const e = s._def, n = e.discriminator;
97
+ function i(u) {
98
+ var c, f, m;
99
+ const l = (((f = (c = u._def).shape) == null ? void 0 : f.call(c)) ?? {})[n];
100
+ return String((m = l == null ? void 0 : l._def) == null ? void 0 : m.value);
101
+ }
102
+ const t = {
103
+ type: "select",
104
+ name: n,
105
+ label: n,
106
+ required: !0,
107
+ options: e.options.map((u) => {
108
+ const d = i(u);
109
+ return { label: d, value: d };
110
+ })
111
+ }, r = {};
112
+ for (const u of e.options) {
113
+ const d = ((a = (o = u._def).shape) == null ? void 0 : a.call(o)) ?? {};
114
+ r[i(u)] = Object.entries(d).filter(([l]) => l !== n).map(([l, c]) => p(l, c));
115
+ }
116
+ return [t, ...y(n, r)];
117
+ }
118
+ function _(s) {
119
+ var i, t;
120
+ const e = s;
121
+ if (e._def.typeName === "ZodDiscriminatedUnion")
122
+ return Z(e);
123
+ if (e._def.typeName !== "ZodObject")
124
+ throw new Error(
125
+ "[vue-form-schema] parseZod expects a ZodObject or ZodDiscriminatedUnion schema"
126
+ );
127
+ const n = ((t = (i = e._def).shape) == null ? void 0 : t.call(i)) ?? {};
128
+ return Object.entries(n).map(
129
+ ([r, o]) => p(r, o)
130
+ );
101
131
  }
102
132
  export {
103
- f as parseZod
133
+ _ as parseZod
104
134
  };