@macrulez/vue-form-schema 0.1.9 → 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.
- package/README.md +461 -180
- package/dist/MaskEngine-BEXwX4BK.js +144 -0
- package/dist/MaskEngine-CPr-fSPy.cjs +1 -0
- package/dist/ValidationEngine-BC4U1ef1.js +135 -0
- package/dist/ValidationEngine-Diz-qTFs.cjs +1 -0
- package/dist/_plugin-vue_export-helper-BHFhmbuH.cjs +1 -0
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js +9 -0
- package/dist/core/ConditionEvaluator.d.ts.map +1 -1
- package/dist/core/MaskEngine.d.ts.map +1 -1
- package/dist/core/ValidationEngine.d.ts +7 -0
- package/dist/core/ValidationEngine.d.ts.map +1 -1
- package/dist/core/formRegistry.d.ts +33 -0
- package/dist/core/formRegistry.d.ts.map +1 -0
- package/dist/core/inferTypes.d.ts.map +1 -1
- package/dist/core/schemaUtils.d.ts +38 -0
- package/dist/core/schemaUtils.d.ts.map +1 -1
- package/dist/core/serverErrors.d.ts +69 -0
- package/dist/core/serverErrors.d.ts.map +1 -0
- package/dist/core/types.d.ts +12 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/useForm.d.ts +4 -1
- package/dist/core/useForm.d.ts.map +1 -1
- package/dist/core/useMultiStepForm.d.ts.map +1 -1
- package/dist/devtools/index.d.ts +26 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools.cjs +1 -0
- package/dist/devtools.d.ts +6 -0
- package/dist/devtools.js +93 -0
- package/dist/formRegistry-Bv1eaWQ-.js +31 -0
- package/dist/formRegistry-DaDmXyYY.cjs +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +393 -368
- package/dist/openapi.cjs +1 -0
- package/dist/openapi.d.ts +202 -0
- package/dist/openapi.js +118 -0
- package/dist/parsers/json.d.ts.map +1 -1
- package/dist/parsers/openapi.d.ts +139 -0
- package/dist/parsers/openapi.d.ts.map +1 -0
- package/dist/parsers/valibot.d.ts +13 -4
- package/dist/parsers/valibot.d.ts.map +1 -1
- package/dist/parsers/yup.d.ts +10 -4
- package/dist/parsers/yup.d.ts.map +1 -1
- package/dist/parsers/zod.d.ts +18 -4
- package/dist/parsers/zod.d.ts.map +1 -1
- package/dist/schemaUtils-Cc7CwGXB.cjs +1 -0
- package/dist/schemaUtils-Cvlsk24U.js +337 -0
- package/dist/style.css +1 -0
- package/dist/ui/naive/index.d.ts +11 -0
- package/dist/ui/naive/index.d.ts.map +1 -0
- package/dist/ui/primevue/index.d.ts +11 -0
- package/dist/ui/primevue/index.d.ts.map +1 -0
- package/dist/ui/shadcn/index.d.ts +11 -0
- package/dist/ui/shadcn/index.d.ts.map +1 -0
- package/dist/ui-naive.cjs +1 -0
- package/dist/ui-naive.d.ts +411 -0
- package/dist/ui-naive.js +667 -0
- package/dist/ui-primevue.cjs +1 -0
- package/dist/ui-primevue.d.ts +411 -0
- package/dist/ui-primevue.js +651 -0
- package/dist/ui-shadcn.cjs +1 -0
- package/dist/ui-shadcn.d.ts +411 -0
- package/dist/ui-shadcn.js +650 -0
- package/dist/ui-tailwind.cjs +1 -1
- package/dist/ui-tailwind.d.ts +14 -0
- package/dist/ui-tailwind.js +180 -161
- package/dist/ui.cjs +1 -1
- package/dist/ui.d.ts +14 -0
- package/dist/ui.js +130 -131
- package/dist/valibot.cjs +1 -1
- package/dist/valibot.d.ts +25 -2
- package/dist/valibot.js +47 -20
- package/dist/yup.cjs +1 -1
- package/dist/yup.d.ts +23 -3
- package/dist/yup.js +16 -15
- package/dist/zod.cjs +1 -1
- package/dist/zod.d.ts +31 -3
- package/dist/zod.js +58 -28
- package/package.json +66 -6
- package/dist/MaskEngine-DAKSNIHQ.cjs +0 -1
- package/dist/MaskEngine-mLoXKd4d.js +0 -251
package/dist/openapi.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("./ValidationEngine-Diz-qTFs.cjs");function y(e,t){if(!t.startsWith("#/"))throw new Error(`[vue-form-schema] Only local JSON pointers ("#/...") are supported, got "${t}"`);const r=t.slice(2).split("/").map(o=>decodeURIComponent(o).replace(/~1/g,"/").replace(/~0/g,"~"));let n=e;for(const o of r){if(n===null||typeof n!="object")throw new Error(`[vue-form-schema] Could not resolve JSON pointer "${t}"`);n=n[o]}if(n===null||typeof n!="object")throw new Error(`[vue-form-schema] Could not resolve JSON pointer "${t}"`);return n}function c(e,t){return e.$ref?c(y(t,e.$ref),t):e}function m(e){return Array.isArray(e)?e.find(t=>t!=="null")??e[0]:e}function b(e){if(e.enum||e.const!==void 0)return"select";switch(m(e.type)){case"string":return e.format==="email"?"email":e.format==="date"||e.format==="date-time"?"date":"text";case"number":case"integer":return"number";case"boolean":return"checkbox";case"array":return"array";case"object":return"group";default:return"text"}}function h(e,t){const r=[];return t&&r.push(p.required),typeof e.minLength=="number"&&r.push(p.minLength(e.minLength)),typeof e.maxLength=="number"&&r.push(p.maxLength(e.maxLength)),typeof e.minimum=="number"&&r.push(p.min(e.minimum)),typeof e.maximum=="number"&&r.push(p.max(e.maximum)),e.pattern&&r.push(p.pattern(new RegExp(e.pattern))),e.format==="email"&&r.push(p.email),(e.format==="uri"||e.format==="url")&&r.push(p.url),r}function l(e,t,r){const n=e.properties??{},o=new Set(e.required??[]);return Object.entries(n).map(([i,a])=>{const u=t?`${t}.${i}`:i;return g(u,a,o.has(i),r)})}function g(e,t,r,n){const o=c(t,n),i=b(o),a=o.title??e;if(i==="select"){const u=o.enum??[o.const];return{type:"select",name:e,label:a,required:r,defaultValue:o.default,options:u.map(s=>({label:String(s),value:s})),validators:h(o,r)}}if(i==="group")return{type:"group",name:e,label:a,required:r,fields:o.properties?l(o,e,n):void 0};if(i==="array"){const u=o.items?c(o.items,n):void 0,s=u&&m(u.type)==="object"&&u.properties?l(u,void 0,n):void 0;return{type:"array",name:e,label:a,required:r,defaultValue:o.default,fields:s}}return{type:i,name:e,label:a,required:r,defaultValue:o.default,validators:h(o,r)}}function v(e,t){const r=t??e,n=c(e,r),o=m(n.type);if(o!==void 0&&o!=="object")throw new Error('[vue-form-schema] parseJSONSchema expects an object schema (type: "object")');if(!n.properties)throw new Error('[vue-form-schema] parseJSONSchema expects a schema with "properties"');return l(n,void 0,r)}function S(e,t){const r=(t.method??"post").toLowerCase(),n=t.contentType??"application/json",o=e.paths,i=o==null?void 0:o[t.path],a=i==null?void 0:i[r],u=a==null?void 0:a.requestBody,s=u==null?void 0:u.content,f=s==null?void 0:s[n],d=f==null?void 0:f.schema;if(!d)throw new Error(`[vue-form-schema] Could not find a request body schema for ${r.toUpperCase()} "${t.path}" (${n})`);return d}function w(e,t){const r=typeof t=="string"?y(e,t):S(e,t);return v(r,e)}exports.parseJSONSchema=v;exports.parseOpenAPI=w;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { Component } from 'vue';
|
|
2
|
+
|
|
3
|
+
declare type AsyncValidatorFn = (value: unknown, values: Record<string, unknown>) => Promise<string | null>;
|
|
4
|
+
|
|
5
|
+
declare interface FieldDefinition {
|
|
6
|
+
type: FieldType;
|
|
7
|
+
/** Dot-path for nested fields, e.g. "address.city" */
|
|
8
|
+
name: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
defaultValue?: unknown | ((values: Record<string, unknown>) => unknown);
|
|
12
|
+
required?: boolean;
|
|
13
|
+
/** Static or dynamic disabled state */
|
|
14
|
+
disabled?: boolean | ((values: Record<string, unknown>) => boolean);
|
|
15
|
+
/** Static or dynamic visibility; string is evaluated as expression */
|
|
16
|
+
visible?: boolean | string | ((values: Record<string, unknown>) => boolean);
|
|
17
|
+
validators?: ValidatorFn[];
|
|
18
|
+
asyncValidators?: AsyncValidatorFn[];
|
|
19
|
+
mask?: string | MaskConfig;
|
|
20
|
+
/** For select / radio — static list, sync function, or async function */
|
|
21
|
+
options?: FieldOption[] | ((values: Record<string, unknown>) => FieldOption[] | Promise<FieldOption[]>);
|
|
22
|
+
/**
|
|
23
|
+
* Field names whose values trigger re-fetching of async options.
|
|
24
|
+
* Only relevant when `options` is an async function.
|
|
25
|
+
*/
|
|
26
|
+
optionsDeps?: string[];
|
|
27
|
+
/** Internal: set by useForm when async options are loading. Read-only for consumers. */
|
|
28
|
+
optionsLoading?: boolean;
|
|
29
|
+
/** For group and array */
|
|
30
|
+
fields?: FieldDefinition[];
|
|
31
|
+
/**
|
|
32
|
+
* Applied on every setField call before the value is stored.
|
|
33
|
+
* Use for trimming, type coercion, formatting, etc.
|
|
34
|
+
*/
|
|
35
|
+
transform?: (value: unknown, values: Record<string, unknown>) => unknown;
|
|
36
|
+
/**
|
|
37
|
+
* Applied at submit time to produce the final payload value.
|
|
38
|
+
* Runs after all validation passes.
|
|
39
|
+
*/
|
|
40
|
+
parse?: (raw: unknown) => unknown;
|
|
41
|
+
/**
|
|
42
|
+
* Custom Vue component to render this field.
|
|
43
|
+
* Receives FormFieldProps and must emit 'update:modelValue' and 'blur'.
|
|
44
|
+
*/
|
|
45
|
+
component?: Component | string;
|
|
46
|
+
/** Accepted file types, e.g. "image/*,.pdf" — passed to <input accept> */
|
|
47
|
+
accept?: string;
|
|
48
|
+
/** Allow selecting multiple files */
|
|
49
|
+
multiple?: boolean;
|
|
50
|
+
/** Maximum file size in bytes */
|
|
51
|
+
maxSize?: number;
|
|
52
|
+
/** Maximum number of files (only relevant when multiple=true) */
|
|
53
|
+
maxFiles?: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
declare interface FieldOption {
|
|
57
|
+
label: string;
|
|
58
|
+
value: unknown;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare type FieldType = 'text' | 'number' | 'email' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'date' | 'array' | 'group' | 'file';
|
|
62
|
+
|
|
63
|
+
/** Infers a values type from a JSON Schema object literal (best-effort — see module docs for the supported subset). */
|
|
64
|
+
export declare type InferJSONSchema<S> = InferObject<S>;
|
|
65
|
+
|
|
66
|
+
declare type InferObject<S> = S extends {
|
|
67
|
+
properties: infer P extends Record<string, unknown>;
|
|
68
|
+
} ? {
|
|
69
|
+
[K in keyof P as K extends RequiredKeys<S> ? K : never]: InferProperty<P[K]>;
|
|
70
|
+
} & {
|
|
71
|
+
[K in keyof P as K extends RequiredKeys<S> ? never : K]?: InferProperty<P[K]>;
|
|
72
|
+
} : Record<string, unknown>;
|
|
73
|
+
|
|
74
|
+
declare type InferProperty<S> = S extends {
|
|
75
|
+
enum: readonly (infer E)[];
|
|
76
|
+
} ? E : S extends {
|
|
77
|
+
const: infer C;
|
|
78
|
+
} ? C : S extends {
|
|
79
|
+
$ref: string;
|
|
80
|
+
} ? unknown : S extends {
|
|
81
|
+
type: 'string';
|
|
82
|
+
} ? string : S extends {
|
|
83
|
+
type: 'number' | 'integer';
|
|
84
|
+
} ? number : S extends {
|
|
85
|
+
type: 'boolean';
|
|
86
|
+
} ? boolean : S extends {
|
|
87
|
+
type: 'array';
|
|
88
|
+
items: infer I;
|
|
89
|
+
} ? InferProperty<I>[] : S extends {
|
|
90
|
+
type: 'object';
|
|
91
|
+
} ? InferObject<S> : unknown;
|
|
92
|
+
|
|
93
|
+
/** A full JSON Schema or OpenAPI document — used as the `$ref` resolution root. */
|
|
94
|
+
export declare type JSONSchemaDocument = Record<string, unknown>;
|
|
95
|
+
|
|
96
|
+
/** A JSON Schema object — the subset this adapter understands. */
|
|
97
|
+
export declare interface JSONSchemaObject {
|
|
98
|
+
type?: string | readonly string[];
|
|
99
|
+
properties?: Record<string, JSONSchemaObject>;
|
|
100
|
+
required?: readonly string[];
|
|
101
|
+
items?: JSONSchemaObject;
|
|
102
|
+
enum?: readonly unknown[];
|
|
103
|
+
const?: unknown;
|
|
104
|
+
format?: string;
|
|
105
|
+
title?: string;
|
|
106
|
+
description?: string;
|
|
107
|
+
minLength?: number;
|
|
108
|
+
maxLength?: number;
|
|
109
|
+
minimum?: number;
|
|
110
|
+
maximum?: number;
|
|
111
|
+
pattern?: string;
|
|
112
|
+
default?: unknown;
|
|
113
|
+
$ref?: string;
|
|
114
|
+
[key: string]: unknown;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
declare interface MaskConfig {
|
|
118
|
+
preset?: MaskPreset;
|
|
119
|
+
/** Custom mask pattern: '#' = digit, 'A' = letter, other chars are literals */
|
|
120
|
+
pattern?: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
declare type MaskPreset = 'phone-ru' | 'phone-eu' | 'date' | 'inn' | 'iban';
|
|
124
|
+
|
|
125
|
+
/** Selects an operation's JSON request body schema. */
|
|
126
|
+
export declare interface OpenAPIRequestBodySelector {
|
|
127
|
+
path: string;
|
|
128
|
+
/** @default 'post' */
|
|
129
|
+
method?: string;
|
|
130
|
+
/** @default 'application/json' */
|
|
131
|
+
contentType?: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Selects a schema by local JSON pointer, e.g. `'#/components/schemas/User'`. */
|
|
135
|
+
export declare type OpenAPISchemaSelector = string;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Parses a JSON Schema object (`{ type: 'object', properties: {...} }`) into
|
|
139
|
+
* a `FieldDefinition[]`.
|
|
140
|
+
*
|
|
141
|
+
* `$ref`s inside `schema` are resolved against `rootDocument` if given
|
|
142
|
+
* (needed when `schema` is a sub-schema extracted from a larger document,
|
|
143
|
+
* e.g. `document.components.schemas.User`), otherwise against `schema`
|
|
144
|
+
* itself (self-contained schemas with their own `$defs`/`definitions`).
|
|
145
|
+
*
|
|
146
|
+
* The return type carries a best-effort inferred value type — see the
|
|
147
|
+
* module docs for what is and isn't inferable.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* const schema = {
|
|
151
|
+
* type: 'object',
|
|
152
|
+
* properties: {
|
|
153
|
+
* name: { type: 'string', minLength: 2 },
|
|
154
|
+
* age: { type: 'integer', minimum: 0 },
|
|
155
|
+
* role: { type: 'string', enum: ['admin', 'user'] },
|
|
156
|
+
* },
|
|
157
|
+
* required: ['name', 'role'],
|
|
158
|
+
* } as const
|
|
159
|
+
*
|
|
160
|
+
* const fields = parseJSONSchema(schema)
|
|
161
|
+
* const { values } = useForm({ schema: fields })
|
|
162
|
+
*/
|
|
163
|
+
export declare function parseJSONSchema<const S extends JSONSchemaObject>(schema: S, rootDocument?: JSONSchemaDocument): TypedFieldDefinitions<InferJSONSchema<S>>;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Parses a schema out of a full OpenAPI document, either by JSON pointer
|
|
167
|
+
* (`'#/components/schemas/User'`) or by selecting an operation's JSON
|
|
168
|
+
* request body (`{ path: '/users', method: 'post' }`).
|
|
169
|
+
*
|
|
170
|
+
* Unlike `parseJSONSchema`, the extracted schema's shape isn't known
|
|
171
|
+
* statically, so the inferred value type defaults to
|
|
172
|
+
* `Record<string, unknown>` — pass an explicit type argument if you already
|
|
173
|
+
* have one generated from the OpenAPI document (e.g. via `openapi-typescript`):
|
|
174
|
+
* `parseOpenAPI<CreateUserRequest>(document, '#/components/schemas/User')`.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* const fields = parseOpenAPI(openapiDocument, '#/components/schemas/User')
|
|
178
|
+
* // or, straight from an operation's request body:
|
|
179
|
+
* const fields2 = parseOpenAPI(openapiDocument, { path: '/users', method: 'post' })
|
|
180
|
+
*/
|
|
181
|
+
export declare function parseOpenAPI<T extends Record<string, unknown> = Record<string, unknown>>(document: JSONSchemaDocument, selector: OpenAPISchemaSelector | OpenAPIRequestBodySelector): TypedFieldDefinitions<T>;
|
|
182
|
+
|
|
183
|
+
declare type RequiredKeys<S> = S extends {
|
|
184
|
+
required: readonly (infer K)[];
|
|
185
|
+
} ? K & string : never;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* A `FieldDefinition[]` returned by a schema adapter (`parseZod` / `parseYup`
|
|
189
|
+
* / `parseValibot`) that also carries the source schema's inferred value
|
|
190
|
+
* type at the type level. `useForm({ schema: parseZod(mySchema) })` then
|
|
191
|
+
* infers `T` automatically — no `useForm<Values>(...)` needed.
|
|
192
|
+
*
|
|
193
|
+
* `__inferredValues` does not exist at runtime; it is a type-only marker
|
|
194
|
+
* erased by the compiler.
|
|
195
|
+
*/
|
|
196
|
+
declare type TypedFieldDefinitions<T> = FieldDefinition[] & {
|
|
197
|
+
readonly __inferredValues?: T;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
declare type ValidatorFn = (value: unknown, values: Record<string, unknown>) => string | null;
|
|
201
|
+
|
|
202
|
+
export { }
|
package/dist/openapi.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { r as v, h as y, c as b, d as g, m as w, p as S, e as x, u as $ } from "./ValidationEngine-BC4U1ef1.js";
|
|
2
|
+
function h(e, t) {
|
|
3
|
+
if (!t.startsWith("#/"))
|
|
4
|
+
throw new Error(
|
|
5
|
+
`[vue-form-schema] Only local JSON pointers ("#/...") are supported, got "${t}"`
|
|
6
|
+
);
|
|
7
|
+
const r = t.slice(2).split("/").map((o) => decodeURIComponent(o).replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
8
|
+
let n = e;
|
|
9
|
+
for (const o of r) {
|
|
10
|
+
if (n === null || typeof n != "object")
|
|
11
|
+
throw new Error(`[vue-form-schema] Could not resolve JSON pointer "${t}"`);
|
|
12
|
+
n = n[o];
|
|
13
|
+
}
|
|
14
|
+
if (n === null || typeof n != "object")
|
|
15
|
+
throw new Error(`[vue-form-schema] Could not resolve JSON pointer "${t}"`);
|
|
16
|
+
return n;
|
|
17
|
+
}
|
|
18
|
+
function p(e, t) {
|
|
19
|
+
return e.$ref ? p(h(t, e.$ref), t) : e;
|
|
20
|
+
}
|
|
21
|
+
function l(e) {
|
|
22
|
+
return Array.isArray(e) ? e.find((t) => t !== "null") ?? e[0] : e;
|
|
23
|
+
}
|
|
24
|
+
function j(e) {
|
|
25
|
+
if (e.enum || e.const !== void 0) return "select";
|
|
26
|
+
switch (l(e.type)) {
|
|
27
|
+
case "string":
|
|
28
|
+
return e.format === "email" ? "email" : e.format === "date" || e.format === "date-time" ? "date" : "text";
|
|
29
|
+
case "number":
|
|
30
|
+
case "integer":
|
|
31
|
+
return "number";
|
|
32
|
+
case "boolean":
|
|
33
|
+
return "checkbox";
|
|
34
|
+
case "array":
|
|
35
|
+
return "array";
|
|
36
|
+
case "object":
|
|
37
|
+
return "group";
|
|
38
|
+
default:
|
|
39
|
+
return "text";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function d(e, t) {
|
|
43
|
+
const r = [];
|
|
44
|
+
return t && r.push(v), typeof e.minLength == "number" && r.push(y(e.minLength)), typeof e.maxLength == "number" && r.push(b(e.maxLength)), typeof e.minimum == "number" && r.push(g(e.minimum)), typeof e.maximum == "number" && r.push(w(e.maximum)), e.pattern && r.push(S(new RegExp(e.pattern))), e.format === "email" && r.push(x), (e.format === "uri" || e.format === "url") && r.push($), r;
|
|
45
|
+
}
|
|
46
|
+
function f(e, t, r) {
|
|
47
|
+
const n = e.properties ?? {}, o = new Set(e.required ?? []);
|
|
48
|
+
return Object.entries(n).map(([i, a]) => {
|
|
49
|
+
const u = t ? `${t}.${i}` : i;
|
|
50
|
+
return O(u, a, o.has(i), r);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function O(e, t, r, n) {
|
|
54
|
+
const o = p(t, n), i = j(o), a = o.title ?? e;
|
|
55
|
+
if (i === "select") {
|
|
56
|
+
const u = o.enum ?? [o.const];
|
|
57
|
+
return {
|
|
58
|
+
type: "select",
|
|
59
|
+
name: e,
|
|
60
|
+
label: a,
|
|
61
|
+
required: r,
|
|
62
|
+
defaultValue: o.default,
|
|
63
|
+
options: u.map((s) => ({ label: String(s), value: s })),
|
|
64
|
+
validators: d(o, r)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (i === "group")
|
|
68
|
+
return {
|
|
69
|
+
type: "group",
|
|
70
|
+
name: e,
|
|
71
|
+
label: a,
|
|
72
|
+
required: r,
|
|
73
|
+
fields: o.properties ? f(o, e, n) : void 0
|
|
74
|
+
};
|
|
75
|
+
if (i === "array") {
|
|
76
|
+
const u = o.items ? p(o.items, n) : void 0, s = u && l(u.type) === "object" && u.properties ? f(u, void 0, n) : void 0;
|
|
77
|
+
return {
|
|
78
|
+
type: "array",
|
|
79
|
+
name: e,
|
|
80
|
+
label: a,
|
|
81
|
+
required: r,
|
|
82
|
+
defaultValue: o.default,
|
|
83
|
+
fields: s
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
type: i,
|
|
88
|
+
name: e,
|
|
89
|
+
label: a,
|
|
90
|
+
required: r,
|
|
91
|
+
defaultValue: o.default,
|
|
92
|
+
validators: d(o, r)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function E(e, t) {
|
|
96
|
+
const r = t ?? e, n = p(e, r), o = l(n.type);
|
|
97
|
+
if (o !== void 0 && o !== "object")
|
|
98
|
+
throw new Error('[vue-form-schema] parseJSONSchema expects an object schema (type: "object")');
|
|
99
|
+
if (!n.properties)
|
|
100
|
+
throw new Error('[vue-form-schema] parseJSONSchema expects a schema with "properties"');
|
|
101
|
+
return f(n, void 0, r);
|
|
102
|
+
}
|
|
103
|
+
function L(e, t) {
|
|
104
|
+
const r = (t.method ?? "post").toLowerCase(), n = t.contentType ?? "application/json", o = e.paths, i = o == null ? void 0 : o[t.path], a = i == null ? void 0 : i[r], u = a == null ? void 0 : a.requestBody, s = u == null ? void 0 : u.content, c = s == null ? void 0 : s[n], m = c == null ? void 0 : c.schema;
|
|
105
|
+
if (!m)
|
|
106
|
+
throw new Error(
|
|
107
|
+
`[vue-form-schema] Could not find a request body schema for ${r.toUpperCase()} "${t.path}" (${n})`
|
|
108
|
+
);
|
|
109
|
+
return m;
|
|
110
|
+
}
|
|
111
|
+
function J(e, t) {
|
|
112
|
+
const r = typeof t == "string" ? h(e, t) : L(e, t);
|
|
113
|
+
return E(r, e);
|
|
114
|
+
}
|
|
115
|
+
export {
|
|
116
|
+
E as parseJSONSchema,
|
|
117
|
+
J as parseOpenAPI
|
|
118
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/parsers/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAgC,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/parsers/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAgC,MAAM,eAAe,CAAA;AAkE9F,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,eAAe,EAAE,CAE/D"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard JSON Schema (draft-07 / 2020-12 subset) and OpenAPI adapter —
|
|
3
|
+
* subentry-point 'vue-form-schema/openapi'.
|
|
4
|
+
*
|
|
5
|
+
* Unlike `parseJSON` (this library's own simplified flat format), this
|
|
6
|
+
* accepts a real JSON Schema object — the kind your backend already emits
|
|
7
|
+
* via OpenAPI/Swagger — and maps it to `FieldDefinition[]`.
|
|
8
|
+
*
|
|
9
|
+
* Supported subset (deliberately not the full spec):
|
|
10
|
+
* - `type`: 'object' | 'string' | 'number' | 'integer' | 'boolean' | 'array'
|
|
11
|
+
* (also a `type` array like `['string', 'null']` — the first non-'null'
|
|
12
|
+
* entry wins)
|
|
13
|
+
* - `properties` + `required` (object schemas)
|
|
14
|
+
* - `items` (array schemas — when `items` is itself an object schema with
|
|
15
|
+
* `properties`, its properties become the array field's row `fields`,
|
|
16
|
+
* using bare names as `useFieldArray` expects — see README)
|
|
17
|
+
* - `enum` / `const` → `select` field with options built from the values
|
|
18
|
+
* - `format`: 'email' → `type: 'email'`; 'date' / 'date-time' → `type:
|
|
19
|
+
* 'date'`; 'uri' / 'url' → adds the `url` validator
|
|
20
|
+
* - `minLength` / `maxLength` / `minimum` / `maximum` / `pattern`
|
|
21
|
+
* - `$ref` — local JSON pointers only (`#/...`), resolved against the
|
|
22
|
+
* document passed as `rootDocument` (or the schema itself if omitted)
|
|
23
|
+
*
|
|
24
|
+
* Not supported: `oneOf` / `anyOf` / `allOf`, `additionalProperties`,
|
|
25
|
+
* `patternProperties`, remote/external `$ref`, `exclusiveMinimum` /
|
|
26
|
+
* `exclusiveMaximum` as separate keywords, tuple-form `items` (array of
|
|
27
|
+
* schemas). Properties using any of these are mapped as a plain `text`
|
|
28
|
+
* field with no extra validation rather than throwing — the schema still
|
|
29
|
+
* parses, just without that particular constraint.
|
|
30
|
+
*/
|
|
31
|
+
import type { TypedFieldDefinitions } from '../core/types';
|
|
32
|
+
/** A JSON Schema object — the subset this adapter understands. */
|
|
33
|
+
export interface JSONSchemaObject {
|
|
34
|
+
type?: string | readonly string[];
|
|
35
|
+
properties?: Record<string, JSONSchemaObject>;
|
|
36
|
+
required?: readonly string[];
|
|
37
|
+
items?: JSONSchemaObject;
|
|
38
|
+
enum?: readonly unknown[];
|
|
39
|
+
const?: unknown;
|
|
40
|
+
format?: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
minLength?: number;
|
|
44
|
+
maxLength?: number;
|
|
45
|
+
minimum?: number;
|
|
46
|
+
maximum?: number;
|
|
47
|
+
pattern?: string;
|
|
48
|
+
default?: unknown;
|
|
49
|
+
$ref?: string;
|
|
50
|
+
[key: string]: unknown;
|
|
51
|
+
}
|
|
52
|
+
/** A full JSON Schema or OpenAPI document — used as the `$ref` resolution root. */
|
|
53
|
+
export type JSONSchemaDocument = Record<string, unknown>;
|
|
54
|
+
type InferProperty<S> = S extends {
|
|
55
|
+
enum: readonly (infer E)[];
|
|
56
|
+
} ? E : S extends {
|
|
57
|
+
const: infer C;
|
|
58
|
+
} ? C : S extends {
|
|
59
|
+
$ref: string;
|
|
60
|
+
} ? unknown : S extends {
|
|
61
|
+
type: 'string';
|
|
62
|
+
} ? string : S extends {
|
|
63
|
+
type: 'number' | 'integer';
|
|
64
|
+
} ? number : S extends {
|
|
65
|
+
type: 'boolean';
|
|
66
|
+
} ? boolean : S extends {
|
|
67
|
+
type: 'array';
|
|
68
|
+
items: infer I;
|
|
69
|
+
} ? InferProperty<I>[] : S extends {
|
|
70
|
+
type: 'object';
|
|
71
|
+
} ? InferObject<S> : unknown;
|
|
72
|
+
type RequiredKeys<S> = S extends {
|
|
73
|
+
required: readonly (infer K)[];
|
|
74
|
+
} ? K & string : never;
|
|
75
|
+
type InferObject<S> = S extends {
|
|
76
|
+
properties: infer P extends Record<string, unknown>;
|
|
77
|
+
} ? {
|
|
78
|
+
[K in keyof P as K extends RequiredKeys<S> ? K : never]: InferProperty<P[K]>;
|
|
79
|
+
} & {
|
|
80
|
+
[K in keyof P as K extends RequiredKeys<S> ? never : K]?: InferProperty<P[K]>;
|
|
81
|
+
} : Record<string, unknown>;
|
|
82
|
+
/** Infers a values type from a JSON Schema object literal (best-effort — see module docs for the supported subset). */
|
|
83
|
+
export type InferJSONSchema<S> = InferObject<S>;
|
|
84
|
+
/**
|
|
85
|
+
* Parses a JSON Schema object (`{ type: 'object', properties: {...} }`) into
|
|
86
|
+
* a `FieldDefinition[]`.
|
|
87
|
+
*
|
|
88
|
+
* `$ref`s inside `schema` are resolved against `rootDocument` if given
|
|
89
|
+
* (needed when `schema` is a sub-schema extracted from a larger document,
|
|
90
|
+
* e.g. `document.components.schemas.User`), otherwise against `schema`
|
|
91
|
+
* itself (self-contained schemas with their own `$defs`/`definitions`).
|
|
92
|
+
*
|
|
93
|
+
* The return type carries a best-effort inferred value type — see the
|
|
94
|
+
* module docs for what is and isn't inferable.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* const schema = {
|
|
98
|
+
* type: 'object',
|
|
99
|
+
* properties: {
|
|
100
|
+
* name: { type: 'string', minLength: 2 },
|
|
101
|
+
* age: { type: 'integer', minimum: 0 },
|
|
102
|
+
* role: { type: 'string', enum: ['admin', 'user'] },
|
|
103
|
+
* },
|
|
104
|
+
* required: ['name', 'role'],
|
|
105
|
+
* } as const
|
|
106
|
+
*
|
|
107
|
+
* const fields = parseJSONSchema(schema)
|
|
108
|
+
* const { values } = useForm({ schema: fields })
|
|
109
|
+
*/
|
|
110
|
+
export declare function parseJSONSchema<const S extends JSONSchemaObject>(schema: S, rootDocument?: JSONSchemaDocument): TypedFieldDefinitions<InferJSONSchema<S>>;
|
|
111
|
+
/** Selects a schema by local JSON pointer, e.g. `'#/components/schemas/User'`. */
|
|
112
|
+
export type OpenAPISchemaSelector = string;
|
|
113
|
+
/** Selects an operation's JSON request body schema. */
|
|
114
|
+
export interface OpenAPIRequestBodySelector {
|
|
115
|
+
path: string;
|
|
116
|
+
/** @default 'post' */
|
|
117
|
+
method?: string;
|
|
118
|
+
/** @default 'application/json' */
|
|
119
|
+
contentType?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Parses a schema out of a full OpenAPI document, either by JSON pointer
|
|
123
|
+
* (`'#/components/schemas/User'`) or by selecting an operation's JSON
|
|
124
|
+
* request body (`{ path: '/users', method: 'post' }`).
|
|
125
|
+
*
|
|
126
|
+
* Unlike `parseJSONSchema`, the extracted schema's shape isn't known
|
|
127
|
+
* statically, so the inferred value type defaults to
|
|
128
|
+
* `Record<string, unknown>` — pass an explicit type argument if you already
|
|
129
|
+
* have one generated from the OpenAPI document (e.g. via `openapi-typescript`):
|
|
130
|
+
* `parseOpenAPI<CreateUserRequest>(document, '#/components/schemas/User')`.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* const fields = parseOpenAPI(openapiDocument, '#/components/schemas/User')
|
|
134
|
+
* // or, straight from an operation's request body:
|
|
135
|
+
* const fields2 = parseOpenAPI(openapiDocument, { path: '/users', method: 'post' })
|
|
136
|
+
*/
|
|
137
|
+
export declare function parseOpenAPI<T extends Record<string, unknown> = Record<string, unknown>>(document: JSONSchemaDocument, selector: OpenAPISchemaSelector | OpenAPIRequestBodySelector): TypedFieldDefinitions<T>;
|
|
138
|
+
export {};
|
|
139
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/parsers/openapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
type
|
|
1
|
+
import type { TypedFieldDefinitions } from '../core/types';
|
|
2
|
+
import type { GenericSchema, InferOutput } from 'valibot';
|
|
3
3
|
/**
|
|
4
4
|
* Convert a Valibot `v.object(...)` schema into a `FieldDefinition[]`.
|
|
5
5
|
*
|
|
@@ -14,7 +14,16 @@ type ValibotSchema = any;
|
|
|
14
14
|
*
|
|
15
15
|
* const schema = v.object({ email: v.pipe(v.string(), v.email()), age: v.number() })
|
|
16
16
|
* const fields = parseValibot(schema)
|
|
17
|
+
*
|
|
18
|
+
* The return type carries the schema's inferred value type
|
|
19
|
+
* (`v.InferOutput<S>`), so `useForm({ schema: fields })` picks up fully
|
|
20
|
+
* typed `values`/`errors`/`onSubmit` without an explicit `useForm<Values>(...)`.
|
|
21
|
+
*
|
|
22
|
+
* Also accepts a `v.variant(key, [...])` schema — converted into a `select`
|
|
23
|
+
* field for the discriminator plus every variant's own fields, each only
|
|
24
|
+
* visible while the discriminator matches its variant (see
|
|
25
|
+
* `discriminatedFields`). Combine with `clearOnHide: true` on `useForm` so
|
|
26
|
+
* switching variants resets the now-hidden variant's values.
|
|
17
27
|
*/
|
|
18
|
-
export declare function parseValibot(schema:
|
|
19
|
-
export {};
|
|
28
|
+
export declare function parseValibot<S extends GenericSchema>(schema: S): TypedFieldDefinitions<InferOutput<S>>;
|
|
20
29
|
//# sourceMappingURL=valibot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"valibot.d.ts","sourceRoot":"","sources":["../../src/parsers/valibot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"valibot.d.ts","sourceRoot":"","sources":["../../src/parsers/valibot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2C,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAKnG,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAMzD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,aAAa,EAClD,MAAM,EAAE,CAAC,GACR,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAcvC"}
|
package/dist/parsers/yup.d.ts
CHANGED
|
@@ -3,8 +3,14 @@
|
|
|
3
3
|
* Yup is a peer dependency; this file does a lazy import so the core bundle
|
|
4
4
|
* is not bloated when Yup is not used.
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
7
|
-
type
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import type { TypedFieldDefinitions } from '../core/types';
|
|
7
|
+
import type { AnySchema, InferType } from 'yup';
|
|
8
|
+
/**
|
|
9
|
+
* Parses a `yup.object({...})` schema into a `FieldDefinition[]`.
|
|
10
|
+
*
|
|
11
|
+
* The return type carries the schema's inferred value type (`InferType<S>`),
|
|
12
|
+
* so `useForm({ schema: parseYup(mySchema) })` picks up fully typed
|
|
13
|
+
* `values`/`errors`/`onSubmit` without an explicit `useForm<Values>(...)`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseYup<S extends AnySchema>(schema: S): TypedFieldDefinitions<InferType<S>>;
|
|
10
16
|
//# sourceMappingURL=yup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yup.d.ts","sourceRoot":"","sources":["../../src/parsers/yup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"yup.d.ts","sourceRoot":"","sources":["../../src/parsers/yup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAe,MAAM,eAAe,CAAA;AAIxF,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AA+E/C;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAQ5F"}
|
package/dist/parsers/zod.d.ts
CHANGED
|
@@ -3,8 +3,22 @@
|
|
|
3
3
|
* Zod is a peer dependency; this file does a lazy import so the core bundle
|
|
4
4
|
* is not bloated when Zod is not used.
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
7
|
-
type
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import type { TypedFieldDefinitions } from '../core/types';
|
|
7
|
+
import type { z } from 'zod';
|
|
8
|
+
/**
|
|
9
|
+
* Parses a `z.object({...})` schema into a `FieldDefinition[]`.
|
|
10
|
+
*
|
|
11
|
+
* The return type carries the schema's inferred value type (`z.infer<S>`),
|
|
12
|
+
* so `useForm({ schema: parseZod(mySchema) })` picks up fully typed
|
|
13
|
+
* `values`/`errors`/`onSubmit` without an explicit `useForm<Values>(...)`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseZod<S extends z.ZodObject<z.ZodRawShape>>(schema: S): TypedFieldDefinitions<z.infer<S>>;
|
|
16
|
+
/**
|
|
17
|
+
* Parses a `z.discriminatedUnion(key, [...])` schema into a `FieldDefinition[]`
|
|
18
|
+
* — a `select` for the discriminator plus every variant's fields, each only
|
|
19
|
+
* visible while the discriminator matches its variant (see
|
|
20
|
+
* `discriminatedFields`). Combine with `clearOnHide: true` on `useForm` so
|
|
21
|
+
* switching variants resets the now-hidden variant's values.
|
|
22
|
+
*/
|
|
23
|
+
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>>>;
|
|
10
24
|
//# sourceMappingURL=zod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/parsers/zod.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/parsers/zod.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAe,MAAM,eAAe,CAAA;AAKxF,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAiM5B;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAC3D,MAAM,EAAE,CAAC,GACR,qBAAqB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AACpC;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,aAAa,SAAS,MAAM,EAC5B,OAAO,SAAS,SAAS,CAAC,CAAC,2BAA2B,CAAC,aAAa,CAAC,EAAE,EAEvE,MAAM,EAAE,CAAC,CAAC,qBAAqB,CAAC,aAAa,EAAE,OAAO,CAAC,GACtD,qBAAqB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const y=require("vue"),p=require("./ValidationEngine-Diz-qTFs.cjs"),m=["===","!==","==","!=","<=",">=","&&","||","(",")","[","]",".","?",":","!","<",">","+","-","*","/","%"],w=new Set(["__proto__","prototype","constructor"]);function b(i){const e=[];let t=0;for(;t<i.length;){const s=i[t];if(/\s/.test(s)){t++;continue}if(s==='"'||s==="'"){const r=s;let a=t+1,o="";for(;a<i.length&&i[a]!==r;)o+=i[a],a++;if(i[a]!==r)throw new Error("Unterminated string literal");e.push({type:"str",value:o}),t=a+1;continue}if(/[0-9]/.test(s)){let r=t;for(;r<i.length&&/[0-9.]/.test(i[r]);)r++;e.push({type:"num",value:Number(i.slice(t,r))}),t=r;continue}if(/[A-Za-z_$]/.test(s)){let r=t;for(;r<i.length&&/[A-Za-z0-9_$]/.test(i[r]);)r++;e.push({type:"ident",value:i.slice(t,r)}),t=r;continue}const n=m.find(r=>i.startsWith(r,t));if(n){e.push({type:"op",value:n}),t+=n.length;continue}throw new Error(`Unexpected character "${s}"`)}return e.push({type:"eof"}),e}class k{constructor(e,t){this.tokens=e,this.values=t,this.pos=0}parse(){const e=this.parseTernary();if(this.peek().type!=="eof")throw new Error("Unexpected trailing tokens");return e}peek(){return this.tokens[this.pos]}next(){return this.tokens[this.pos++]}isOp(e){const t=this.peek();return t.type==="op"&&t.value===e}expectOp(e){const t=this.next();if(t.type!=="op"||t.value!==e)throw new Error(`Expected "${e}"`)}parseTernary(){const e=this.parseLogicalOr();if(this.isOp("?")){this.next();const t=this.parseTernary();this.expectOp(":");const s=this.parseTernary();return e?t:s}return e}parseLogicalOr(){let e=this.parseLogicalAnd();for(;this.isOp("||");)this.next(),e=e||this.parseLogicalAnd();return e}parseLogicalAnd(){let e=this.parseEquality();for(;this.isOp("&&");)this.next(),e=e&&this.parseEquality();return e}parseEquality(){let e=this.parseRelational();for(;;){const t=this.peek();if(t.type!=="op"||!["==","!=","===","!=="].includes(t.value))break;this.next();const s=this.parseRelational();switch(t.value){case"==":e=e==s;break;case"!=":e=e!=s;break;case"===":e=e===s;break;case"!==":e=e!==s;break}}return e}parseRelational(){let e=this.parseAdditive();for(;;){const t=this.peek();if(t.type!=="op"||!["<=",">=","<",">"].includes(t.value))break;this.next();const s=this.parseAdditive();switch(t.value){case"<=":e=e<=s;break;case">=":e=e>=s;break;case"<":e=e<s;break;case">":e=e>s;break}}return e}parseAdditive(){let e=this.parseMultiplicative();for(;;){const t=this.peek();if(t.type!=="op"||!["+","-"].includes(t.value))break;this.next();const s=this.parseMultiplicative();e=t.value==="+"?e+s:e-s}return e}parseMultiplicative(){let e=this.parseUnary();for(;;){const t=this.peek();if(t.type!=="op"||!["*","/","%"].includes(t.value))break;this.next();const s=this.parseUnary();t.value==="*"?e=e*s:t.value==="/"?e=e/s:e=e%s}return e}parseUnary(){return this.isOp("!")?(this.next(),!this.parseUnary()):this.isOp("-")?(this.next(),-this.parseUnary()):this.parsePrimary()}parsePrimary(){const e=this.next();if(e.type==="num"||e.type==="str")return e.value;if(e.type==="ident"){if(e.value==="true")return!0;if(e.value==="false")return!1;if(e.value==="null")return null;if(e.value==="undefined")return;if(e.value!=="values")throw new Error(`Unknown identifier "${e.value}"`);return this.parseMemberChain(this.values)}if(e.type==="op"&&e.value==="("){const t=this.parseTernary();return this.expectOp(")"),t}throw new Error("Unexpected token")}parseMemberChain(e){let t=e;for(;;)if(this.isOp(".")){this.next();const s=this.next();if(s.type!=="ident")throw new Error("Expected property name");t=this.readProp(t,s.value)}else if(this.isOp("[")){this.next();const s=this.parseTernary();this.expectOp("]"),t=this.readProp(t,String(s))}else break;return t}readProp(e,t){if(!w.has(t)&&e!=null&&typeof e=="object")return e[t]}}function x(i,e){try{const t=b(i);return!!new k(t,e).parse()}catch{return console.warn(`[vue-form-schema] Invalid or unsupported expression: "${i}"`),!0}}class h{constructor(){this.stopHandle=null}start(e,t,s,n){this.stopHandle=y.watchEffect(()=>{const r=t.value,a=s.value,o=this.evaluateFields(e,r);n&&this.clearHiddenValues(e,o,r,t,a),s.value=o})}stop(){var e;(e=this.stopHandle)==null||e.call(this),this.stopHandle=null}evaluateFields(e,t){return e.map(s=>{const n=this.resolveBoolean(s.visible,t,!0),r=this.resolveBoolean(s.disabled,t,!1);let a;if(typeof s.options=="function"){const l=s.options(t);a=l instanceof Promise?void 0:l}else a=s.options;return{...s,visible:n,disabled:r,options:a,fields:s.fields?this.evaluateFields(s.fields,t):void 0}})}resolveBoolean(e,t,s){return e===void 0?s:typeof e=="boolean"?e:typeof e=="function"?e(t):typeof e=="string"?x(e,t):s}clearHiddenValues(e,t,s,n,r){for(let a=0;a<e.length;a++){const o=e[a],l=t[a],f=this.wasVisible(r,o.name),d=l.visible;if(f&&!d){const v=p.getByPath(s,o.name),u=o.defaultValue??null;v!==u&&(n.value=p.setByPath(n.value,o.name,u))}o.fields&&l.fields&&this.clearHiddenValues(o.fields,l.fields,s,n,r)}}wasVisible(e,t){const s=e.find(n=>n.name===t);return s?s.visible!==!1:!0}}function c(i,e){return new h().evaluateFields(i,e)}function g(...i){const e=new Map;for(const t of i)for(const s of t)e.set(s.name,s);return Array.from(e.values())}function E(i,e){const t=new Set(e);return i.filter(s=>!t.has(s.name))}function O(i,e){const t=new Set(e);return i.filter(s=>t.has(s.name))}function F(i,e,t){return i.map(s=>s.name===e?{...s,...t}:s)}function _(i,e){const t=[];for(const[s,n]of Object.entries(e))for(const r of n)t.push({...r,visible:A(r.visible,i,s)});return t}function A(i,e,t){return s=>{if(s[e]!==t)return!1;if(i===void 0)return!0;const[n]=c([{type:"text",name:"__discriminatedFields_probe__",visible:i}],s);return n.visible===!0}}exports.ConditionEvaluator=h;exports.discriminatedFields=_;exports.evaluateFieldConditions=c;exports.extendField=F;exports.mergeSchemas=g;exports.omitFields=E;exports.pickFields=O;
|