@coherent.js/forms 1.0.0-beta.6 → 1.0.0-beta.7
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/dist/advanced-validation.js +523 -0
- package/dist/advanced-validation.js.map +7 -0
- package/dist/form-builder.js +492 -0
- package/dist/form-builder.js.map +7 -0
- package/dist/form-hydration.js +565 -0
- package/dist/form-hydration.js.map +7 -0
- package/dist/forms.js +432 -0
- package/dist/forms.js.map +7 -0
- package/dist/index.js.map +7 -0
- package/dist/validation.js +186 -0
- package/dist/validation.js.map +7 -0
- package/dist/validators.js +365 -0
- package/dist/validators.js.map +7 -0
- package/package.json +14 -4
package/dist/forms.js
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
// src/forms.js
|
|
2
|
+
function createForm(options = {}) {
|
|
3
|
+
const opts = {
|
|
4
|
+
fields: {},
|
|
5
|
+
validation: {
|
|
6
|
+
strategy: "blur",
|
|
7
|
+
debounce: 300,
|
|
8
|
+
async: true,
|
|
9
|
+
stopOnFirstError: false,
|
|
10
|
+
revalidateOn: ["change", "blur"],
|
|
11
|
+
...options.validation
|
|
12
|
+
},
|
|
13
|
+
errors: {
|
|
14
|
+
format: "detailed",
|
|
15
|
+
display: "inline",
|
|
16
|
+
customFormatter: null,
|
|
17
|
+
...options.errors
|
|
18
|
+
},
|
|
19
|
+
submission: {
|
|
20
|
+
preventDefault: true,
|
|
21
|
+
validateBeforeSubmit: true,
|
|
22
|
+
disableOnSubmit: true,
|
|
23
|
+
resetOnSuccess: false,
|
|
24
|
+
onSuccess: null,
|
|
25
|
+
onError: null,
|
|
26
|
+
...options.submission
|
|
27
|
+
},
|
|
28
|
+
state: {
|
|
29
|
+
trackDirty: true,
|
|
30
|
+
trackTouched: true,
|
|
31
|
+
trackVisited: true,
|
|
32
|
+
initialValues: {},
|
|
33
|
+
resetValues: null,
|
|
34
|
+
...options.state
|
|
35
|
+
},
|
|
36
|
+
middleware: options.middleware || [],
|
|
37
|
+
...options
|
|
38
|
+
};
|
|
39
|
+
const state = {
|
|
40
|
+
values: { ...opts.state.initialValues },
|
|
41
|
+
errors: {},
|
|
42
|
+
touched: {},
|
|
43
|
+
dirty: {},
|
|
44
|
+
visited: {},
|
|
45
|
+
isSubmitting: false,
|
|
46
|
+
isValidating: false,
|
|
47
|
+
submitCount: 0,
|
|
48
|
+
asyncValidations: /* @__PURE__ */ new Map()
|
|
49
|
+
};
|
|
50
|
+
const fields = /* @__PURE__ */ new Map();
|
|
51
|
+
const stats = {
|
|
52
|
+
validations: 0,
|
|
53
|
+
asyncValidations: 0,
|
|
54
|
+
submissions: 0,
|
|
55
|
+
successfulSubmissions: 0,
|
|
56
|
+
failedSubmissions: 0,
|
|
57
|
+
middlewareExecutions: 0
|
|
58
|
+
};
|
|
59
|
+
function registerField(name, config) {
|
|
60
|
+
fields.set(name, {
|
|
61
|
+
name,
|
|
62
|
+
type: config.type || "text",
|
|
63
|
+
validators: config.validators || [],
|
|
64
|
+
transform: config.transform || {},
|
|
65
|
+
validateWhen: config.validateWhen,
|
|
66
|
+
required: config.required || false,
|
|
67
|
+
defaultValue: config.defaultValue,
|
|
68
|
+
...config
|
|
69
|
+
});
|
|
70
|
+
if (!(name in state.values)) {
|
|
71
|
+
state.values[name] = config.defaultValue !== void 0 ? config.defaultValue : "";
|
|
72
|
+
}
|
|
73
|
+
state.errors[name] = [];
|
|
74
|
+
state.touched[name] = false;
|
|
75
|
+
state.dirty[name] = false;
|
|
76
|
+
state.visited[name] = false;
|
|
77
|
+
}
|
|
78
|
+
function getField(name) {
|
|
79
|
+
return fields.get(name);
|
|
80
|
+
}
|
|
81
|
+
function setFieldValue(name, value, shouldValidate = true) {
|
|
82
|
+
const field = fields.get(name);
|
|
83
|
+
if (!field) {
|
|
84
|
+
console.warn(`Field ${name} not registered`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (field.transform?.input) {
|
|
88
|
+
value = field.transform.input(value);
|
|
89
|
+
}
|
|
90
|
+
state.values[name] = value;
|
|
91
|
+
if (opts.state.trackDirty) {
|
|
92
|
+
const initialValue = opts.state.initialValues[name];
|
|
93
|
+
state.dirty[name] = value !== initialValue;
|
|
94
|
+
}
|
|
95
|
+
if (shouldValidate && opts.validation.revalidateOn.includes("change")) {
|
|
96
|
+
validateField(name);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function getFieldValue(name) {
|
|
100
|
+
return state.values[name];
|
|
101
|
+
}
|
|
102
|
+
function setFieldTouched(name, touched = true) {
|
|
103
|
+
if (!opts.state.trackTouched) return;
|
|
104
|
+
state.touched[name] = touched;
|
|
105
|
+
if (touched && opts.validation.revalidateOn.includes("blur")) {
|
|
106
|
+
validateField(name);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function setFieldVisited(name, visited = true) {
|
|
110
|
+
if (!opts.state.trackVisited) return;
|
|
111
|
+
state.visited[name] = visited;
|
|
112
|
+
}
|
|
113
|
+
async function validateField(name) {
|
|
114
|
+
const field = fields.get(name);
|
|
115
|
+
if (!field) return { valid: true, errors: [] };
|
|
116
|
+
stats.validations++;
|
|
117
|
+
if (field.validateWhen && !field.validateWhen(state.values)) {
|
|
118
|
+
state.errors[name] = [];
|
|
119
|
+
return { valid: true, errors: [] };
|
|
120
|
+
}
|
|
121
|
+
const value = state.values[name];
|
|
122
|
+
const errors = [];
|
|
123
|
+
if (state.asyncValidations.has(name)) {
|
|
124
|
+
clearTimeout(state.asyncValidations.get(name));
|
|
125
|
+
}
|
|
126
|
+
if (field.required && (value === "" || value === null || value === void 0)) {
|
|
127
|
+
errors.push({
|
|
128
|
+
field: name,
|
|
129
|
+
type: "required",
|
|
130
|
+
message: `${name} is required`
|
|
131
|
+
});
|
|
132
|
+
state.errors[name] = errors;
|
|
133
|
+
return { valid: false, errors };
|
|
134
|
+
}
|
|
135
|
+
for (const validator of field.validators) {
|
|
136
|
+
try {
|
|
137
|
+
let result;
|
|
138
|
+
if (validator.validate.constructor.name === "AsyncFunction" || opts.validation.async) {
|
|
139
|
+
stats.asyncValidations++;
|
|
140
|
+
if (validator.debounce || opts.validation.debounce) {
|
|
141
|
+
await new Promise((resolve) => {
|
|
142
|
+
const timeoutId = setTimeout(resolve, validator.debounce || opts.validation.debounce);
|
|
143
|
+
state.asyncValidations.set(name, timeoutId);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
result = await validator.validate(value, state.values);
|
|
147
|
+
} else {
|
|
148
|
+
result = validator.validate(value, state.values);
|
|
149
|
+
}
|
|
150
|
+
if (result !== true && result !== void 0 && result !== null) {
|
|
151
|
+
errors.push({
|
|
152
|
+
field: name,
|
|
153
|
+
type: validator.name || "custom",
|
|
154
|
+
message: validator.message || result || "Validation failed"
|
|
155
|
+
});
|
|
156
|
+
if (opts.validation.stopOnFirstError) {
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} catch (error) {
|
|
161
|
+
errors.push({
|
|
162
|
+
field: name,
|
|
163
|
+
type: "error",
|
|
164
|
+
message: error.message || "Validation error"
|
|
165
|
+
});
|
|
166
|
+
if (opts.validation.stopOnFirstError) {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
state.errors[name] = errors;
|
|
172
|
+
return { valid: errors.length === 0, errors };
|
|
173
|
+
}
|
|
174
|
+
async function validateForm() {
|
|
175
|
+
state.isValidating = true;
|
|
176
|
+
const validationPromises = Array.from(fields.keys()).map(
|
|
177
|
+
(name) => validateField(name)
|
|
178
|
+
);
|
|
179
|
+
const results = await Promise.all(validationPromises);
|
|
180
|
+
state.isValidating = false;
|
|
181
|
+
const allErrors = results.reduce((acc, result, index) => {
|
|
182
|
+
const fieldName = Array.from(fields.keys())[index];
|
|
183
|
+
if (result.errors.length > 0) {
|
|
184
|
+
acc[fieldName] = result.errors;
|
|
185
|
+
}
|
|
186
|
+
return acc;
|
|
187
|
+
}, {});
|
|
188
|
+
const isValid2 = Object.keys(allErrors).length === 0;
|
|
189
|
+
return {
|
|
190
|
+
valid: isValid2,
|
|
191
|
+
errors: allErrors
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function executeMiddleware(action, data) {
|
|
195
|
+
if (opts.middleware.length === 0) return data;
|
|
196
|
+
stats.middlewareExecutions++;
|
|
197
|
+
let result = data;
|
|
198
|
+
for (const middleware of opts.middleware) {
|
|
199
|
+
try {
|
|
200
|
+
const next = () => result;
|
|
201
|
+
result = await middleware(action, result, next, state);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
console.error("Middleware error:", error);
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
function applyTransformations(values) {
|
|
210
|
+
const transformed = { ...values };
|
|
211
|
+
fields.forEach((field, name) => {
|
|
212
|
+
if (field.transform?.output && name in transformed) {
|
|
213
|
+
transformed[name] = field.transform.output(transformed[name]);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
return transformed;
|
|
217
|
+
}
|
|
218
|
+
async function handleSubmit(onSubmit) {
|
|
219
|
+
stats.submissions++;
|
|
220
|
+
try {
|
|
221
|
+
if (opts.submission.preventDefault && typeof event !== "undefined") {
|
|
222
|
+
event.preventDefault();
|
|
223
|
+
}
|
|
224
|
+
if (opts.submission.disableOnSubmit) {
|
|
225
|
+
state.isSubmitting = true;
|
|
226
|
+
}
|
|
227
|
+
let values = { ...state.values };
|
|
228
|
+
values = await executeMiddleware("beforeSubmit", values);
|
|
229
|
+
if (opts.submission.validateBeforeSubmit) {
|
|
230
|
+
const validation = await validateForm();
|
|
231
|
+
if (!validation.valid) {
|
|
232
|
+
if (opts.submission.onError) {
|
|
233
|
+
opts.submission.onError(validation.errors);
|
|
234
|
+
}
|
|
235
|
+
stats.failedSubmissions++;
|
|
236
|
+
return { success: false, errors: validation.errors };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
values = applyTransformations(values);
|
|
240
|
+
values = await executeMiddleware("afterValidation", values);
|
|
241
|
+
const result = await onSubmit(values);
|
|
242
|
+
await executeMiddleware("afterSubmit", result);
|
|
243
|
+
state.submitCount++;
|
|
244
|
+
stats.successfulSubmissions++;
|
|
245
|
+
if (opts.submission.resetOnSuccess) {
|
|
246
|
+
reset();
|
|
247
|
+
}
|
|
248
|
+
if (opts.submission.onSuccess) {
|
|
249
|
+
opts.submission.onSuccess(result);
|
|
250
|
+
}
|
|
251
|
+
return { success: true, data: result };
|
|
252
|
+
} catch (error) {
|
|
253
|
+
stats.failedSubmissions++;
|
|
254
|
+
if (opts.submission.onError) {
|
|
255
|
+
opts.submission.onError(error);
|
|
256
|
+
}
|
|
257
|
+
await executeMiddleware("onError", error);
|
|
258
|
+
return { success: false, error };
|
|
259
|
+
} finally {
|
|
260
|
+
state.isSubmitting = false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function reset(values) {
|
|
264
|
+
const resetValues = values || opts.state.resetValues || opts.state.initialValues;
|
|
265
|
+
state.values = { ...resetValues };
|
|
266
|
+
state.errors = {};
|
|
267
|
+
state.touched = {};
|
|
268
|
+
state.dirty = {};
|
|
269
|
+
state.visited = {};
|
|
270
|
+
state.submitCount = 0;
|
|
271
|
+
fields.forEach((field, name) => {
|
|
272
|
+
if (!(name in state.values)) {
|
|
273
|
+
state.values[name] = field.defaultValue !== void 0 ? field.defaultValue : "";
|
|
274
|
+
}
|
|
275
|
+
state.errors[name] = [];
|
|
276
|
+
state.touched[name] = false;
|
|
277
|
+
state.dirty[name] = false;
|
|
278
|
+
state.visited[name] = false;
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
function getErrors(fieldName) {
|
|
282
|
+
if (fieldName) {
|
|
283
|
+
return state.errors[fieldName] || [];
|
|
284
|
+
}
|
|
285
|
+
if (opts.errors.customFormatter) {
|
|
286
|
+
return opts.errors.customFormatter(state.errors);
|
|
287
|
+
}
|
|
288
|
+
if (opts.errors.format === "simple") {
|
|
289
|
+
return Object.values(state.errors).flat().map((e) => e.message);
|
|
290
|
+
}
|
|
291
|
+
return state.errors;
|
|
292
|
+
}
|
|
293
|
+
function isValid() {
|
|
294
|
+
return Object.values(state.errors).every((errors) => errors.length === 0);
|
|
295
|
+
}
|
|
296
|
+
function isDirty(fieldName) {
|
|
297
|
+
if (fieldName) {
|
|
298
|
+
return state.dirty[fieldName] || false;
|
|
299
|
+
}
|
|
300
|
+
return Object.values(state.dirty).some((dirty) => dirty);
|
|
301
|
+
}
|
|
302
|
+
function isTouched(fieldName) {
|
|
303
|
+
if (fieldName) {
|
|
304
|
+
return state.touched[fieldName] || false;
|
|
305
|
+
}
|
|
306
|
+
return Object.values(state.touched).some((touched) => touched);
|
|
307
|
+
}
|
|
308
|
+
function getValues() {
|
|
309
|
+
return { ...state.values };
|
|
310
|
+
}
|
|
311
|
+
function setValues(values, shouldValidate = false) {
|
|
312
|
+
Object.entries(values).forEach(([name, value]) => {
|
|
313
|
+
setFieldValue(name, value, shouldValidate);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
function getState() {
|
|
317
|
+
return {
|
|
318
|
+
values: { ...state.values },
|
|
319
|
+
errors: { ...state.errors },
|
|
320
|
+
touched: { ...state.touched },
|
|
321
|
+
dirty: { ...state.dirty },
|
|
322
|
+
visited: { ...state.visited },
|
|
323
|
+
isSubmitting: state.isSubmitting,
|
|
324
|
+
isValidating: state.isValidating,
|
|
325
|
+
submitCount: state.submitCount,
|
|
326
|
+
isValid: isValid(),
|
|
327
|
+
isDirty: isDirty(),
|
|
328
|
+
isTouched: isTouched()
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function getStats() {
|
|
332
|
+
return {
|
|
333
|
+
...stats,
|
|
334
|
+
fieldsRegistered: fields.size,
|
|
335
|
+
activeAsyncValidations: state.asyncValidations.size
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
Object.entries(opts.fields).forEach(([name, config]) => {
|
|
339
|
+
registerField(name, config);
|
|
340
|
+
});
|
|
341
|
+
return {
|
|
342
|
+
registerField,
|
|
343
|
+
getField,
|
|
344
|
+
setFieldValue,
|
|
345
|
+
getFieldValue,
|
|
346
|
+
setFieldTouched,
|
|
347
|
+
setFieldVisited,
|
|
348
|
+
validateField,
|
|
349
|
+
validateForm,
|
|
350
|
+
handleSubmit,
|
|
351
|
+
reset,
|
|
352
|
+
getErrors,
|
|
353
|
+
isValid,
|
|
354
|
+
isDirty,
|
|
355
|
+
isTouched,
|
|
356
|
+
getValues,
|
|
357
|
+
setValues,
|
|
358
|
+
getState,
|
|
359
|
+
getStats,
|
|
360
|
+
// Expose state for testing
|
|
361
|
+
_state: state
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
var formValidators = {
|
|
365
|
+
required: {
|
|
366
|
+
name: "required",
|
|
367
|
+
validate: (value) => {
|
|
368
|
+
return value !== "" && value !== null && value !== void 0;
|
|
369
|
+
},
|
|
370
|
+
message: "This field is required"
|
|
371
|
+
},
|
|
372
|
+
email: {
|
|
373
|
+
name: "email",
|
|
374
|
+
validate: (value) => {
|
|
375
|
+
if (!value) return true;
|
|
376
|
+
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
377
|
+
return regex.test(value);
|
|
378
|
+
},
|
|
379
|
+
message: "Please enter a valid email address"
|
|
380
|
+
},
|
|
381
|
+
minLength: (min) => ({
|
|
382
|
+
name: "minLength",
|
|
383
|
+
validate: (value) => {
|
|
384
|
+
if (!value) return true;
|
|
385
|
+
return String(value).length >= min;
|
|
386
|
+
},
|
|
387
|
+
message: `Must be at least ${min} characters`
|
|
388
|
+
}),
|
|
389
|
+
maxLength: (max) => ({
|
|
390
|
+
name: "maxLength",
|
|
391
|
+
validate: (value) => {
|
|
392
|
+
if (!value) return true;
|
|
393
|
+
return String(value).length <= max;
|
|
394
|
+
},
|
|
395
|
+
message: `Must be no more than ${max} characters`
|
|
396
|
+
}),
|
|
397
|
+
pattern: (regex, message) => ({
|
|
398
|
+
name: "pattern",
|
|
399
|
+
validate: (value) => {
|
|
400
|
+
if (!value) return true;
|
|
401
|
+
return regex.test(value);
|
|
402
|
+
},
|
|
403
|
+
message: message || "Invalid format"
|
|
404
|
+
}),
|
|
405
|
+
asyncEmail: {
|
|
406
|
+
name: "asyncEmail",
|
|
407
|
+
validate: async (value) => {
|
|
408
|
+
if (!value) return true;
|
|
409
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
410
|
+
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
411
|
+
return regex.test(value);
|
|
412
|
+
},
|
|
413
|
+
message: "Please enter a valid email address",
|
|
414
|
+
debounce: 500
|
|
415
|
+
},
|
|
416
|
+
asyncUnique: (checkFn) => ({
|
|
417
|
+
name: "asyncUnique",
|
|
418
|
+
validate: async (value) => {
|
|
419
|
+
if (!value) return true;
|
|
420
|
+
return await checkFn(value);
|
|
421
|
+
},
|
|
422
|
+
message: "This value is already taken",
|
|
423
|
+
debounce: 500
|
|
424
|
+
})
|
|
425
|
+
};
|
|
426
|
+
var enhancedForm = createForm();
|
|
427
|
+
export {
|
|
428
|
+
createForm,
|
|
429
|
+
enhancedForm,
|
|
430
|
+
formValidators
|
|
431
|
+
};
|
|
432
|
+
//# sourceMappingURL=forms.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/forms.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * Enhanced Form System\n *\n * Provides advanced form features:\n * - Async validation\n * - Custom validators\n * - Field transformations\n * - Form middleware\n */\n\n/**\n * Create an enhanced form with advanced validation and middleware\n *\n * @param {Object} options - Configuration options\n * @param {Object} [options.fields] - Field configurations\n * @param {Object} [options.validation] - Validation options\n * @param {Array} [options.middleware] - Form middleware functions\n * @param {Object} [options.submission] - Submission options\n * @returns {Object} Enhanced form instance\n */\nexport function createForm(options = {}) {\n const opts = {\n fields: {},\n validation: {\n strategy: 'blur',\n debounce: 300,\n async: true,\n stopOnFirstError: false,\n revalidateOn: ['change', 'blur'],\n ...options.validation\n },\n errors: {\n format: 'detailed',\n display: 'inline',\n customFormatter: null,\n ...options.errors\n },\n submission: {\n preventDefault: true,\n validateBeforeSubmit: true,\n disableOnSubmit: true,\n resetOnSuccess: false,\n onSuccess: null,\n onError: null,\n ...options.submission\n },\n state: {\n trackDirty: true,\n trackTouched: true,\n trackVisited: true,\n initialValues: {},\n resetValues: null,\n ...options.state\n },\n middleware: options.middleware || [],\n ...options\n };\n\n // Form state\n const state = {\n values: { ...opts.state.initialValues },\n errors: {},\n touched: {},\n dirty: {},\n visited: {},\n isSubmitting: false,\n isValidating: false,\n submitCount: 0,\n asyncValidations: new Map()\n };\n\n // Field metadata\n const fields = new Map();\n\n // Statistics\n const stats = {\n validations: 0,\n asyncValidations: 0,\n submissions: 0,\n successfulSubmissions: 0,\n failedSubmissions: 0,\n middlewareExecutions: 0\n };\n\n /**\n * Register a field\n */\n function registerField(name, config) {\n fields.set(name, {\n name,\n type: config.type || 'text',\n validators: config.validators || [],\n transform: config.transform || {},\n validateWhen: config.validateWhen,\n required: config.required || false,\n defaultValue: config.defaultValue,\n ...config\n });\n\n // Initialize field state\n if (!(name in state.values)) {\n state.values[name] = config.defaultValue !== undefined\n ? config.defaultValue\n : '';\n }\n state.errors[name] = [];\n state.touched[name] = false;\n state.dirty[name] = false;\n state.visited[name] = false;\n }\n\n /**\n * Get field configuration\n */\n function getField(name) {\n return fields.get(name);\n }\n\n /**\n * Set field value\n */\n function setFieldValue(name, value, shouldValidate = true) {\n const field = fields.get(name);\n if (!field) {\n console.warn(`Field ${name} not registered`);\n return;\n }\n\n // Apply input transformation\n if (field.transform?.input) {\n value = field.transform.input(value);\n }\n\n state.values[name] = value;\n\n // Track dirty state\n if (opts.state.trackDirty) {\n const initialValue = opts.state.initialValues[name];\n state.dirty[name] = value !== initialValue;\n }\n\n // Validate if needed\n if (shouldValidate && opts.validation.revalidateOn.includes('change')) {\n validateField(name);\n }\n }\n\n /**\n * Get field value\n */\n function getFieldValue(name) {\n return state.values[name];\n }\n\n /**\n * Set field touched\n */\n function setFieldTouched(name, touched = true) {\n if (!opts.state.trackTouched) return;\n\n state.touched[name] = touched;\n\n // Validate on blur if configured\n if (touched && opts.validation.revalidateOn.includes('blur')) {\n validateField(name);\n }\n }\n\n /**\n * Set field visited\n */\n function setFieldVisited(name, visited = true) {\n if (!opts.state.trackVisited) return;\n state.visited[name] = visited;\n }\n\n /**\n * Validate a single field\n */\n async function validateField(name) {\n const field = fields.get(name);\n if (!field) return { valid: true, errors: [] };\n\n stats.validations++;\n\n // Check conditional validation\n if (field.validateWhen && !field.validateWhen(state.values)) {\n state.errors[name] = [];\n return { valid: true, errors: [] };\n }\n\n const value = state.values[name];\n const errors = [];\n\n // Cancel previous async validation if any\n if (state.asyncValidations.has(name)) {\n clearTimeout(state.asyncValidations.get(name));\n }\n\n // Required validation\n if (field.required && (value === '' || value === null || value === undefined)) {\n errors.push({\n field: name,\n type: 'required',\n message: `${name} is required`\n });\n\n state.errors[name] = errors;\n return { valid: false, errors };\n }\n\n // Run validators\n for (const validator of field.validators) {\n try {\n let result;\n\n // Check if validator is async\n if (validator.validate.constructor.name === 'AsyncFunction' || opts.validation.async) {\n stats.asyncValidations++;\n\n // Debounce async validation\n if (validator.debounce || opts.validation.debounce) {\n await new Promise(resolve => {\n const timeoutId = setTimeout(resolve, validator.debounce || opts.validation.debounce);\n state.asyncValidations.set(name, timeoutId);\n });\n }\n\n result = await validator.validate(value, state.values);\n } else {\n result = validator.validate(value, state.values);\n }\n\n // Check result\n if (result !== true && result !== undefined && result !== null) {\n errors.push({\n field: name,\n type: validator.name || 'custom',\n message: validator.message || result || 'Validation failed'\n });\n\n if (opts.validation.stopOnFirstError) {\n break;\n }\n }\n } catch (error) {\n errors.push({\n field: name,\n type: 'error',\n message: error.message || 'Validation error'\n });\n\n if (opts.validation.stopOnFirstError) {\n break;\n }\n }\n }\n\n state.errors[name] = errors;\n return { valid: errors.length === 0, errors };\n }\n\n /**\n * Validate all fields\n */\n async function validateForm() {\n state.isValidating = true;\n\n const validationPromises = Array.from(fields.keys()).map(name =>\n validateField(name)\n );\n\n const results = await Promise.all(validationPromises);\n\n state.isValidating = false;\n\n const allErrors = results.reduce((acc, result, index) => {\n const fieldName = Array.from(fields.keys())[index];\n if (result.errors.length > 0) {\n acc[fieldName] = result.errors;\n }\n return acc;\n }, {});\n\n const isValid = Object.keys(allErrors).length === 0;\n\n return {\n valid: isValid,\n errors: allErrors\n };\n }\n\n /**\n * Execute middleware\n */\n async function executeMiddleware(action, data) {\n if (opts.middleware.length === 0) return data;\n\n stats.middlewareExecutions++;\n\n let result = data;\n\n for (const middleware of opts.middleware) {\n try {\n const next = () => result;\n result = await middleware(action, result, next, state);\n } catch (error) {\n console.error('Middleware error:', error);\n throw error;\n }\n }\n\n return result;\n }\n\n /**\n * Apply field transformations\n */\n function applyTransformations(values) {\n const transformed = { ...values };\n\n fields.forEach((field, name) => {\n if (field.transform?.output && name in transformed) {\n transformed[name] = field.transform.output(transformed[name]);\n }\n });\n\n return transformed;\n }\n\n /**\n * Submit the form\n */\n async function handleSubmit(onSubmit) {\n stats.submissions++;\n\n try {\n // Prevent default if needed\n if (opts.submission.preventDefault && typeof event !== 'undefined') {\n event.preventDefault();\n }\n\n // Disable form during submission\n if (opts.submission.disableOnSubmit) {\n state.isSubmitting = true;\n }\n\n // Execute beforeSubmit middleware\n let values = { ...state.values };\n values = await executeMiddleware('beforeSubmit', values);\n\n // Validate before submit\n if (opts.submission.validateBeforeSubmit) {\n const validation = await validateForm();\n\n if (!validation.valid) {\n if (opts.submission.onError) {\n opts.submission.onError(validation.errors);\n }\n\n stats.failedSubmissions++;\n return { success: false, errors: validation.errors };\n }\n }\n\n // Apply transformations\n values = applyTransformations(values);\n\n // Execute afterValidation middleware\n values = await executeMiddleware('afterValidation', values);\n\n // Submit\n const result = await onSubmit(values);\n\n // Execute afterSubmit middleware\n await executeMiddleware('afterSubmit', result);\n\n state.submitCount++;\n stats.successfulSubmissions++;\n\n // Reset on success\n if (opts.submission.resetOnSuccess) {\n reset();\n }\n\n if (opts.submission.onSuccess) {\n opts.submission.onSuccess(result);\n }\n\n return { success: true, data: result };\n\n } catch (error) {\n stats.failedSubmissions++;\n\n if (opts.submission.onError) {\n opts.submission.onError(error);\n }\n\n // Execute onError middleware\n await executeMiddleware('onError', error);\n\n return { success: false, error };\n\n } finally {\n state.isSubmitting = false;\n }\n }\n\n /**\n * Reset form to initial state\n */\n function reset(values) {\n const resetValues = values || opts.state.resetValues || opts.state.initialValues;\n\n state.values = { ...resetValues };\n state.errors = {};\n state.touched = {};\n state.dirty = {};\n state.visited = {};\n state.submitCount = 0;\n\n // Re-initialize field states\n fields.forEach((field, name) => {\n // Ensure field has a value from resetValues or defaultValue\n if (!(name in state.values)) {\n state.values[name] = field.defaultValue !== undefined\n ? field.defaultValue\n : '';\n }\n state.errors[name] = [];\n state.touched[name] = false;\n state.dirty[name] = false;\n state.visited[name] = false;\n });\n }\n\n /**\n * Get form errors\n */\n function getErrors(fieldName) {\n if (fieldName) {\n return state.errors[fieldName] || [];\n }\n\n if (opts.errors.customFormatter) {\n return opts.errors.customFormatter(state.errors);\n }\n\n if (opts.errors.format === 'simple') {\n // Return array of error messages\n return Object.values(state.errors).flat().map(e => e.message);\n }\n\n // Return detailed errors\n return state.errors;\n }\n\n /**\n * Check if form is valid\n */\n function isValid() {\n return Object.values(state.errors).every(errors => errors.length === 0);\n }\n\n /**\n * Check if form is dirty\n */\n function isDirty(fieldName) {\n if (fieldName) {\n return state.dirty[fieldName] || false;\n }\n return Object.values(state.dirty).some(dirty => dirty);\n }\n\n /**\n * Check if form is touched\n */\n function isTouched(fieldName) {\n if (fieldName) {\n return state.touched[fieldName] || false;\n }\n return Object.values(state.touched).some(touched => touched);\n }\n\n /**\n * Get form values\n */\n function getValues() {\n return { ...state.values };\n }\n\n /**\n * Set form values\n */\n function setValues(values, shouldValidate = false) {\n Object.entries(values).forEach(([name, value]) => {\n setFieldValue(name, value, shouldValidate);\n });\n }\n\n /**\n * Get form state\n */\n function getState() {\n return {\n values: { ...state.values },\n errors: { ...state.errors },\n touched: { ...state.touched },\n dirty: { ...state.dirty },\n visited: { ...state.visited },\n isSubmitting: state.isSubmitting,\n isValidating: state.isValidating,\n submitCount: state.submitCount,\n isValid: isValid(),\n isDirty: isDirty(),\n isTouched: isTouched()\n };\n }\n\n /**\n * Get statistics\n */\n function getStats() {\n return {\n ...stats,\n fieldsRegistered: fields.size,\n activeAsyncValidations: state.asyncValidations.size\n };\n }\n\n // Register initial fields\n Object.entries(opts.fields).forEach(([name, config]) => {\n registerField(name, config);\n });\n\n return {\n registerField,\n getField,\n setFieldValue,\n getFieldValue,\n setFieldTouched,\n setFieldVisited,\n validateField,\n validateForm,\n handleSubmit,\n reset,\n getErrors,\n isValid,\n isDirty,\n isTouched,\n getValues,\n setValues,\n getState,\n getStats,\n // Expose state for testing\n _state: state\n };\n}\n\n// Export built-in validators\nexport const formValidators = {\n required: {\n name: 'required',\n validate: (value) => {\n return value !== '' && value !== null && value !== undefined;\n },\n message: 'This field is required'\n },\n\n email: {\n name: 'email',\n validate: (value) => {\n if (!value) return true;\n const regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return regex.test(value);\n },\n message: 'Please enter a valid email address'\n },\n\n minLength: (min) => ({\n name: 'minLength',\n validate: (value) => {\n if (!value) return true;\n return String(value).length >= min;\n },\n message: `Must be at least ${min} characters`\n }),\n\n maxLength: (max) => ({\n name: 'maxLength',\n validate: (value) => {\n if (!value) return true;\n return String(value).length <= max;\n },\n message: `Must be no more than ${max} characters`\n }),\n\n pattern: (regex, message) => ({\n name: 'pattern',\n validate: (value) => {\n if (!value) return true;\n return regex.test(value);\n },\n message: message || 'Invalid format'\n }),\n\n asyncEmail: {\n name: 'asyncEmail',\n validate: async (value) => {\n if (!value) return true;\n // Simulate async validation (e.g., check if email exists)\n await new Promise(resolve => setTimeout(resolve, 100));\n const regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return regex.test(value);\n },\n message: 'Please enter a valid email address',\n debounce: 500\n },\n\n asyncUnique: (checkFn) => ({\n name: 'asyncUnique',\n validate: async (value) => {\n if (!value) return true;\n return await checkFn(value);\n },\n message: 'This value is already taken',\n debounce: 500\n })\n};\n\n// Export default instance\nexport const enhancedForm = createForm();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["isValid"]
|
|
7
|
+
}
|