@mosaicoo/form-core 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 +37 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/interop/importer.d.ts +38 -0
- package/dist/interop/importer.d.ts.map +1 -0
- package/dist/interop/importer.js +29 -0
- package/dist/interop/importer.js.map +1 -0
- package/dist/interop/legacy/legacy-exporter.d.ts +14 -0
- package/dist/interop/legacy/legacy-exporter.d.ts.map +1 -0
- package/dist/interop/legacy/legacy-exporter.js +234 -0
- package/dist/interop/legacy/legacy-exporter.js.map +1 -0
- package/dist/interop/legacy/legacy-importer.d.ts +25 -0
- package/dist/interop/legacy/legacy-importer.d.ts.map +1 -0
- package/dist/interop/legacy/legacy-importer.js +382 -0
- package/dist/interop/legacy/legacy-importer.js.map +1 -0
- package/dist/schema/types.d.ts +181 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +9 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/schema/walk.d.ts +27 -0
- package/dist/schema/walk.d.ts.map +1 -0
- package/dist/schema/walk.js +56 -0
- package/dist/schema/walk.js.map +1 -0
- package/dist/state/engine.d.ts +93 -0
- package/dist/state/engine.d.ts.map +1 -0
- package/dist/state/engine.js +358 -0
- package/dist/state/engine.js.map +1 -0
- package/dist/util/clone.d.ts +6 -0
- package/dist/util/clone.d.ts.map +1 -0
- package/dist/util/clone.js +18 -0
- package/dist/util/clone.js.map +1 -0
- package/dist/validation/validate.d.ts +35 -0
- package/dist/validation/validate.d.ts.map +1 -0
- package/dist/validation/validate.js +113 -0
- package/dist/validation/validate.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
function joinPath(scope, key) {
|
|
2
|
+
return scope ? `${scope}.${key}` : key;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Depth-first traversal of a schema, yielding every node with its resolved
|
|
6
|
+
* data path. Layout containers pass their scope through; `nested` containers
|
|
7
|
+
* push their key onto the scope.
|
|
8
|
+
*/
|
|
9
|
+
export function* walkSchema(schema) {
|
|
10
|
+
yield* walkNodes(schema.fields, '', []);
|
|
11
|
+
}
|
|
12
|
+
function* walkNodes(nodes, scope, parents) {
|
|
13
|
+
for (const node of nodes) {
|
|
14
|
+
if (node.kind === 'input') {
|
|
15
|
+
yield { node, path: joinPath(scope, node.key), parents };
|
|
16
|
+
}
|
|
17
|
+
else if (node.kind === 'container') {
|
|
18
|
+
const ownPath = joinPath(scope, node.key);
|
|
19
|
+
const childScope = node.dataScope === 'nested'
|
|
20
|
+
? ownPath
|
|
21
|
+
: node.dataScope === 'array'
|
|
22
|
+
? `${ownPath}.*`
|
|
23
|
+
: scope;
|
|
24
|
+
yield {
|
|
25
|
+
node,
|
|
26
|
+
path: node.dataScope === 'inherit' ? scope : ownPath,
|
|
27
|
+
parents,
|
|
28
|
+
};
|
|
29
|
+
yield* walkNodes(node.children, childScope, [...parents, node]);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
yield { node, path: scope, parents };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Every input field of the schema with its data path. */
|
|
37
|
+
export function collectInputs(schema) {
|
|
38
|
+
const out = [];
|
|
39
|
+
for (const entry of walkSchema(schema)) {
|
|
40
|
+
if (entry.node.kind === 'input') {
|
|
41
|
+
out.push({ node: entry.node, path: entry.path, parents: entry.parents });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
/** Find a node by its data path (inputs) or key (containers/static). */
|
|
47
|
+
export function findByPath(schema, path) {
|
|
48
|
+
for (const entry of walkSchema(schema)) {
|
|
49
|
+
if (entry.node.kind === 'input' && entry.path === path)
|
|
50
|
+
return entry;
|
|
51
|
+
if (entry.node.kind !== 'input' && entry.node.key === path)
|
|
52
|
+
return entry;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=walk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/schema/walk.ts"],"names":[],"mappings":"AAcA,SAAS,QAAQ,CAAC,KAAa,EAAE,GAAW;IAC1C,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,SAAS,CAAC,CAAC,UAAU,CAAC,MAAkB;IAC5C,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,QAAQ,CAAC,CAAC,SAAS,CACjB,KAAkB,EAClB,KAAa,EACb,OAAoB;IAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC;QAC3D,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,UAAU,GACd,IAAI,CAAC,SAAS,KAAK,QAAQ;gBACzB,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,OAAO;oBAC1B,CAAC,CAAC,GAAG,OAAO,IAAI;oBAChB,CAAC,CAAC,KAAK,CAAC;YACd,MAAM;gBACJ,IAAI;gBACJ,IAAI,EAAE,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO;gBACpD,OAAO;aACR,CAAC;YACF,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,aAAa,CAC3B,MAAkB;IAElB,MAAM,GAAG,GAAoE,EAAE,CAAC;IAChF,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU,CACxB,MAAkB,EAClB,IAAY;IAEZ,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACrE,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;IAC3E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Condition, FormSchema } from '../schema/types.js';
|
|
2
|
+
import { type FieldError, type MessageResolver, type ValidatorRegistry } from '../validation/validate.js';
|
|
3
|
+
/** Events emitted by the engine to keep rendering layers in sync. */
|
|
4
|
+
export type EngineEvent = {
|
|
5
|
+
type: 'value-change';
|
|
6
|
+
path: string;
|
|
7
|
+
value: unknown;
|
|
8
|
+
} | {
|
|
9
|
+
type: 'touched';
|
|
10
|
+
path: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'validation';
|
|
13
|
+
errors: FieldError[];
|
|
14
|
+
} | {
|
|
15
|
+
type: 'reset';
|
|
16
|
+
};
|
|
17
|
+
export interface EngineOptions {
|
|
18
|
+
initialData?: Record<string, unknown>;
|
|
19
|
+
validators?: ValidatorRegistry;
|
|
20
|
+
messages?: MessageResolver;
|
|
21
|
+
}
|
|
22
|
+
export interface SubmitResult {
|
|
23
|
+
ok: boolean;
|
|
24
|
+
/** Data snapshot with hidden-field values stripped when `clearOnHide`. */
|
|
25
|
+
data: Record<string, unknown>;
|
|
26
|
+
errors: FieldError[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Headless form engine.
|
|
30
|
+
*
|
|
31
|
+
* Holds the data model for one schema instance: values, touched/dirty flags,
|
|
32
|
+
* conditional visibility and validation state. Rendering layers subscribe to
|
|
33
|
+
* events and project the state -- they never own it.
|
|
34
|
+
*/
|
|
35
|
+
export declare class FormEngine {
|
|
36
|
+
readonly schema: FormSchema;
|
|
37
|
+
private data;
|
|
38
|
+
private readonly initialData;
|
|
39
|
+
private readonly touchedPaths;
|
|
40
|
+
private readonly dirtyPaths;
|
|
41
|
+
private errors;
|
|
42
|
+
private readonly listeners;
|
|
43
|
+
private readonly options;
|
|
44
|
+
constructor(schema: FormSchema, options?: EngineOptions);
|
|
45
|
+
/** Deep snapshot of the current data. */
|
|
46
|
+
getData(): Record<string, unknown>;
|
|
47
|
+
getValue(path: string): unknown;
|
|
48
|
+
setValue(path: string, value: unknown): void;
|
|
49
|
+
/**
|
|
50
|
+
* Appends a row to an `array` container. Without a seed, the row is built
|
|
51
|
+
* from the template children's default values.
|
|
52
|
+
*/
|
|
53
|
+
addRow(path: string, seed?: Record<string, unknown>): void;
|
|
54
|
+
removeRow(path: string, index: number): void;
|
|
55
|
+
reset(data?: Record<string, unknown>): void;
|
|
56
|
+
markTouched(path: string): void;
|
|
57
|
+
isTouched(path: string): boolean;
|
|
58
|
+
isDirty(path?: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Whether a node is currently visible: not statically hidden, its own
|
|
61
|
+
* condition matches, and every ancestor container is visible too.
|
|
62
|
+
*/
|
|
63
|
+
isVisible(nodeKeyOrPath: string): boolean;
|
|
64
|
+
private isNodeVisible;
|
|
65
|
+
getErrors(): FieldError[];
|
|
66
|
+
getFieldErrors(path: string): FieldError[];
|
|
67
|
+
/** Validates every visible input field (array rows included). */
|
|
68
|
+
validate(): FieldError[];
|
|
69
|
+
/** Re-validates one field (concrete row paths accepted), patching in place. */
|
|
70
|
+
validateField(path: string): FieldError[];
|
|
71
|
+
/**
|
|
72
|
+
* Validates only the visible inputs inside one container (by key), patching
|
|
73
|
+
* the error list in place. Used for per-step validation in wizard forms.
|
|
74
|
+
*/
|
|
75
|
+
validateContainer(containerKey: string): FieldError[];
|
|
76
|
+
/**
|
|
77
|
+
* Validates and, when valid, returns the data ready for submission.
|
|
78
|
+
* Values of hidden fields are stripped when `settings.clearOnHide`.
|
|
79
|
+
*/
|
|
80
|
+
submit(): SubmitResult;
|
|
81
|
+
subscribe(listener: (event: EngineEvent) => void): () => void;
|
|
82
|
+
private emit;
|
|
83
|
+
private isInputVisible;
|
|
84
|
+
private runFieldValidators;
|
|
85
|
+
private buildInitialData;
|
|
86
|
+
/** Default row for an `array` container, from its template children. */
|
|
87
|
+
private buildRowDefaults;
|
|
88
|
+
/** Expands `*` segments of a path pattern against the current data. */
|
|
89
|
+
private expandPattern;
|
|
90
|
+
}
|
|
91
|
+
export declare function createFormEngine(schema: FormSchema, options?: EngineOptions): FormEngine;
|
|
92
|
+
export declare function evaluateCondition(condition: Condition, data: Record<string, unknown>): boolean;
|
|
93
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/state/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { collectInputs, walkSchema } from '../schema/walk.js';
|
|
2
|
+
import { cloneDeep } from '../util/clone.js';
|
|
3
|
+
import { defaultMessageResolver, validateFieldValue, } from '../validation/validate.js';
|
|
4
|
+
/**
|
|
5
|
+
* Headless form engine.
|
|
6
|
+
*
|
|
7
|
+
* Holds the data model for one schema instance: values, touched/dirty flags,
|
|
8
|
+
* conditional visibility and validation state. Rendering layers subscribe to
|
|
9
|
+
* events and project the state -- they never own it.
|
|
10
|
+
*/
|
|
11
|
+
export class FormEngine {
|
|
12
|
+
schema;
|
|
13
|
+
data;
|
|
14
|
+
initialData;
|
|
15
|
+
touchedPaths = new Set();
|
|
16
|
+
dirtyPaths = new Set();
|
|
17
|
+
errors = [];
|
|
18
|
+
listeners = new Set();
|
|
19
|
+
options;
|
|
20
|
+
constructor(schema, options = {}) {
|
|
21
|
+
this.schema = schema;
|
|
22
|
+
this.options = options;
|
|
23
|
+
this.data = this.buildInitialData(options.initialData);
|
|
24
|
+
this.initialData = cloneDeep(this.data);
|
|
25
|
+
}
|
|
26
|
+
// -- data -----------------------------------------------------------------
|
|
27
|
+
/** Deep snapshot of the current data. */
|
|
28
|
+
getData() {
|
|
29
|
+
return cloneDeep(this.data);
|
|
30
|
+
}
|
|
31
|
+
getValue(path) {
|
|
32
|
+
return readPath(this.data, path);
|
|
33
|
+
}
|
|
34
|
+
setValue(path, value) {
|
|
35
|
+
writePath(this.data, path, value);
|
|
36
|
+
this.dirtyPaths.add(path);
|
|
37
|
+
this.emit({ type: 'value-change', path, value });
|
|
38
|
+
// Re-validate only what already has errors so messages clear as the
|
|
39
|
+
// user fixes them, without prematurely flagging untouched fields.
|
|
40
|
+
if (this.errors.some((e) => e.path === path)) {
|
|
41
|
+
this.validateField(path);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Appends a row to an `array` container. Without a seed, the row is built
|
|
46
|
+
* from the template children's default values.
|
|
47
|
+
*/
|
|
48
|
+
addRow(path, seed) {
|
|
49
|
+
const row = seed ? cloneDeep(seed) : this.buildRowDefaults(path);
|
|
50
|
+
const current = readPath(this.data, path);
|
|
51
|
+
if (Array.isArray(current)) {
|
|
52
|
+
current.push(row);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
writePath(this.data, path, [row]);
|
|
56
|
+
}
|
|
57
|
+
this.dirtyPaths.add(path);
|
|
58
|
+
this.emit({ type: 'value-change', path, value: readPath(this.data, path) });
|
|
59
|
+
}
|
|
60
|
+
removeRow(path, index) {
|
|
61
|
+
const current = readPath(this.data, path);
|
|
62
|
+
if (!Array.isArray(current) || index < 0 || index >= current.length)
|
|
63
|
+
return;
|
|
64
|
+
current.splice(index, 1);
|
|
65
|
+
this.dirtyPaths.add(path);
|
|
66
|
+
// Drop errors bound to the removed row; a full validate() re-indexes.
|
|
67
|
+
this.errors = this.errors.filter((e) => !e.path.startsWith(`${path}.`));
|
|
68
|
+
this.emit({ type: 'value-change', path, value: readPath(this.data, path) });
|
|
69
|
+
}
|
|
70
|
+
reset(data) {
|
|
71
|
+
this.data = data ? this.buildInitialData(data) : cloneDeep(this.initialData);
|
|
72
|
+
this.touchedPaths.clear();
|
|
73
|
+
this.dirtyPaths.clear();
|
|
74
|
+
this.errors = [];
|
|
75
|
+
this.emit({ type: 'reset' });
|
|
76
|
+
}
|
|
77
|
+
// -- interaction state ----------------------------------------------------
|
|
78
|
+
markTouched(path) {
|
|
79
|
+
if (!this.touchedPaths.has(path)) {
|
|
80
|
+
this.touchedPaths.add(path);
|
|
81
|
+
this.emit({ type: 'touched', path });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
isTouched(path) {
|
|
85
|
+
return this.touchedPaths.has(path);
|
|
86
|
+
}
|
|
87
|
+
isDirty(path) {
|
|
88
|
+
return path ? this.dirtyPaths.has(path) : this.dirtyPaths.size > 0;
|
|
89
|
+
}
|
|
90
|
+
// -- visibility -----------------------------------------------------------
|
|
91
|
+
/**
|
|
92
|
+
* Whether a node is currently visible: not statically hidden, its own
|
|
93
|
+
* condition matches, and every ancestor container is visible too.
|
|
94
|
+
*/
|
|
95
|
+
isVisible(nodeKeyOrPath) {
|
|
96
|
+
const pattern = toPattern(nodeKeyOrPath);
|
|
97
|
+
for (const entry of walkSchema(this.schema)) {
|
|
98
|
+
const matches = entry.node.kind === 'input'
|
|
99
|
+
? entry.path === nodeKeyOrPath || entry.path === pattern
|
|
100
|
+
: entry.node.key === nodeKeyOrPath;
|
|
101
|
+
if (!matches)
|
|
102
|
+
continue;
|
|
103
|
+
return (this.isNodeVisible(entry.node) &&
|
|
104
|
+
entry.parents.every((parent) => this.isNodeVisible(parent)));
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
isNodeVisible(node) {
|
|
109
|
+
if (node.hidden)
|
|
110
|
+
return false;
|
|
111
|
+
if (!node.conditional)
|
|
112
|
+
return true;
|
|
113
|
+
return evaluateCondition(node.conditional, this.data);
|
|
114
|
+
}
|
|
115
|
+
// -- validation -----------------------------------------------------------
|
|
116
|
+
getErrors() {
|
|
117
|
+
return [...this.errors];
|
|
118
|
+
}
|
|
119
|
+
getFieldErrors(path) {
|
|
120
|
+
return this.errors.filter((e) => e.path === path);
|
|
121
|
+
}
|
|
122
|
+
/** Validates every visible input field (array rows included). */
|
|
123
|
+
validate() {
|
|
124
|
+
const next = [];
|
|
125
|
+
for (const { node, path, parents } of collectInputs(this.schema)) {
|
|
126
|
+
if (!this.isInputVisible(node, parents))
|
|
127
|
+
continue;
|
|
128
|
+
for (const concrete of this.expandPattern(path)) {
|
|
129
|
+
next.push(...this.runFieldValidators(node, concrete));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
this.errors = next;
|
|
133
|
+
this.emit({ type: 'validation', errors: [...next] });
|
|
134
|
+
return [...next];
|
|
135
|
+
}
|
|
136
|
+
/** Re-validates one field (concrete row paths accepted), patching in place. */
|
|
137
|
+
validateField(path) {
|
|
138
|
+
const pattern = toPattern(path);
|
|
139
|
+
const entry = collectInputs(this.schema).find((e) => e.path === pattern);
|
|
140
|
+
if (!entry)
|
|
141
|
+
return [];
|
|
142
|
+
const fieldErrors = this.isInputVisible(entry.node, entry.parents)
|
|
143
|
+
? this.runFieldValidators(entry.node, path)
|
|
144
|
+
: [];
|
|
145
|
+
this.errors = [...this.errors.filter((e) => e.path !== path), ...fieldErrors];
|
|
146
|
+
this.emit({ type: 'validation', errors: this.getErrors() });
|
|
147
|
+
return fieldErrors;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Validates only the visible inputs inside one container (by key), patching
|
|
151
|
+
* the error list in place. Used for per-step validation in wizard forms.
|
|
152
|
+
*/
|
|
153
|
+
validateContainer(containerKey) {
|
|
154
|
+
const inside = [];
|
|
155
|
+
for (const entry of collectInputs(this.schema)) {
|
|
156
|
+
if (entry.parents.some((p) => p.kind === 'container' && p.key === containerKey)) {
|
|
157
|
+
inside.push(entry);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const stepErrors = [];
|
|
161
|
+
const stepPaths = new Set();
|
|
162
|
+
for (const { node, path, parents } of inside) {
|
|
163
|
+
for (const concrete of this.expandPattern(path))
|
|
164
|
+
stepPaths.add(concrete);
|
|
165
|
+
if (!this.isInputVisible(node, parents))
|
|
166
|
+
continue;
|
|
167
|
+
for (const concrete of this.expandPattern(path)) {
|
|
168
|
+
stepErrors.push(...this.runFieldValidators(node, concrete));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
this.errors = [
|
|
172
|
+
...this.errors.filter((e) => !stepPaths.has(e.path)),
|
|
173
|
+
...stepErrors,
|
|
174
|
+
];
|
|
175
|
+
this.emit({ type: 'validation', errors: this.getErrors() });
|
|
176
|
+
return stepErrors;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Validates and, when valid, returns the data ready for submission.
|
|
180
|
+
* Values of hidden fields are stripped when `settings.clearOnHide`.
|
|
181
|
+
*/
|
|
182
|
+
submit() {
|
|
183
|
+
const errors = this.validate();
|
|
184
|
+
const data = this.getData();
|
|
185
|
+
if (this.schema.settings?.clearOnHide) {
|
|
186
|
+
for (const { node, path, parents } of collectInputs(this.schema)) {
|
|
187
|
+
if (this.isInputVisible(node, parents))
|
|
188
|
+
continue;
|
|
189
|
+
for (const concrete of this.expandPattern(path))
|
|
190
|
+
deletePath(data, concrete);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return { ok: errors.length === 0, data, errors };
|
|
194
|
+
}
|
|
195
|
+
// -- events ---------------------------------------------------------------
|
|
196
|
+
subscribe(listener) {
|
|
197
|
+
this.listeners.add(listener);
|
|
198
|
+
return () => this.listeners.delete(listener);
|
|
199
|
+
}
|
|
200
|
+
// -- internals ------------------------------------------------------------
|
|
201
|
+
emit(event) {
|
|
202
|
+
for (const listener of this.listeners)
|
|
203
|
+
listener(event);
|
|
204
|
+
}
|
|
205
|
+
isInputVisible(node, parents) {
|
|
206
|
+
return this.isNodeVisible(node) && parents.every((p) => this.isNodeVisible(p));
|
|
207
|
+
}
|
|
208
|
+
runFieldValidators(node, path) {
|
|
209
|
+
return validateFieldValue(node, path, readPath(this.data, path), this.data, {
|
|
210
|
+
registry: this.options.validators,
|
|
211
|
+
messages: this.options.messages ?? defaultMessageResolver,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
buildInitialData(seed) {
|
|
215
|
+
const data = {};
|
|
216
|
+
for (const entry of walkSchema(this.schema)) {
|
|
217
|
+
if (entry.path.includes('*'))
|
|
218
|
+
continue; // row defaults are applied per row
|
|
219
|
+
if (entry.node.kind === 'input' && entry.node.defaultValue !== undefined) {
|
|
220
|
+
writePath(data, entry.path, cloneDeep(entry.node.defaultValue));
|
|
221
|
+
}
|
|
222
|
+
else if (entry.node.kind === 'container' && entry.node.dataScope === 'array') {
|
|
223
|
+
writePath(data, entry.path, cloneDeep(entry.node.defaultRows ?? [{}]));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (seed)
|
|
227
|
+
mergeDeep(data, cloneDeep(seed));
|
|
228
|
+
return data;
|
|
229
|
+
}
|
|
230
|
+
/** Default row for an `array` container, from its template children. */
|
|
231
|
+
buildRowDefaults(path) {
|
|
232
|
+
const row = {};
|
|
233
|
+
for (const entry of walkSchema(this.schema)) {
|
|
234
|
+
if (entry.node.kind !== 'container' ||
|
|
235
|
+
entry.node.dataScope !== 'array' ||
|
|
236
|
+
entry.path !== toPattern(path)) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const template = { version: 1, fields: entry.node.children };
|
|
240
|
+
for (const child of collectInputs(template)) {
|
|
241
|
+
if (child.path.includes('*'))
|
|
242
|
+
continue;
|
|
243
|
+
if (child.node.defaultValue !== undefined) {
|
|
244
|
+
writePath(row, child.path, cloneDeep(child.node.defaultValue));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
return row;
|
|
250
|
+
}
|
|
251
|
+
/** Expands `*` segments of a path pattern against the current data. */
|
|
252
|
+
expandPattern(pattern) {
|
|
253
|
+
if (!pattern.includes('*'))
|
|
254
|
+
return [pattern];
|
|
255
|
+
let paths = [''];
|
|
256
|
+
for (const part of pattern.split('.')) {
|
|
257
|
+
if (part === '*') {
|
|
258
|
+
const next = [];
|
|
259
|
+
for (const prefix of paths) {
|
|
260
|
+
const value = readPath(this.data, prefix);
|
|
261
|
+
const length = Array.isArray(value) ? value.length : 0;
|
|
262
|
+
for (let i = 0; i < length; i++) {
|
|
263
|
+
next.push(prefix ? `${prefix}.${i}` : String(i));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
paths = next;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
paths = paths.map((prefix) => (prefix ? `${prefix}.${part}` : part));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return paths;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/** Replaces numeric path segments with `*` to match template patterns. */
|
|
276
|
+
function toPattern(path) {
|
|
277
|
+
return path
|
|
278
|
+
.split('.')
|
|
279
|
+
.map((part) => (/^\d+$/.test(part) ? '*' : part))
|
|
280
|
+
.join('.');
|
|
281
|
+
}
|
|
282
|
+
export function createFormEngine(schema, options) {
|
|
283
|
+
return new FormEngine(schema, options);
|
|
284
|
+
}
|
|
285
|
+
// -- condition evaluation ---------------------------------------------------
|
|
286
|
+
export function evaluateCondition(condition, data) {
|
|
287
|
+
const observed = readPath(data, condition.field);
|
|
288
|
+
let matches;
|
|
289
|
+
if (observed !== null &&
|
|
290
|
+
typeof observed === 'object' &&
|
|
291
|
+
!Array.isArray(observed) &&
|
|
292
|
+
typeof condition.value === 'string') {
|
|
293
|
+
// Choice-map values ({ red: true }) match when the named option is set.
|
|
294
|
+
matches = Boolean(observed[condition.value]);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
matches = looseEquals(observed, condition.value);
|
|
298
|
+
}
|
|
299
|
+
if (condition.op === 'neq')
|
|
300
|
+
matches = !matches;
|
|
301
|
+
return condition.show ? matches : !matches;
|
|
302
|
+
}
|
|
303
|
+
function looseEquals(a, b) {
|
|
304
|
+
if (a === b)
|
|
305
|
+
return true;
|
|
306
|
+
// Schema conditions are authored as strings; tolerate number/boolean data.
|
|
307
|
+
return a !== undefined && a !== null && b !== undefined && b !== null &&
|
|
308
|
+
String(a) === String(b);
|
|
309
|
+
}
|
|
310
|
+
// -- path helpers -----------------------------------------------------------
|
|
311
|
+
function readPath(data, path) {
|
|
312
|
+
let cursor = data;
|
|
313
|
+
for (const part of path.split('.')) {
|
|
314
|
+
if (cursor === null || typeof cursor !== 'object')
|
|
315
|
+
return undefined;
|
|
316
|
+
cursor = cursor[part];
|
|
317
|
+
}
|
|
318
|
+
return cursor;
|
|
319
|
+
}
|
|
320
|
+
function writePath(data, path, value) {
|
|
321
|
+
const parts = path.split('.');
|
|
322
|
+
let cursor = data;
|
|
323
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
324
|
+
const part = parts[i];
|
|
325
|
+
const next = cursor[part];
|
|
326
|
+
if (next === null || typeof next !== 'object') {
|
|
327
|
+
// Create an array when the next segment is a row index.
|
|
328
|
+
cursor[part] = /^\d+$/.test(parts[i + 1]) ? [] : {};
|
|
329
|
+
}
|
|
330
|
+
cursor = cursor[part];
|
|
331
|
+
}
|
|
332
|
+
cursor[parts[parts.length - 1]] = value;
|
|
333
|
+
}
|
|
334
|
+
function deletePath(data, path) {
|
|
335
|
+
const parts = path.split('.');
|
|
336
|
+
let cursor = data;
|
|
337
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
338
|
+
if (cursor === null || typeof cursor !== 'object')
|
|
339
|
+
return;
|
|
340
|
+
cursor = cursor[parts[i]];
|
|
341
|
+
}
|
|
342
|
+
if (cursor !== null && typeof cursor === 'object') {
|
|
343
|
+
delete cursor[parts[parts.length - 1]];
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function mergeDeep(target, source) {
|
|
347
|
+
for (const [key, value] of Object.entries(source)) {
|
|
348
|
+
const existing = target[key];
|
|
349
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value) &&
|
|
350
|
+
existing !== null && typeof existing === 'object' && !Array.isArray(existing)) {
|
|
351
|
+
mergeDeep(existing, value);
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
target[key] = value;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/state/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone.d.ts","sourceRoot":"","sources":["../../src/util/clone.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CASxC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep clone for form data values (JSON-like structures plus Date).
|
|
3
|
+
* Kept dependency- and host-global-free so the core runs anywhere.
|
|
4
|
+
*/
|
|
5
|
+
export function cloneDeep(value) {
|
|
6
|
+
if (value === null || typeof value !== 'object')
|
|
7
|
+
return value;
|
|
8
|
+
if (value instanceof Date)
|
|
9
|
+
return new Date(value.getTime());
|
|
10
|
+
if (Array.isArray(value))
|
|
11
|
+
return value.map((item) => cloneDeep(item));
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
14
|
+
out[key] = cloneDeep(entry);
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=clone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/util/clone.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAI,KAAQ;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAM,CAAC;IACjE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAM,CAAC;IAC3E,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,GAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { InputField, ValidatorSpec } from '../schema/types.js';
|
|
2
|
+
/** A single validation failure for a field. */
|
|
3
|
+
export interface FieldError {
|
|
4
|
+
/** Data path of the failing field. */
|
|
5
|
+
path: string;
|
|
6
|
+
/** Validator type that failed (`required`, `pattern`, `custom:<name>`…). */
|
|
7
|
+
rule: string;
|
|
8
|
+
/** Human-readable message (already resolved). */
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
/** Signature of a registered custom validator. */
|
|
12
|
+
export type CustomValidatorFn = (value: unknown, args: Record<string, unknown>, context: {
|
|
13
|
+
field: InputField;
|
|
14
|
+
path: string;
|
|
15
|
+
data: Record<string, unknown>;
|
|
16
|
+
}) => boolean | string;
|
|
17
|
+
/** Registry of custom validators referenced by `{ type: 'custom', name }`. */
|
|
18
|
+
export type ValidatorRegistry = Record<string, CustomValidatorFn>;
|
|
19
|
+
/**
|
|
20
|
+
* Resolves the message for a failed rule. Hosts replace this to localize;
|
|
21
|
+
* the `{{...}}` placeholders keep defaults readable and overridable.
|
|
22
|
+
*/
|
|
23
|
+
export type MessageResolver = (rule: string, field: InputField, spec: ValidatorSpec | undefined) => string;
|
|
24
|
+
export declare const defaultMessageResolver: MessageResolver;
|
|
25
|
+
export declare function isEmptyValue(value: unknown): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Validates a single input field value against its declared validators.
|
|
28
|
+
* Empty values only fail `required` — the remaining rules apply to provided
|
|
29
|
+
* values, so optional fields stay optional.
|
|
30
|
+
*/
|
|
31
|
+
export declare function validateFieldValue(field: InputField, path: string, value: unknown, data: Record<string, unknown>, options?: {
|
|
32
|
+
registry?: ValidatorRegistry;
|
|
33
|
+
messages?: MessageResolver;
|
|
34
|
+
}): FieldError[];
|
|
35
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/validation/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEpE,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GAAG,CAC9B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,KACxE,OAAO,GAAG,MAAM,CAAC;AAEtB,8EAA8E;AAC9E,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,aAAa,GAAG,SAAS,KAC5B,MAAM,CAAC;AAaZ,eAAO,MAAM,sBAAsB,EAAE,eASpC,CAAC;AAIF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWpD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;CAAE,GACrE,UAAU,EAAE,CA4Dd"}
|