@macrulez/vue-form-schema 0.1.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 +829 -0
- package/dist/MaskEngine-D22m29OM.js +157 -0
- package/dist/MaskEngine-hd5xHed7.cjs +1 -0
- package/dist/__tests__/ConditionEvaluator.test.d.ts +2 -0
- package/dist/__tests__/ConditionEvaluator.test.d.ts.map +1 -0
- package/dist/__tests__/MaskEngine.test.d.ts +2 -0
- package/dist/__tests__/MaskEngine.test.d.ts.map +1 -0
- package/dist/__tests__/ValidationEngine.test.d.ts +2 -0
- package/dist/__tests__/ValidationEngine.test.d.ts.map +1 -0
- package/dist/__tests__/parsers.test.d.ts +2 -0
- package/dist/__tests__/parsers.test.d.ts.map +1 -0
- package/dist/__tests__/useForm.test.d.ts +2 -0
- package/dist/__tests__/useForm.test.d.ts.map +1 -0
- package/dist/core/ConditionEvaluator.d.ts +18 -0
- package/dist/core/ConditionEvaluator.d.ts.map +1 -0
- package/dist/core/MaskEngine.d.ts +21 -0
- package/dist/core/MaskEngine.d.ts.map +1 -0
- package/dist/core/ValidationEngine.d.ts +25 -0
- package/dist/core/ValidationEngine.d.ts.map +1 -0
- package/dist/core/types.d.ts +76 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/useForm.d.ts +3 -0
- package/dist/core/useForm.d.ts.map +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +278 -0
- package/dist/parsers/json.d.ts +3 -0
- package/dist/parsers/json.d.ts.map +1 -0
- package/dist/parsers/yup.d.ts +10 -0
- package/dist/parsers/yup.d.ts.map +1 -0
- package/dist/parsers/zod.d.ts +10 -0
- package/dist/parsers/zod.d.ts.map +1 -0
- package/dist/ui/index.d.ts +9 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui.cjs +1 -0
- package/dist/ui.d.ts +324 -0
- package/dist/ui.js +438 -0
- package/dist/yup.cjs +1 -0
- package/dist/yup.d.ts +45 -0
- package/dist/yup.js +55 -0
- package/dist/zod.cjs +1 -0
- package/dist/zod.d.ts +45 -0
- package/dist/zod.js +104 -0
- package/package.json +69 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
const y = (t) => t == null || t === "" || Array.isArray(t) && t.length === 0 ? "This field is required" : null, M = (t, e) => (r) => typeof r != "string" && !Array.isArray(r) || r.length >= t ? null : e ?? `Minimum length is ${t}`, T = (t, e) => (r) => typeof r != "string" && !Array.isArray(r) || r.length <= t ? null : e ?? `Maximum length is ${t}`, v = (t, e) => (r) => {
|
|
2
|
+
const s = Number(r);
|
|
3
|
+
return isNaN(s) || s >= t ? null : e ?? `Minimum value is ${t}`;
|
|
4
|
+
}, x = (t, e) => (r) => {
|
|
5
|
+
const s = Number(r);
|
|
6
|
+
return isNaN(s) || s <= t ? null : e ?? `Maximum value is ${t}`;
|
|
7
|
+
}, I = (t, e) => (r) => typeof r != "string" || t.test(r) ? null : e ?? "Invalid format", b = (t) => t ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(t)) ? null : "Invalid email address" : null, E = (t) => {
|
|
8
|
+
if (!t) return null;
|
|
9
|
+
try {
|
|
10
|
+
return new URL(String(t)), null;
|
|
11
|
+
} catch {
|
|
12
|
+
return "Invalid URL";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
class w {
|
|
16
|
+
constructor(e = 300) {
|
|
17
|
+
this.asyncTimers = /* @__PURE__ */ new Map(), this.debounceMs = e;
|
|
18
|
+
}
|
|
19
|
+
/** Run sync validators for a single field; returns list of error messages */
|
|
20
|
+
validateField(e, r, s) {
|
|
21
|
+
const i = [];
|
|
22
|
+
if (e.required) {
|
|
23
|
+
const n = y(r);
|
|
24
|
+
n && i.push(n);
|
|
25
|
+
}
|
|
26
|
+
for (const n of e.validators ?? []) {
|
|
27
|
+
const o = n(r, s);
|
|
28
|
+
o && i.push(o);
|
|
29
|
+
}
|
|
30
|
+
return i;
|
|
31
|
+
}
|
|
32
|
+
/** Run all sync validators across all visible fields */
|
|
33
|
+
validateAll(e, r) {
|
|
34
|
+
const s = {};
|
|
35
|
+
return this.collectErrors(e, r, s), s;
|
|
36
|
+
}
|
|
37
|
+
collectErrors(e, r, s) {
|
|
38
|
+
for (const i of e) {
|
|
39
|
+
const n = p(r, i.name), o = this.validateField(i, n, r);
|
|
40
|
+
o.length && (s[i.name] = o), (i.type === "group" || i.type === "array") && i.fields && this.collectErrors(i.fields, r, s);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Run async validators with debounce; calls onResult when done */
|
|
44
|
+
validateAsync(e, r, s, i) {
|
|
45
|
+
var l;
|
|
46
|
+
if (!((l = e.asyncValidators) != null && l.length)) return;
|
|
47
|
+
const n = this.asyncTimers.get(e.name);
|
|
48
|
+
n && clearTimeout(n);
|
|
49
|
+
const o = setTimeout(async () => {
|
|
50
|
+
const c = (await Promise.all(
|
|
51
|
+
e.asyncValidators.map((u) => u(r, s))
|
|
52
|
+
)).filter((u) => u !== null);
|
|
53
|
+
i(e.name, c), this.asyncTimers.delete(e.name);
|
|
54
|
+
}, this.debounceMs);
|
|
55
|
+
this.asyncTimers.set(e.name, o);
|
|
56
|
+
}
|
|
57
|
+
destroy() {
|
|
58
|
+
for (const e of this.asyncTimers.values()) clearTimeout(e);
|
|
59
|
+
this.asyncTimers.clear();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function p(t, e) {
|
|
63
|
+
return e.split(".").reduce((r, s) => {
|
|
64
|
+
if (r && typeof r == "object") return r[s];
|
|
65
|
+
}, t);
|
|
66
|
+
}
|
|
67
|
+
function P(t, e, r) {
|
|
68
|
+
const s = e.split("."), i = { ...t };
|
|
69
|
+
let n = i;
|
|
70
|
+
for (let o = 0; o < s.length - 1; o++) {
|
|
71
|
+
const l = s[o];
|
|
72
|
+
n[l] = n[l] && typeof n[l] == "object" ? { ...n[l] } : {}, n = n[l];
|
|
73
|
+
}
|
|
74
|
+
return n[s[s.length - 1]] = r, i;
|
|
75
|
+
}
|
|
76
|
+
const A = {
|
|
77
|
+
"phone-ru": "+7 (###) ###-##-##",
|
|
78
|
+
"phone-eu": "+## (##) ###-##-##",
|
|
79
|
+
date: "##.##.####",
|
|
80
|
+
inn: "############",
|
|
81
|
+
iban: "AA## #### #### #### #### #### ####"
|
|
82
|
+
};
|
|
83
|
+
function m(t) {
|
|
84
|
+
return t.preset ? A[t.preset] : t.pattern ?? "";
|
|
85
|
+
}
|
|
86
|
+
function f(t) {
|
|
87
|
+
return t === "#" || t === "A";
|
|
88
|
+
}
|
|
89
|
+
function h(t, e) {
|
|
90
|
+
return e === "#" ? /\d/.test(t) : e === "A" ? /[a-zA-Z]/.test(t) : !1;
|
|
91
|
+
}
|
|
92
|
+
function d(t, e) {
|
|
93
|
+
const s = m(typeof e == "string" ? { pattern: e } : e);
|
|
94
|
+
if (!s) return t;
|
|
95
|
+
const i = Array.from(t);
|
|
96
|
+
let n = 0, o = -1;
|
|
97
|
+
for (let a = 0; a < s.length && n < i.length; a++) {
|
|
98
|
+
const c = s[a];
|
|
99
|
+
if (f(c)) {
|
|
100
|
+
for (; n < i.length && !h(i[n], c); ) n++;
|
|
101
|
+
n < i.length && (o = a, n++);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (o === -1) return "";
|
|
105
|
+
let l = "";
|
|
106
|
+
n = 0;
|
|
107
|
+
for (let a = 0; a <= o; a++) {
|
|
108
|
+
const c = s[a];
|
|
109
|
+
if (f(c)) {
|
|
110
|
+
for (; n < i.length && !h(i[n], c); ) n++;
|
|
111
|
+
n < i.length && (l += c === "A" ? i[n++].toUpperCase() : i[n++]);
|
|
112
|
+
} else
|
|
113
|
+
l += c;
|
|
114
|
+
}
|
|
115
|
+
return l;
|
|
116
|
+
}
|
|
117
|
+
function g(t, e) {
|
|
118
|
+
const s = m(typeof e == "string" ? { pattern: e } : e);
|
|
119
|
+
if (!s) return t;
|
|
120
|
+
const i = [];
|
|
121
|
+
let n = 0;
|
|
122
|
+
for (let o = 0; o < s.length && n < t.length; o++) {
|
|
123
|
+
const l = s[o], a = t[n];
|
|
124
|
+
f(l) ? (i.push(a), n++) : a === l && n++;
|
|
125
|
+
}
|
|
126
|
+
return i.join("");
|
|
127
|
+
}
|
|
128
|
+
function S(t, e) {
|
|
129
|
+
function r() {
|
|
130
|
+
const i = g(t.value, e), n = d(i, e);
|
|
131
|
+
if (t.value !== n) {
|
|
132
|
+
const o = t.selectionStart ?? n.length;
|
|
133
|
+
t.value = n;
|
|
134
|
+
const l = Math.min(o, n.length);
|
|
135
|
+
t.setSelectionRange(l, l);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
t.addEventListener("input", r);
|
|
139
|
+
const s = d(g(t.value, e), e);
|
|
140
|
+
return t.value !== s && s && (t.value = s), () => t.removeEventListener("input", r);
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
w as V,
|
|
144
|
+
d as a,
|
|
145
|
+
S as b,
|
|
146
|
+
T as c,
|
|
147
|
+
v as d,
|
|
148
|
+
b as e,
|
|
149
|
+
M as f,
|
|
150
|
+
p as g,
|
|
151
|
+
y as h,
|
|
152
|
+
x as m,
|
|
153
|
+
I as p,
|
|
154
|
+
g as r,
|
|
155
|
+
P as s,
|
|
156
|
+
E as u
|
|
157
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const m=t=>t==null||t===""||Array.isArray(t)&&t.length===0?"This field is required":null,A=(t,e)=>r=>typeof r!="string"&&!Array.isArray(r)||r.length>=t?null:e??`Minimum length is ${t}`,M=(t,e)=>r=>typeof r!="string"&&!Array.isArray(r)||r.length<=t?null:e??`Maximum length is ${t}`,v=(t,e)=>r=>{const s=Number(r);return isNaN(s)||s>=t?null:e??`Minimum value is ${t}`},T=(t,e)=>r=>{const s=Number(r);return isNaN(s)||s<=t?null:e??`Maximum value is ${t}`},x=(t,e)=>r=>typeof r!="string"||t.test(r)?null:e??"Invalid format",E=t=>t?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(t))?null:"Invalid email address":null,I=t=>{if(!t)return null;try{return new URL(String(t)),null}catch{return"Invalid URL"}};class b{constructor(e=300){this.asyncTimers=new Map,this.debounceMs=e}validateField(e,r,s){const i=[];if(e.required){const n=m(r);n&&i.push(n)}for(const n of e.validators??[]){const o=n(r,s);o&&i.push(o)}return i}validateAll(e,r){const s={};return this.collectErrors(e,r,s),s}collectErrors(e,r,s){for(const i of e){const n=y(r,i.name),o=this.validateField(i,n,r);o.length&&(s[i.name]=o),(i.type==="group"||i.type==="array")&&i.fields&&this.collectErrors(i.fields,r,s)}}validateAsync(e,r,s,i){var l;if(!((l=e.asyncValidators)!=null&&l.length))return;const n=this.asyncTimers.get(e.name);n&&clearTimeout(n);const o=setTimeout(async()=>{const c=(await Promise.all(e.asyncValidators.map(u=>u(r,s)))).filter(u=>u!==null);i(e.name,c),this.asyncTimers.delete(e.name)},this.debounceMs);this.asyncTimers.set(e.name,o)}destroy(){for(const e of this.asyncTimers.values())clearTimeout(e);this.asyncTimers.clear()}}function y(t,e){return e.split(".").reduce((r,s)=>{if(r&&typeof r=="object")return r[s]},t)}function P(t,e,r){const s=e.split("."),i={...t};let n=i;for(let o=0;o<s.length-1;o++){const l=s[o];n[l]=n[l]&&typeof n[l]=="object"?{...n[l]}:{},n=n[l]}return n[s[s.length-1]]=r,i}const w={"phone-ru":"+7 (###) ###-##-##","phone-eu":"+## (##) ###-##-##",date:"##.##.####",inn:"############",iban:"AA## #### #### #### #### #### ####"};function p(t){return t.preset?w[t.preset]:t.pattern??""}function f(t){return t==="#"||t==="A"}function g(t,e){return e==="#"?/\d/.test(t):e==="A"?/[a-zA-Z]/.test(t):!1}function h(t,e){const s=p(typeof e=="string"?{pattern:e}:e);if(!s)return t;const i=Array.from(t);let n=0,o=-1;for(let a=0;a<s.length&&n<i.length;a++){const c=s[a];if(f(c)){for(;n<i.length&&!g(i[n],c);)n++;n<i.length&&(o=a,n++)}}if(o===-1)return"";let l="";n=0;for(let a=0;a<=o;a++){const c=s[a];if(f(c)){for(;n<i.length&&!g(i[n],c);)n++;n<i.length&&(l+=c==="A"?i[n++].toUpperCase():i[n++])}else l+=c}return l}function d(t,e){const s=p(typeof e=="string"?{pattern:e}:e);if(!s)return t;const i=[];let n=0;for(let o=0;o<s.length&&n<t.length;o++){const l=s[o],a=t[n];f(l)?(i.push(a),n++):a===l&&n++}return i.join("")}function L(t,e){function r(){const i=d(t.value,e),n=h(i,e);if(t.value!==n){const o=t.selectionStart??n.length;t.value=n;const l=Math.min(o,n.length);t.setSelectionRange(l,l)}}t.addEventListener("input",r);const s=h(d(t.value,e),e);return t.value!==s&&s&&(t.value=s),()=>t.removeEventListener("input",r)}exports.ValidationEngine=b;exports.applyMask=h;exports.bindMask=L;exports.email=E;exports.getByPath=y;exports.max=T;exports.maxLength=M;exports.min=v;exports.minLength=A;exports.pattern=x;exports.removeMask=d;exports.required=m;exports.setByPath=P;exports.url=I;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConditionEvaluator.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ConditionEvaluator.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaskEngine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/MaskEngine.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationEngine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ValidationEngine.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsers.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/parsers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForm.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/useForm.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import type { FieldDefinition } from './types';
|
|
3
|
+
export declare class ConditionEvaluator {
|
|
4
|
+
private stopHandle;
|
|
5
|
+
/**
|
|
6
|
+
* Start reactively watching values and writing evaluated fields into
|
|
7
|
+
* `resolvedFields`. Also handles clearOnHide side effect.
|
|
8
|
+
*/
|
|
9
|
+
start(rawFields: FieldDefinition[], values: Ref<Record<string, unknown>>, resolvedFields: Ref<FieldDefinition[]>, clearOnHide: boolean): void;
|
|
10
|
+
stop(): void;
|
|
11
|
+
/** Recursively evaluate visible/disabled/required for each field */
|
|
12
|
+
evaluateFields(fields: FieldDefinition[], values: Record<string, unknown>): FieldDefinition[];
|
|
13
|
+
private resolveBoolean;
|
|
14
|
+
private clearHiddenValues;
|
|
15
|
+
private wasVisible;
|
|
16
|
+
}
|
|
17
|
+
export declare function evaluateFieldConditions(fields: FieldDefinition[], values: Record<string, unknown>): FieldDefinition[];
|
|
18
|
+
//# sourceMappingURL=ConditionEvaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConditionEvaluator.d.ts","sourceRoot":"","sources":["../../src/core/ConditionEvaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAsB9C,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,UAAU,CAA4B;IAE9C;;;OAGG;IACH,KAAK,CACH,SAAS,EAAE,eAAe,EAAE,EAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACpC,cAAc,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,EACtC,WAAW,EAAE,OAAO;IAgBtB,IAAI;IAKJ,oEAAoE;IACpE,cAAc,CACZ,MAAM,EAAE,eAAe,EAAE,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,eAAe,EAAE;IAiBpB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IA2BzB,OAAO,CAAC,UAAU;CAKnB;AAID,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,eAAe,EAAE,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,eAAe,EAAE,CAGnB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { MaskConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Apply mask to a *raw* input (no existing literals).
|
|
4
|
+
* '#' = digit, 'A' = letter (uppercased), other mask chars are literals.
|
|
5
|
+
*
|
|
6
|
+
* Output extends only up to the last successfully filled placeholder —
|
|
7
|
+
* no trailing literals are appended.
|
|
8
|
+
*/
|
|
9
|
+
export declare function applyMask(value: string, mask: string | MaskConfig): string;
|
|
10
|
+
/**
|
|
11
|
+
* Remove mask formatting from a *masked* string, returning only the raw chars
|
|
12
|
+
* that were placed in placeholder (#/A) slots.
|
|
13
|
+
* Works positionally: aligns each value character against the pattern.
|
|
14
|
+
*/
|
|
15
|
+
export declare function removeMask(value: string, mask: string | MaskConfig): string;
|
|
16
|
+
/**
|
|
17
|
+
* Attach mask handling to a native <input> element.
|
|
18
|
+
* Returns a cleanup function.
|
|
19
|
+
*/
|
|
20
|
+
export declare function bindMask(input: HTMLInputElement, mask: string | MaskConfig): () => void;
|
|
21
|
+
//# sourceMappingURL=MaskEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaskEngine.d.ts","sourceRoot":"","sources":["../../src/core/MaskEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,SAAS,CAAA;AA+BrD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAyC1E;AAID;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAwB3E;AAID;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,GAAG,UAAU,GACxB,MAAM,IAAI,CAiBZ"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FieldDefinition, ValidatorFn } from './types';
|
|
2
|
+
export declare const required: ValidatorFn;
|
|
3
|
+
export declare const minLength: (min: number, message?: string) => ValidatorFn;
|
|
4
|
+
export declare const maxLength: (max: number, message?: string) => ValidatorFn;
|
|
5
|
+
export declare const min: (minVal: number, message?: string) => ValidatorFn;
|
|
6
|
+
export declare const max: (maxVal: number, message?: string) => ValidatorFn;
|
|
7
|
+
export declare const pattern: (regex: RegExp, message?: string) => ValidatorFn;
|
|
8
|
+
export declare const email: ValidatorFn;
|
|
9
|
+
export declare const url: ValidatorFn;
|
|
10
|
+
export declare class ValidationEngine {
|
|
11
|
+
private asyncTimers;
|
|
12
|
+
private readonly debounceMs;
|
|
13
|
+
constructor(debounceMs?: number);
|
|
14
|
+
/** Run sync validators for a single field; returns list of error messages */
|
|
15
|
+
validateField(field: FieldDefinition, value: unknown, allValues: Record<string, unknown>): string[];
|
|
16
|
+
/** Run all sync validators across all visible fields */
|
|
17
|
+
validateAll(fields: FieldDefinition[], values: Record<string, unknown>): Record<string, string[]>;
|
|
18
|
+
private collectErrors;
|
|
19
|
+
/** Run async validators with debounce; calls onResult when done */
|
|
20
|
+
validateAsync(field: FieldDefinition, value: unknown, allValues: Record<string, unknown>, onResult: (path: string, errors: string[]) => void): void;
|
|
21
|
+
destroy(): void;
|
|
22
|
+
}
|
|
23
|
+
export declare function getByPath(obj: Record<string, unknown>, path: string): unknown;
|
|
24
|
+
export declare function setByPath(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>;
|
|
25
|
+
//# sourceMappingURL=ValidationEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationEngine.d.ts","sourceRoot":"","sources":["../../src/core/ValidationEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAoB,MAAM,SAAS,CAAA;AAI7E,eAAO,MAAM,QAAQ,EAAE,WAItB,CAAA;AAED,eAAO,MAAM,SAAS,GACnB,KAAK,MAAM,EAAE,UAAU,MAAM,KAAG,WAMhC,CAAA;AAEH,eAAO,MAAM,SAAS,GACnB,KAAK,MAAM,EAAE,UAAU,MAAM,KAAG,WAMhC,CAAA;AAEH,eAAO,MAAM,GAAG,GACb,QAAQ,MAAM,EAAE,UAAU,MAAM,KAAG,WAKnC,CAAA;AAEH,eAAO,MAAM,GAAG,GACb,QAAQ,MAAM,EAAE,UAAU,MAAM,KAAG,WAKnC,CAAA;AAEH,eAAO,MAAM,OAAO,GACjB,OAAO,MAAM,EAAE,UAAU,MAAM,KAAG,WAIlC,CAAA;AAEH,eAAO,MAAM,KAAK,EAAE,WAInB,CAAA;AAED,eAAO,MAAM,GAAG,EAAE,WAQjB,CAAA;AAID,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAmD;IACtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;gBAEvB,UAAU,SAAM;IAI5B,6EAA6E;IAC7E,aAAa,CACX,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,EAAE;IAgBX,wDAAwD;IACxD,WAAW,CACT,MAAM,EAAE,eAAe,EAAE,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAM3B,OAAO,CAAC,aAAa;IAgBrB,mEAAmE;IACnE,aAAa,CACX,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,GACjD,IAAI;IAkBP,OAAO;CAIR;AAID,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK7E;AAED,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export type ValidatorFn = (value: unknown, values: Record<string, unknown>) => string | null;
|
|
2
|
+
export type AsyncValidatorFn = (value: unknown, values: Record<string, unknown>) => Promise<string | null>;
|
|
3
|
+
export type MaskPreset = 'phone-ru' | 'phone-eu' | 'date' | 'inn' | 'iban';
|
|
4
|
+
export interface MaskConfig {
|
|
5
|
+
preset?: MaskPreset;
|
|
6
|
+
/** Custom mask pattern: '#' = digit, 'A' = letter, other chars are literals */
|
|
7
|
+
pattern?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface FieldOption {
|
|
10
|
+
label: string;
|
|
11
|
+
value: unknown;
|
|
12
|
+
}
|
|
13
|
+
export type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group';
|
|
14
|
+
export interface FieldDefinition {
|
|
15
|
+
type: FieldType;
|
|
16
|
+
/** Dot-path for nested fields, e.g. "address.city" */
|
|
17
|
+
name: string;
|
|
18
|
+
label?: string;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
defaultValue?: unknown;
|
|
21
|
+
required?: boolean;
|
|
22
|
+
/** Static or dynamic disabled state */
|
|
23
|
+
disabled?: boolean | ((values: Record<string, unknown>) => boolean);
|
|
24
|
+
/** Static or dynamic visibility; string is evaluated as expression */
|
|
25
|
+
visible?: boolean | string | ((values: Record<string, unknown>) => boolean);
|
|
26
|
+
validators?: ValidatorFn[];
|
|
27
|
+
asyncValidators?: AsyncValidatorFn[];
|
|
28
|
+
mask?: string | MaskConfig;
|
|
29
|
+
/** For select / radio */
|
|
30
|
+
options?: FieldOption[];
|
|
31
|
+
/** For group and array */
|
|
32
|
+
fields?: FieldDefinition[];
|
|
33
|
+
}
|
|
34
|
+
export interface JSONSchemaField {
|
|
35
|
+
type: FieldType;
|
|
36
|
+
name: string;
|
|
37
|
+
label?: string;
|
|
38
|
+
placeholder?: string;
|
|
39
|
+
default?: unknown;
|
|
40
|
+
required?: boolean;
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
visible?: boolean | string;
|
|
43
|
+
options?: FieldOption[];
|
|
44
|
+
fields?: JSONSchemaField[];
|
|
45
|
+
mask?: string | MaskConfig;
|
|
46
|
+
validators?: Array<{
|
|
47
|
+
rule: string;
|
|
48
|
+
value?: unknown;
|
|
49
|
+
message?: string;
|
|
50
|
+
}>;
|
|
51
|
+
}
|
|
52
|
+
export type JSONSchema = JSONSchemaField[];
|
|
53
|
+
export type ValidateOn = 'input' | 'blur' | 'submit';
|
|
54
|
+
export interface UseFormConfig<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
55
|
+
schema: FieldDefinition[] | JSONSchema;
|
|
56
|
+
initialValues?: Partial<T>;
|
|
57
|
+
validateOn?: ValidateOn;
|
|
58
|
+
clearOnHide?: boolean;
|
|
59
|
+
onSubmit?: (values: T) => void | Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
62
|
+
export interface UseFormReturn<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
63
|
+
fields: ComputedRef<FieldDefinition[]>;
|
|
64
|
+
values: Ref<T>;
|
|
65
|
+
errors: Ref<Record<string, string[]>>;
|
|
66
|
+
touched: Ref<Record<string, boolean>>;
|
|
67
|
+
isDirty: ComputedRef<boolean>;
|
|
68
|
+
isValid: ComputedRef<boolean>;
|
|
69
|
+
isSubmitting: Ref<boolean>;
|
|
70
|
+
submit(): Promise<void>;
|
|
71
|
+
reset(values?: Partial<T>): void;
|
|
72
|
+
setField(path: string, value: unknown): void;
|
|
73
|
+
getField(path: string): unknown;
|
|
74
|
+
}
|
|
75
|
+
export type BuiltinRule = 'required' | 'minLength' | 'maxLength' | 'min' | 'max' | 'pattern' | 'email' | 'url';
|
|
76
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../src/core/useForm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,aAAa,EAAE,aAAa,EAAc,MAAM,SAAS,CAAA;AAwExF,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjF,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACvB,aAAa,CAAC,CAAC,CAAC,CA6JlB"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("vue"),a=require("./MaskEngine-hd5xHed7.cjs"),j=/^[\w\s\d.'"[\]()!<>=&|?:+\-*/%]+$/;function J(l,n){if(!j.test(l))return console.warn(`[vue-form-schema] Blocked unsafe expression: "${l}"`),!0;try{return!!new Function("values",`"use strict"; return (${l})`)(n)}catch{return!0}}class V{constructor(){this.stopHandle=null}start(n,e,t,i){this.stopHandle=v.watchEffect(()=>{const c=e.value,o=t.value,u=this.evaluateFields(n,c);i&&this.clearHiddenValues(n,u,c,e,o),t.value=u})}stop(){var n;(n=this.stopHandle)==null||n.call(this),this.stopHandle=null}evaluateFields(n,e){return n.map(t=>{const i=this.resolveBoolean(t.visible,e,!0),c=this.resolveBoolean(t.disabled,e,!1);return{...t,visible:i,disabled:c,fields:t.fields?this.evaluateFields(t.fields,e):void 0}})}resolveBoolean(n,e,t){return n===void 0?t:typeof n=="boolean"?n:typeof n=="function"?n(e):typeof n=="string"?J(n,e):t}clearHiddenValues(n,e,t,i,c){for(let o=0;o<n.length;o++){const u=n[o],b=e[o],s=this.wasVisible(c,u.name),f=b.visible;if(s&&!f){const y=a.getByPath(t,u.name),p=u.defaultValue??null;y!==p&&(i.value=a.setByPath(i.value,u.name,p))}u.fields&&b.fields&&this.clearHiddenValues(u.fields,b.fields,t,i,c)}}wasVisible(n,e){const t=n.find(i=>i.name===e);return t?t.visible!==!1:!0}}function C(l,n){return new V().evaluateFields(l,n)}function T(l,n,e){switch(l){case"required":return e?(t,i)=>a.required(t)?e:null:a.required;case"minLength":return a.minLength(Number(n),e);case"maxLength":return a.maxLength(Number(n),e);case"min":return a.min(Number(n),e);case"max":return a.max(Number(n),e);case"pattern":return a.pattern(new RegExp(String(n)),e);case"email":return e?(t,i)=>a.email(t)?e:null:a.email;case"url":return e?(t,i)=>a.url(t)?e:null:a.url;default:return console.warn(`[vue-form-schema] Unknown validator rule: "${l}"`),null}}function P(l){const n=[];for(const e of l.validators??[]){const t=T(e.rule,e.value,e.message);t&&n.push(t)}return{type:l.type,name:l.name,label:l.label,placeholder:l.placeholder,defaultValue:l.default,required:l.required,disabled:l.disabled,visible:l.visible,mask:l.mask,options:l.options,validators:n.length?n:void 0,fields:l.fields?l.fields.map(P):void 0}}function k(l){return l.map(P)}function $(l){if(!Array.isArray(l)||l.length===0)return!1;for(const n of l){const e=n.validators;if(Array.isArray(e)&&e.some(t=>typeof t=="function"))return!1}return l.some(n=>{const e=n;if("default"in e)return!0;const t=e.validators;return Array.isArray(t)&&t.length>0&&typeof t[0]=="object"&&t[0]!==null&&"rule"in t[0]})}function w(l){return $(l)?k(l):l}function g(l,n={}){const e={};for(const t of l)if(t.type==="group"&&t.fields){const i=g(t.fields,n);Object.assign(e,i)}else if(t.type==="array"){const i=a.getByPath(n,t.name);e[t.name]=i??t.defaultValue??[]}else{const i=a.getByPath(n,t.name);e[t.name]=i!==void 0?i:t.defaultValue??null}for(const[t,i]of Object.entries(n))t in e||(e[t]=i);return e}function D(l){const{schema:n,initialValues:e={},validateOn:t="blur",clearOnHide:i=!1,onSubmit:c}=l,o=w(n),u=new a.ValidationEngine,b=new V,s=v.ref(g(o,e)),f=v.ref({}),y=v.ref({}),p=v.ref(!1),h=v.ref(o);b.start(o,s,h,i??!1);const O=v.computed(()=>h.value),x=v.computed(()=>{const r=g(o,e);return JSON.stringify(s.value)!==JSON.stringify(r)}),A=v.computed(()=>{const r=u.validateAll(h.value,s.value);return Object.values(r).every(d=>d.length===0)});function E(r){if(r){const d=u.validateField(r,a.getByPath(s.value,r.name),s.value);f.value={...f.value,[r.name]:d},u.validateAsync(r,a.getByPath(s.value,r.name),s.value,(m,M)=>{f.value={...f.value,[m]:[...f.value[m]??[],...M]}})}else f.value=u.validateAll(h.value,s.value)}function L(r,d){if(s.value=a.setByPath(s.value,r,d),t==="input"){const m=B(h.value,r);m&&E(m)}}function S(r){return a.getByPath(s.value,r)}function q(r){if(y.value={...y.value,[r]:!0},t==="blur"){const d=B(h.value,r);d&&E(d)}}async function N(){const r={};for(const m of h.value)F(m,r);if(y.value=r,f.value=u.validateAll(h.value,s.value),!Object.values(f.value).some(m=>m.length>0)){p.value=!0;try{await(c==null?void 0:c(s.value))}finally{p.value=!1}}}function H(r){const d=r??e;s.value=g(o,d??{}),f.value={},y.value={},p.value=!1}return v.onUnmounted(()=>{b.stop(),u.destroy()}),{fields:O,values:s,errors:f,touched:y,isDirty:x,isValid:A,isSubmitting:p,submit:N,reset:H,setField:L,getField:S,touchField:q}}function B(l,n){for(const e of l){if(e.name===n)return e;if(e.fields){const t=B(e.fields,n);if(t)return t}}}function F(l,n={}){return n[l.name]=!0,l.fields&&l.fields.forEach(e=>F(e,n)),n}exports.ValidationEngine=a.ValidationEngine;exports.applyMask=a.applyMask;exports.bindMask=a.bindMask;exports.email=a.email;exports.getByPath=a.getByPath;exports.max=a.max;exports.maxLength=a.maxLength;exports.min=a.min;exports.minLength=a.minLength;exports.pattern=a.pattern;exports.removeMask=a.removeMask;exports.required=a.required;exports.setByPath=a.setByPath;exports.url=a.url;exports.ConditionEvaluator=V;exports.evaluateFieldConditions=C;exports.parseJSON=k;exports.useForm=D;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { FieldDefinition, FieldType, FieldOption, MaskConfig, MaskPreset, ValidatorFn, AsyncValidatorFn, UseFormConfig, UseFormReturn, ValidateOn, JSONSchema, JSONSchemaField, BuiltinRule, } from './core/types';
|
|
2
|
+
export { useForm } from './core/useForm';
|
|
3
|
+
export { required, minLength, maxLength, min, max, pattern, email, url, ValidationEngine, getByPath, setByPath, } from './core/ValidationEngine';
|
|
4
|
+
export { ConditionEvaluator, evaluateFieldConditions } from './core/ConditionEvaluator';
|
|
5
|
+
export { applyMask, removeMask, bindMask } from './core/MaskEngine';
|
|
6
|
+
export { parseJSON } from './parsers/json';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,eAAe,EACf,SAAS,EACT,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,UAAU,EACV,UAAU,EACV,eAAe,EACf,WAAW,GACZ,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAGxC,OAAO,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,GAAG,EACH,GAAG,EACH,OAAO,EACP,KAAK,EACL,GAAG,EACH,gBAAgB,EAChB,SAAS,EACT,SAAS,GACV,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AAGvF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
|