react-f0rm 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +527 -33
  2. package/dist/devtools/index.cjs.js +737 -0
  3. package/dist/devtools/index.cjs.js.map +1 -0
  4. package/dist/devtools/index.d.ts +33 -0
  5. package/dist/devtools/index.mjs +717 -0
  6. package/dist/devtools/index.mjs.map +1 -0
  7. package/dist/form-61297bc0.d.ts +578 -0
  8. package/dist/form-94c70b4b.mjs +378 -0
  9. package/dist/form-94c70b4b.mjs.map +1 -0
  10. package/dist/form-b9441d8c.cjs.js +387 -0
  11. package/dist/form-b9441d8c.cjs.js.map +1 -0
  12. package/dist/index.cjs.js +1257 -157
  13. package/dist/index.cjs.js.map +1 -1
  14. package/dist/index.d.ts +357 -53
  15. package/dist/index.mjs +1676 -0
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/index.umd.js +1257 -157
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/index.umd.min.js +2 -2
  20. package/dist/index.umd.min.js.map +1 -1
  21. package/dist/resolvers/standard-schema.cjs.js +90 -0
  22. package/dist/resolvers/standard-schema.cjs.js.map +1 -0
  23. package/dist/resolvers/standard-schema.d.ts +66 -0
  24. package/dist/resolvers/standard-schema.mjs +86 -0
  25. package/dist/resolvers/standard-schema.mjs.map +1 -0
  26. package/dist/resolvers/yup.cjs.js +12 -2
  27. package/dist/resolvers/yup.cjs.js.map +1 -1
  28. package/dist/resolvers/yup.d.ts +2 -2
  29. package/dist/resolvers/yup.mjs +23 -0
  30. package/dist/resolvers/yup.mjs.map +1 -0
  31. package/dist/resolvers/zod.cjs.js +14 -1
  32. package/dist/resolvers/zod.cjs.js.map +1 -1
  33. package/dist/resolvers/zod.d.ts +2 -2
  34. package/dist/resolvers/zod.mjs +23 -0
  35. package/dist/resolvers/zod.mjs.map +1 -0
  36. package/dist/validate-148fe167.d.ts +22 -0
  37. package/package.json +34 -8
  38. package/dist/form-d06e6444.d.ts +0 -201
  39. package/dist/index.esm.js +0 -593
  40. package/dist/index.esm.js.map +0 -1
  41. package/dist/resolvers/yup.esm.js +0 -13
  42. package/dist/resolvers/yup.esm.js.map +0 -1
  43. package/dist/resolvers/zod.esm.js +0 -10
  44. package/dist/resolvers/zod.esm.js.map +0 -1
  45. package/dist/validate-0f17f86a.d.ts +0 -8
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+
3
+ var form = require('../form-b9441d8c.cjs.js');
4
+
5
+ function hasStandardProps(schema) {
6
+ return !!schema && typeof schema === "object" && typeof schema["~standard"]?.validate === "function";
7
+ }
8
+ function toFieldError(issue) {
9
+ return { type: "standard", message: issue?.message || "Validation failed" };
10
+ }
11
+ function standardSchemaResolver(schema) {
12
+ return async (value) => {
13
+ const result = await schema["~standard"].validate(value);
14
+ if (!result.issues?.length) return void 0;
15
+ return result.issues.map(toFieldError);
16
+ };
17
+ }
18
+ function standardSchemaFormValidator(schema) {
19
+ return async (values) => {
20
+ const result = await schema["~standard"].validate(values);
21
+ const { issues } = result;
22
+ if (!issues?.length) {
23
+ return {
24
+ [form.VALIDATION_OUTCOME]: true,
25
+ values: "value" in result ? result.value : void 0
26
+ };
27
+ }
28
+ const errors = {};
29
+ for (const issue of issues) {
30
+ const segments = toPathSegments(issue);
31
+ if (segments.length) {
32
+ assignAtPath(errors, segments, toFieldError(issue));
33
+ } else {
34
+ const slot = errors._form ??= [];
35
+ if (Array.isArray(slot)) slot.push(toFieldError(issue));
36
+ }
37
+ }
38
+ return { [form.VALIDATION_OUTCOME]: true, errors: pruneEmpty(errors) || {} };
39
+ };
40
+ }
41
+ function toPathSegments(issue) {
42
+ const path = issue.path || [];
43
+ const segments = [];
44
+ for (const segment of path) {
45
+ const key = typeof segment === "object" && segment !== null ? segment.key : segment;
46
+ segments.push(String(key));
47
+ }
48
+ return segments;
49
+ }
50
+ function assignAtPath(root, segments, error) {
51
+ let node = root;
52
+ for (let i = 0; i < segments.length - 1; i++) {
53
+ const segment = segments[i];
54
+ let next = node[segment];
55
+ if (next === void 0) {
56
+ next = node[segment] = {};
57
+ }
58
+ if (!isBranch(next)) return;
59
+ node = next;
60
+ }
61
+ const leaf = segments[segments.length - 1];
62
+ const slot = node[leaf];
63
+ if (slot === void 0) node[leaf] = [error];
64
+ else if (Array.isArray(slot)) slot.push(error);
65
+ }
66
+ function isBranch(value) {
67
+ return !!value && typeof value === "object" && !Array.isArray(value);
68
+ }
69
+ function pruneEmpty(node) {
70
+ let hasLeaf = false;
71
+ const result = {};
72
+ Object.entries(node).forEach(([key, value]) => {
73
+ if (isBranch(value)) {
74
+ const pruned = pruneEmpty(value);
75
+ if (pruned) {
76
+ result[key] = pruned;
77
+ hasLeaf = true;
78
+ }
79
+ } else {
80
+ result[key] = value;
81
+ hasLeaf = true;
82
+ }
83
+ });
84
+ return hasLeaf ? result : void 0;
85
+ }
86
+
87
+ exports.hasStandardProps = hasStandardProps;
88
+ exports.standardSchemaFormValidator = standardSchemaFormValidator;
89
+ exports.standardSchemaResolver = standardSchemaResolver;
90
+ //# sourceMappingURL=standard-schema.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard-schema.cjs.js","sources":["../../src/resolvers/standard-schema.ts"],"sourcesContent":["import {VALIDATION_OUTCOME} from '../form';\nimport type {FieldError, ValidationOutcome} from '../form';\nimport type {Validator} from '../hooks/validate';\n\n/**\n * Minimal copy of the Standard Schema v1 interfaces\n * (https://standardschema.dev) so this module has zero runtime and type\n * dependencies on any schema library. Implemented by zod v3.24+/v4,\n * valibot v1, arktype and others.\n */\nexport interface StandardSchemaIssue {\n readonly message: string;\n readonly path?:\n | ReadonlyArray<PropertyKey | {readonly key: PropertyKey}>\n | undefined;\n}\n\nexport interface StandardSchemaV1<Input = unknown, Output = Input> {\n readonly '~standard': {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (\n value: Input\n ) =>\n | {readonly value: Output; readonly issues?: undefined}\n | {readonly issues: ReadonlyArray<StandardSchemaIssue>}\n | Promise<\n | {readonly value: Output; readonly issues?: undefined}\n | {readonly issues: ReadonlyArray<StandardSchemaIssue>}\n >;\n };\n}\n\n/**\n * Does the schema implement the Standard Schema v1 props?\n */\nexport function hasStandardProps(schema: any): schema is StandardSchemaV1 {\n return (\n !!schema &&\n typeof schema === 'object' &&\n typeof schema['~standard']?.validate === 'function'\n );\n}\n\nfunction toFieldError(issue: StandardSchemaIssue | undefined): FieldError {\n return {type: 'standard', message: issue?.message || 'Validation failed'};\n}\n\n/**\n * Field-level Standard Schema adapter: validate a single value with any\n * schema implementing '~standard' and map every issue to a FieldError,\n * so a value breaking several rules surfaces all of them (setErrorByPath\n * stores the array; error/errorObject readers still see the first).\n *\n * @param schema a Standard Schema v1 (zod v3.24+/v4, valibot v1, arktype...)\n * @return field validator compatible with useField's validate option\n */\nexport function standardSchemaResolver(schema: StandardSchemaV1): Validator {\n return async (value: any) => {\n const result = await schema['~standard'].validate(value);\n if (!result.issues?.length) return undefined;\n return result.issues.map(toFieldError);\n };\n}\n\n/**\n * Form-level Standard Schema adapter: validate the whole values object with\n * any schema implementing '~standard' and return a ValidationOutcome. On\n * failure `errors` carries the nested shape Options.validate expects\n * ({a: {b: FieldError[]}}; ensureValidate flattens it back to per-field\n * errors, keeping every issue of a path). Issues without a path are\n * form-level errors and land on the '_form' key. On success `values`\n * carries the schema's parsed output (coerce/transform results included),\n * which the form stores as its parsedValues baseline — the layer getValues\n * reads above initialValues, mirroring how react-hook-form's zodResolver\n * and TanStack's standardSchemaValidators use the parsed value.\n *\n * @param schema a Standard Schema v1 (zod v3.24+/v4, valibot v1, arktype...)\n * @return form-level validator for createForm({validate: ...})\n */\nexport function standardSchemaFormValidator<T extends Record<string, any>>(\n schema: StandardSchemaV1<T, any>\n): (values: T) => Promise<ValidationOutcome<T>> {\n return async (values: T) => {\n const result = await schema['~standard'].validate(values);\n const {issues} = result;\n if (!issues?.length) {\n // Success: expose the schema's parsed output. `in` keeps the union\n // narrowed (the success variant is the one carrying `value`).\n return {\n [VALIDATION_OUTCOME]: true,\n values: 'value' in result ? result.value : undefined\n };\n }\n const errors: Record<string, any> = {};\n for (const issue of issues) {\n const segments = toPathSegments(issue);\n if (segments.length) {\n assignAtPath(errors, segments, toFieldError(issue));\n } else {\n // Pathless issues are all form-level: they accumulate on '_form'\n // instead of the first shadowing the rest. (A nested path literally\n // named '_form' would have made the slot a branch — skip then.)\n const slot = (errors._form ??= []);\n if (Array.isArray(slot)) slot.push(toFieldError(issue));\n }\n }\n return {[VALIDATION_OUTCOME]: true, errors: pruneEmpty(errors) || {}};\n };\n}\n\n/**\n * Stringify an issue path: PropertyKey or {key} path segments → strings.\n */\nfunction toPathSegments(issue: StandardSchemaIssue): string[] {\n const path = issue.path || [];\n const segments: string[] = [];\n for (const segment of path) {\n const key =\n typeof segment === 'object' && segment !== null\n ? (segment as {key: PropertyKey}).key\n : segment;\n segments.push(String(key));\n }\n return segments;\n}\n\n/**\n * Append the error at a nested path. Leaves are FieldError[] arrays, so\n * several issues on one field accumulate in issue order; an issue whose\n * path conflicts with an existing leaf or crosses it is skipped.\n */\nfunction assignAtPath(\n root: Record<string, any>,\n segments: string[],\n error: FieldError\n): void {\n let node = root;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n let next = node[segment];\n if (next === undefined) {\n next = node[segment] = {};\n }\n if (!isBranch(next)) return;\n node = next;\n }\n const leaf = segments[segments.length - 1];\n const slot = node[leaf];\n if (slot === undefined) node[leaf] = [error];\n else if (Array.isArray(slot)) slot.push(error);\n}\n\n/**\n * A branch is a plain container built while nesting; the leaves it carries\n * are the FieldError[] arrays assignAtPath appends.\n */\nfunction isBranch(value: any): value is Record<string, any> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Drop empty branch objects left behind by conflicting issue paths.\n */\nfunction pruneEmpty(\n node: Record<string, any>\n): Record<string, any> | undefined {\n let hasLeaf = false;\n const result: Record<string, any> = {};\n Object.entries(node).forEach(([key, value]) => {\n if (isBranch(value)) {\n const pruned = pruneEmpty(value);\n if (pruned) {\n result[key] = pruned;\n hasLeaf = true;\n }\n } else {\n result[key] = value;\n hasLeaf = true;\n }\n });\n return hasLeaf ? result : undefined;\n}\n"],"names":["VALIDATION_OUTCOME"],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { h as ValidationOutcome } from '../form-61297bc0.js';
2
+ import { V as Validator } from '../validate-148fe167.js';
3
+ import '@for-fun/event-emitter';
4
+
5
+ /**
6
+ * Minimal copy of the Standard Schema v1 interfaces
7
+ * (https://standardschema.dev) so this module has zero runtime and type
8
+ * dependencies on any schema library. Implemented by zod v3.24+/v4,
9
+ * valibot v1, arktype and others.
10
+ */
11
+ interface StandardSchemaIssue {
12
+ readonly message: string;
13
+ readonly path?: ReadonlyArray<PropertyKey | {
14
+ readonly key: PropertyKey;
15
+ }> | undefined;
16
+ }
17
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
18
+ readonly '~standard': {
19
+ readonly version: 1;
20
+ readonly vendor: string;
21
+ readonly validate: (value: Input) => {
22
+ readonly value: Output;
23
+ readonly issues?: undefined;
24
+ } | {
25
+ readonly issues: ReadonlyArray<StandardSchemaIssue>;
26
+ } | Promise<{
27
+ readonly value: Output;
28
+ readonly issues?: undefined;
29
+ } | {
30
+ readonly issues: ReadonlyArray<StandardSchemaIssue>;
31
+ }>;
32
+ };
33
+ }
34
+ /**
35
+ * Does the schema implement the Standard Schema v1 props?
36
+ */
37
+ declare function hasStandardProps(schema: any): schema is StandardSchemaV1;
38
+ /**
39
+ * Field-level Standard Schema adapter: validate a single value with any
40
+ * schema implementing '~standard' and map every issue to a FieldError,
41
+ * so a value breaking several rules surfaces all of them (setErrorByPath
42
+ * stores the array; error/errorObject readers still see the first).
43
+ *
44
+ * @param schema a Standard Schema v1 (zod v3.24+/v4, valibot v1, arktype...)
45
+ * @return field validator compatible with useField's validate option
46
+ */
47
+ declare function standardSchemaResolver(schema: StandardSchemaV1): Validator;
48
+ /**
49
+ * Form-level Standard Schema adapter: validate the whole values object with
50
+ * any schema implementing '~standard' and return a ValidationOutcome. On
51
+ * failure `errors` carries the nested shape Options.validate expects
52
+ * ({a: {b: FieldError[]}}; ensureValidate flattens it back to per-field
53
+ * errors, keeping every issue of a path). Issues without a path are
54
+ * form-level errors and land on the '_form' key. On success `values`
55
+ * carries the schema's parsed output (coerce/transform results included),
56
+ * which the form stores as its parsedValues baseline — the layer getValues
57
+ * reads above initialValues, mirroring how react-hook-form's zodResolver
58
+ * and TanStack's standardSchemaValidators use the parsed value.
59
+ *
60
+ * @param schema a Standard Schema v1 (zod v3.24+/v4, valibot v1, arktype...)
61
+ * @return form-level validator for createForm({validate: ...})
62
+ */
63
+ declare function standardSchemaFormValidator<T extends Record<string, any>>(schema: StandardSchemaV1<T, any>): (values: T) => Promise<ValidationOutcome<T>>;
64
+
65
+ export { hasStandardProps, standardSchemaFormValidator, standardSchemaResolver };
66
+ export type { StandardSchemaIssue, StandardSchemaV1 };
@@ -0,0 +1,86 @@
1
+ import { V as VALIDATION_OUTCOME } from '../form-94c70b4b.mjs';
2
+
3
+ function hasStandardProps(schema) {
4
+ return !!schema && typeof schema === "object" && typeof schema["~standard"]?.validate === "function";
5
+ }
6
+ function toFieldError(issue) {
7
+ return { type: "standard", message: issue?.message || "Validation failed" };
8
+ }
9
+ function standardSchemaResolver(schema) {
10
+ return async (value) => {
11
+ const result = await schema["~standard"].validate(value);
12
+ if (!result.issues?.length) return void 0;
13
+ return result.issues.map(toFieldError);
14
+ };
15
+ }
16
+ function standardSchemaFormValidator(schema) {
17
+ return async (values) => {
18
+ const result = await schema["~standard"].validate(values);
19
+ const { issues } = result;
20
+ if (!issues?.length) {
21
+ return {
22
+ [VALIDATION_OUTCOME]: true,
23
+ values: "value" in result ? result.value : void 0
24
+ };
25
+ }
26
+ const errors = {};
27
+ for (const issue of issues) {
28
+ const segments = toPathSegments(issue);
29
+ if (segments.length) {
30
+ assignAtPath(errors, segments, toFieldError(issue));
31
+ } else {
32
+ const slot = errors._form ??= [];
33
+ if (Array.isArray(slot)) slot.push(toFieldError(issue));
34
+ }
35
+ }
36
+ return { [VALIDATION_OUTCOME]: true, errors: pruneEmpty(errors) || {} };
37
+ };
38
+ }
39
+ function toPathSegments(issue) {
40
+ const path = issue.path || [];
41
+ const segments = [];
42
+ for (const segment of path) {
43
+ const key = typeof segment === "object" && segment !== null ? segment.key : segment;
44
+ segments.push(String(key));
45
+ }
46
+ return segments;
47
+ }
48
+ function assignAtPath(root, segments, error) {
49
+ let node = root;
50
+ for (let i = 0; i < segments.length - 1; i++) {
51
+ const segment = segments[i];
52
+ let next = node[segment];
53
+ if (next === void 0) {
54
+ next = node[segment] = {};
55
+ }
56
+ if (!isBranch(next)) return;
57
+ node = next;
58
+ }
59
+ const leaf = segments[segments.length - 1];
60
+ const slot = node[leaf];
61
+ if (slot === void 0) node[leaf] = [error];
62
+ else if (Array.isArray(slot)) slot.push(error);
63
+ }
64
+ function isBranch(value) {
65
+ return !!value && typeof value === "object" && !Array.isArray(value);
66
+ }
67
+ function pruneEmpty(node) {
68
+ let hasLeaf = false;
69
+ const result = {};
70
+ Object.entries(node).forEach(([key, value]) => {
71
+ if (isBranch(value)) {
72
+ const pruned = pruneEmpty(value);
73
+ if (pruned) {
74
+ result[key] = pruned;
75
+ hasLeaf = true;
76
+ }
77
+ } else {
78
+ result[key] = value;
79
+ hasLeaf = true;
80
+ }
81
+ });
82
+ return hasLeaf ? result : void 0;
83
+ }
84
+
85
+ export { hasStandardProps, standardSchemaFormValidator, standardSchemaResolver };
86
+ //# sourceMappingURL=standard-schema.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard-schema.mjs","sources":["../../src/resolvers/standard-schema.ts"],"sourcesContent":["import {VALIDATION_OUTCOME} from '../form';\nimport type {FieldError, ValidationOutcome} from '../form';\nimport type {Validator} from '../hooks/validate';\n\n/**\n * Minimal copy of the Standard Schema v1 interfaces\n * (https://standardschema.dev) so this module has zero runtime and type\n * dependencies on any schema library. Implemented by zod v3.24+/v4,\n * valibot v1, arktype and others.\n */\nexport interface StandardSchemaIssue {\n readonly message: string;\n readonly path?:\n | ReadonlyArray<PropertyKey | {readonly key: PropertyKey}>\n | undefined;\n}\n\nexport interface StandardSchemaV1<Input = unknown, Output = Input> {\n readonly '~standard': {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (\n value: Input\n ) =>\n | {readonly value: Output; readonly issues?: undefined}\n | {readonly issues: ReadonlyArray<StandardSchemaIssue>}\n | Promise<\n | {readonly value: Output; readonly issues?: undefined}\n | {readonly issues: ReadonlyArray<StandardSchemaIssue>}\n >;\n };\n}\n\n/**\n * Does the schema implement the Standard Schema v1 props?\n */\nexport function hasStandardProps(schema: any): schema is StandardSchemaV1 {\n return (\n !!schema &&\n typeof schema === 'object' &&\n typeof schema['~standard']?.validate === 'function'\n );\n}\n\nfunction toFieldError(issue: StandardSchemaIssue | undefined): FieldError {\n return {type: 'standard', message: issue?.message || 'Validation failed'};\n}\n\n/**\n * Field-level Standard Schema adapter: validate a single value with any\n * schema implementing '~standard' and map every issue to a FieldError,\n * so a value breaking several rules surfaces all of them (setErrorByPath\n * stores the array; error/errorObject readers still see the first).\n *\n * @param schema a Standard Schema v1 (zod v3.24+/v4, valibot v1, arktype...)\n * @return field validator compatible with useField's validate option\n */\nexport function standardSchemaResolver(schema: StandardSchemaV1): Validator {\n return async (value: any) => {\n const result = await schema['~standard'].validate(value);\n if (!result.issues?.length) return undefined;\n return result.issues.map(toFieldError);\n };\n}\n\n/**\n * Form-level Standard Schema adapter: validate the whole values object with\n * any schema implementing '~standard' and return a ValidationOutcome. On\n * failure `errors` carries the nested shape Options.validate expects\n * ({a: {b: FieldError[]}}; ensureValidate flattens it back to per-field\n * errors, keeping every issue of a path). Issues without a path are\n * form-level errors and land on the '_form' key. On success `values`\n * carries the schema's parsed output (coerce/transform results included),\n * which the form stores as its parsedValues baseline — the layer getValues\n * reads above initialValues, mirroring how react-hook-form's zodResolver\n * and TanStack's standardSchemaValidators use the parsed value.\n *\n * @param schema a Standard Schema v1 (zod v3.24+/v4, valibot v1, arktype...)\n * @return form-level validator for createForm({validate: ...})\n */\nexport function standardSchemaFormValidator<T extends Record<string, any>>(\n schema: StandardSchemaV1<T, any>\n): (values: T) => Promise<ValidationOutcome<T>> {\n return async (values: T) => {\n const result = await schema['~standard'].validate(values);\n const {issues} = result;\n if (!issues?.length) {\n // Success: expose the schema's parsed output. `in` keeps the union\n // narrowed (the success variant is the one carrying `value`).\n return {\n [VALIDATION_OUTCOME]: true,\n values: 'value' in result ? result.value : undefined\n };\n }\n const errors: Record<string, any> = {};\n for (const issue of issues) {\n const segments = toPathSegments(issue);\n if (segments.length) {\n assignAtPath(errors, segments, toFieldError(issue));\n } else {\n // Pathless issues are all form-level: they accumulate on '_form'\n // instead of the first shadowing the rest. (A nested path literally\n // named '_form' would have made the slot a branch — skip then.)\n const slot = (errors._form ??= []);\n if (Array.isArray(slot)) slot.push(toFieldError(issue));\n }\n }\n return {[VALIDATION_OUTCOME]: true, errors: pruneEmpty(errors) || {}};\n };\n}\n\n/**\n * Stringify an issue path: PropertyKey or {key} path segments → strings.\n */\nfunction toPathSegments(issue: StandardSchemaIssue): string[] {\n const path = issue.path || [];\n const segments: string[] = [];\n for (const segment of path) {\n const key =\n typeof segment === 'object' && segment !== null\n ? (segment as {key: PropertyKey}).key\n : segment;\n segments.push(String(key));\n }\n return segments;\n}\n\n/**\n * Append the error at a nested path. Leaves are FieldError[] arrays, so\n * several issues on one field accumulate in issue order; an issue whose\n * path conflicts with an existing leaf or crosses it is skipped.\n */\nfunction assignAtPath(\n root: Record<string, any>,\n segments: string[],\n error: FieldError\n): void {\n let node = root;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n let next = node[segment];\n if (next === undefined) {\n next = node[segment] = {};\n }\n if (!isBranch(next)) return;\n node = next;\n }\n const leaf = segments[segments.length - 1];\n const slot = node[leaf];\n if (slot === undefined) node[leaf] = [error];\n else if (Array.isArray(slot)) slot.push(error);\n}\n\n/**\n * A branch is a plain container built while nesting; the leaves it carries\n * are the FieldError[] arrays assignAtPath appends.\n */\nfunction isBranch(value: any): value is Record<string, any> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Drop empty branch objects left behind by conflicting issue paths.\n */\nfunction pruneEmpty(\n node: Record<string, any>\n): Record<string, any> | undefined {\n let hasLeaf = false;\n const result: Record<string, any> = {};\n Object.entries(node).forEach(([key, value]) => {\n if (isBranch(value)) {\n const pruned = pruneEmpty(value);\n if (pruned) {\n result[key] = pruned;\n hasLeaf = true;\n }\n } else {\n result[key] = value;\n hasLeaf = true;\n }\n });\n return hasLeaf ? result : undefined;\n}\n"],"names":[],"mappings":"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"}
@@ -1,12 +1,22 @@
1
1
  'use strict';
2
2
 
3
+ var resolvers_standardSchema = require('./standard-schema.cjs.js');
4
+ require('../form-b9441d8c.cjs.js');
5
+
3
6
  function yupResolver(schema) {
7
+ if (resolvers_standardSchema.hasStandardProps(schema)) return resolvers_standardSchema.standardSchemaResolver(schema);
4
8
  return async (value) => {
5
9
  try {
6
- await schema.validate(value);
10
+ await schema.validate(value, { abortEarly: false });
7
11
  return void 0;
8
12
  } catch (err) {
9
- return err.message;
13
+ const issues = Array.isArray(err?.inner) && err.inner.length ? err.inner : [err];
14
+ return issues.map(
15
+ (issue) => ({
16
+ type: issue?.type || "custom",
17
+ message: issue?.message || "Validation failed"
18
+ })
19
+ );
10
20
  }
11
21
  };
12
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"yup.cjs.js","sources":["../../src/resolvers/yup.ts"],"sourcesContent":["import type {Validator} from '../hooks/validate';\n\nexport function yupResolver(schema: any): Validator {\n return async (value: any) => {\n try {\n await schema.validate(value);\n return undefined;\n } catch (err: any) {\n return err.message;\n }\n };\n}\n"],"names":[],"mappings":";;AAEO,SAAS,YAAY,MAAwB,EAAA;AAClD,EAAA,OAAO,OAAO,KAAe,KAAA;AAC3B,IAAI,IAAA;AACF,MAAM,MAAA,MAAA,CAAO,SAAS,KAAK,CAAA,CAAA;AAC3B,MAAO,OAAA,KAAA,CAAA,CAAA;AAAA,aACA,GAAU,EAAA;AACjB,MAAA,OAAO,GAAI,CAAA,OAAA,CAAA;AAAA,KACb;AAAA,GACF,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"yup.cjs.js","sources":["../../src/resolvers/yup.ts"],"sourcesContent":["import type {FieldError} from '../form';\nimport type {Validator} from '../hooks/validate';\nimport {hasStandardProps, standardSchemaResolver} from './standard-schema';\n\nexport function yupResolver(schema: any): Validator {\n // Recent yup versions implement the Standard Schema props — prefer them.\n if (hasStandardProps(schema)) return standardSchemaResolver(schema);\n // Older yup: fall back to the throw-based validate API. abortEarly:false\n // makes yup aggregate every failure into err.inner instead of throwing\n // on the first, so all of a field's errors reach the form.\n return async (value: any) => {\n try {\n await schema.validate(value, {abortEarly: false});\n return undefined;\n } catch (err: any) {\n const issues =\n Array.isArray(err?.inner) && err.inner.length ? err.inner : [err];\n return issues.map(\n (issue: any): FieldError => ({\n type: issue?.type || 'custom',\n message: issue?.message || 'Validation failed'\n })\n );\n }\n };\n}\n"],"names":["hasStandardProps","standardSchemaResolver"],"mappings":";;;;;AAIO,SAAS,YAAY,MAAwB,EAAA;AAElD,EAAA,IAAIA,yCAAiB,CAAA,MAAM,CAAG,EAAA,OAAOC,gDAAuB,MAAM,CAAA,CAAA;AAIlE,EAAA,OAAO,OAAO,KAAe,KAAA;AAC3B,IAAI,IAAA;AACF,MAAA,MAAM,OAAO,QAAS,CAAA,KAAA,EAAO,EAAC,UAAA,EAAY,OAAM,CAAA,CAAA;AAChD,MAAO,OAAA,KAAA,CAAA,CAAA;AAAA,aACA,GAAU,EAAA;AACjB,MAAA,MAAM,MACJ,GAAA,KAAA,CAAM,OAAQ,CAAA,GAAA,EAAK,KAAK,CAAA,IAAK,GAAI,CAAA,KAAA,CAAM,MAAS,GAAA,GAAA,CAAI,KAAQ,GAAA,CAAC,GAAG,CAAA,CAAA;AAClE,MAAA,OAAO,MAAO,CAAA,GAAA;AAAA,QACZ,CAAC,KAA4B,MAAA;AAAA,UAC3B,IAAA,EAAM,OAAO,IAAQ,IAAA,QAAA;AAAA,UACrB,OAAA,EAAS,OAAO,OAAW,IAAA,mBAAA;AAAA,SAC7B,CAAA;AAAA,OACF,CAAA;AAAA,KACF;AAAA,GACF,CAAA;AACF;;;;"}
@@ -1,5 +1,5 @@
1
- import { V as Validator } from '../validate-0f17f86a.js';
2
- import '../form-d06e6444.js';
1
+ import { V as Validator } from '../validate-148fe167.js';
2
+ import '../form-61297bc0.js';
3
3
  import '@for-fun/event-emitter';
4
4
 
5
5
  declare function yupResolver(schema: any): Validator;
@@ -0,0 +1,23 @@
1
+ import { hasStandardProps, standardSchemaResolver } from './standard-schema.mjs';
2
+ import '../form-94c70b4b.mjs';
3
+
4
+ function yupResolver(schema) {
5
+ if (hasStandardProps(schema)) return standardSchemaResolver(schema);
6
+ return async (value) => {
7
+ try {
8
+ await schema.validate(value, { abortEarly: false });
9
+ return void 0;
10
+ } catch (err) {
11
+ const issues = Array.isArray(err?.inner) && err.inner.length ? err.inner : [err];
12
+ return issues.map(
13
+ (issue) => ({
14
+ type: issue?.type || "custom",
15
+ message: issue?.message || "Validation failed"
16
+ })
17
+ );
18
+ }
19
+ };
20
+ }
21
+
22
+ export { yupResolver };
23
+ //# sourceMappingURL=yup.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yup.mjs","sources":["../../src/resolvers/yup.ts"],"sourcesContent":["import type {FieldError} from '../form';\nimport type {Validator} from '../hooks/validate';\nimport {hasStandardProps, standardSchemaResolver} from './standard-schema';\n\nexport function yupResolver(schema: any): Validator {\n // Recent yup versions implement the Standard Schema props — prefer them.\n if (hasStandardProps(schema)) return standardSchemaResolver(schema);\n // Older yup: fall back to the throw-based validate API. abortEarly:false\n // makes yup aggregate every failure into err.inner instead of throwing\n // on the first, so all of a field's errors reach the form.\n return async (value: any) => {\n try {\n await schema.validate(value, {abortEarly: false});\n return undefined;\n } catch (err: any) {\n const issues =\n Array.isArray(err?.inner) && err.inner.length ? err.inner : [err];\n return issues.map(\n (issue: any): FieldError => ({\n type: issue?.type || 'custom',\n message: issue?.message || 'Validation failed'\n })\n );\n }\n };\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,YAAY,MAAwB,EAAA;AAElD,EAAA,IAAI,gBAAiB,CAAA,MAAM,CAAG,EAAA,OAAO,uBAAuB,MAAM,CAAA,CAAA;AAIlE,EAAA,OAAO,OAAO,KAAe,KAAA;AAC3B,IAAI,IAAA;AACF,MAAA,MAAM,OAAO,QAAS,CAAA,KAAA,EAAO,EAAC,UAAA,EAAY,OAAM,CAAA,CAAA;AAChD,MAAO,OAAA,KAAA,CAAA,CAAA;AAAA,aACA,GAAU,EAAA;AACjB,MAAA,MAAM,MACJ,GAAA,KAAA,CAAM,OAAQ,CAAA,GAAA,EAAK,KAAK,CAAA,IAAK,GAAI,CAAA,KAAA,CAAM,MAAS,GAAA,GAAA,CAAI,KAAQ,GAAA,CAAC,GAAG,CAAA,CAAA;AAClE,MAAA,OAAO,MAAO,CAAA,GAAA;AAAA,QACZ,CAAC,KAA4B,MAAA;AAAA,UAC3B,IAAA,EAAM,OAAO,IAAQ,IAAA,QAAA;AAAA,UACrB,OAAA,EAAS,OAAO,OAAW,IAAA,mBAAA;AAAA,SAC7B,CAAA;AAAA,OACF,CAAA;AAAA,KACF;AAAA,GACF,CAAA;AACF;;;;"}
@@ -1,10 +1,23 @@
1
1
  'use strict';
2
2
 
3
+ var resolvers_standardSchema = require('./standard-schema.cjs.js');
4
+ require('../form-b9441d8c.cjs.js');
5
+
3
6
  function zodResolver(schema) {
7
+ if (resolvers_standardSchema.hasStandardProps(schema)) return resolvers_standardSchema.standardSchemaResolver(schema);
4
8
  return async (value) => {
5
9
  const result = await schema.safeParseAsync(value);
6
10
  if (result.success) return void 0;
7
- return result.error.issues[0]?.message || "Validation failed";
11
+ const { issues } = result.error;
12
+ if (!issues?.length) {
13
+ return [{ type: "custom", message: "Validation failed" }];
14
+ }
15
+ return issues.map(
16
+ (issue) => ({
17
+ type: issue?.code || "custom",
18
+ message: issue?.message || "Validation failed"
19
+ })
20
+ );
8
21
  };
9
22
  }
10
23
 
@@ -1 +1 @@
1
- {"version":3,"file":"zod.cjs.js","sources":["../../src/resolvers/zod.ts"],"sourcesContent":["import type {Validator} from '../hooks/validate';\n\nexport function zodResolver(schema: any): Validator {\n return async (value: any) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return undefined;\n return result.error.issues[0]?.message || 'Validation failed';\n };\n}\n"],"names":[],"mappings":";;AAEO,SAAS,YAAY,MAAwB,EAAA;AAClD,EAAA,OAAO,OAAO,KAAe,KAAA;AAC3B,IAAA,MAAM,MAAS,GAAA,MAAM,MAAO,CAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AAChD,IAAI,IAAA,MAAA,CAAO,SAAgB,OAAA,KAAA,CAAA,CAAA;AAC3B,IAAA,OAAO,MAAO,CAAA,KAAA,CAAM,MAAO,CAAA,CAAC,GAAG,OAAW,IAAA,mBAAA,CAAA;AAAA,GAC5C,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"zod.cjs.js","sources":["../../src/resolvers/zod.ts"],"sourcesContent":["import type {FieldError} from '../form';\nimport type {Validator} from '../hooks/validate';\nimport {hasStandardProps, standardSchemaResolver} from './standard-schema';\n\nexport function zodResolver(schema: any): Validator {\n // zod v3.24+/v4 schemas carry the Standard Schema props — prefer them.\n if (hasStandardProps(schema)) return standardSchemaResolver(schema);\n // Older zod: fall back to the legacy safeParseAsync API. It aggregates\n // every issue (no abortEarly), so map them all — a value breaking\n // several rules surfaces all of its errors.\n return async (value: any) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return undefined;\n const {issues} = result.error;\n if (!issues?.length) {\n return [{type: 'custom', message: 'Validation failed'}];\n }\n return issues.map(\n (issue: any): FieldError => ({\n type: issue?.code || 'custom',\n message: issue?.message || 'Validation failed'\n })\n );\n };\n}\n"],"names":["hasStandardProps","standardSchemaResolver"],"mappings":";;;;;AAIO,SAAS,YAAY,MAAwB,EAAA;AAElD,EAAA,IAAIA,yCAAiB,CAAA,MAAM,CAAG,EAAA,OAAOC,gDAAuB,MAAM,CAAA,CAAA;AAIlE,EAAA,OAAO,OAAO,KAAe,KAAA;AAC3B,IAAA,MAAM,MAAS,GAAA,MAAM,MAAO,CAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AAChD,IAAI,IAAA,MAAA,CAAO,SAAgB,OAAA,KAAA,CAAA,CAAA;AAC3B,IAAM,MAAA,EAAC,MAAM,EAAA,GAAI,MAAO,CAAA,KAAA,CAAA;AACxB,IAAI,IAAA,CAAC,QAAQ,MAAQ,EAAA;AACnB,MAAA,OAAO,CAAC,EAAC,IAAA,EAAM,QAAU,EAAA,OAAA,EAAS,qBAAoB,CAAA,CAAA;AAAA,KACxD;AACA,IAAA,OAAO,MAAO,CAAA,GAAA;AAAA,MACZ,CAAC,KAA4B,MAAA;AAAA,QAC3B,IAAA,EAAM,OAAO,IAAQ,IAAA,QAAA;AAAA,QACrB,OAAA,EAAS,OAAO,OAAW,IAAA,mBAAA;AAAA,OAC7B,CAAA;AAAA,KACF,CAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -1,5 +1,5 @@
1
- import { V as Validator } from '../validate-0f17f86a.js';
2
- import '../form-d06e6444.js';
1
+ import { V as Validator } from '../validate-148fe167.js';
2
+ import '../form-61297bc0.js';
3
3
  import '@for-fun/event-emitter';
4
4
 
5
5
  declare function zodResolver(schema: any): Validator;
@@ -0,0 +1,23 @@
1
+ import { hasStandardProps, standardSchemaResolver } from './standard-schema.mjs';
2
+ import '../form-94c70b4b.mjs';
3
+
4
+ function zodResolver(schema) {
5
+ if (hasStandardProps(schema)) return standardSchemaResolver(schema);
6
+ return async (value) => {
7
+ const result = await schema.safeParseAsync(value);
8
+ if (result.success) return void 0;
9
+ const { issues } = result.error;
10
+ if (!issues?.length) {
11
+ return [{ type: "custom", message: "Validation failed" }];
12
+ }
13
+ return issues.map(
14
+ (issue) => ({
15
+ type: issue?.code || "custom",
16
+ message: issue?.message || "Validation failed"
17
+ })
18
+ );
19
+ };
20
+ }
21
+
22
+ export { zodResolver };
23
+ //# sourceMappingURL=zod.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.mjs","sources":["../../src/resolvers/zod.ts"],"sourcesContent":["import type {FieldError} from '../form';\nimport type {Validator} from '../hooks/validate';\nimport {hasStandardProps, standardSchemaResolver} from './standard-schema';\n\nexport function zodResolver(schema: any): Validator {\n // zod v3.24+/v4 schemas carry the Standard Schema props — prefer them.\n if (hasStandardProps(schema)) return standardSchemaResolver(schema);\n // Older zod: fall back to the legacy safeParseAsync API. It aggregates\n // every issue (no abortEarly), so map them all — a value breaking\n // several rules surfaces all of its errors.\n return async (value: any) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return undefined;\n const {issues} = result.error;\n if (!issues?.length) {\n return [{type: 'custom', message: 'Validation failed'}];\n }\n return issues.map(\n (issue: any): FieldError => ({\n type: issue?.code || 'custom',\n message: issue?.message || 'Validation failed'\n })\n );\n };\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,YAAY,MAAwB,EAAA;AAElD,EAAA,IAAI,gBAAiB,CAAA,MAAM,CAAG,EAAA,OAAO,uBAAuB,MAAM,CAAA,CAAA;AAIlE,EAAA,OAAO,OAAO,KAAe,KAAA;AAC3B,IAAA,MAAM,MAAS,GAAA,MAAM,MAAO,CAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AAChD,IAAI,IAAA,MAAA,CAAO,SAAgB,OAAA,KAAA,CAAA,CAAA;AAC3B,IAAM,MAAA,EAAC,MAAM,EAAA,GAAI,MAAO,CAAA,KAAA,CAAA;AACxB,IAAI,IAAA,CAAC,QAAQ,MAAQ,EAAA;AACnB,MAAA,OAAO,CAAC,EAAC,IAAA,EAAM,QAAU,EAAA,OAAA,EAAS,qBAAoB,CAAA,CAAA;AAAA,KACxD;AACA,IAAA,OAAO,MAAO,CAAA,GAAA;AAAA,MACZ,CAAC,KAA4B,MAAA;AAAA,QAC3B,IAAA,EAAM,OAAO,IAAQ,IAAA,QAAA;AAAA,QACrB,OAAA,EAAS,OAAO,OAAW,IAAA,mBAAA;AAAA,OAC7B,CAAA;AAAA,KACF,CAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -0,0 +1,22 @@
1
+ import { a as Form, c as Path, b as FieldError } from './form-61297bc0.js';
2
+
3
+ /**
4
+ * Field validator. Returns an error (a string, a FieldError, or an array
5
+ * mixing both) or undefined when valid; may return a Promise for async
6
+ * validation.
7
+ *
8
+ * The second argument carries the validation context. `meta.signal` is
9
+ * aborted as soon as the round is superseded — a newer round started, or
10
+ * the field unregistered — so async validators can cancel their underlying
11
+ * work (fetch, timers) instead of racing a stale result home. Stale
12
+ * results are dropped independently by useValidate's lock, so validators
13
+ * that ignore the signal stay correct too. Validators written against the
14
+ * older two-argument signature keep working.
15
+ */
16
+ type Validator = (value: any, meta: {
17
+ form: Form;
18
+ path: Path;
19
+ signal: AbortSignal;
20
+ }) => string | FieldError | (string | FieldError)[] | undefined | Promise<string | FieldError | (string | FieldError)[] | undefined>;
21
+
22
+ export type { Validator as V };
package/package.json CHANGED
@@ -1,26 +1,36 @@
1
1
  {
2
2
  "name": "react-f0rm",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "packageManager": "pnpm@11.4.0",
5
5
  "description": "react form",
6
6
  "main": "dist/index.cjs.js",
7
- "module": "dist/index.esm.js",
7
+ "module": "dist/index.mjs",
8
8
  "unpkg": "dist/index.umd.min.js",
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/index.d.ts",
12
- "import": "./dist/index.esm.js",
12
+ "import": "./dist/index.mjs",
13
13
  "require": "./dist/index.cjs.js"
14
14
  },
15
+ "./resolvers/standard-schema": {
16
+ "types": "./dist/resolvers/standard-schema.d.ts",
17
+ "import": "./dist/resolvers/standard-schema.mjs",
18
+ "require": "./dist/resolvers/standard-schema.cjs.js"
19
+ },
15
20
  "./resolvers/zod": {
16
21
  "types": "./dist/resolvers/zod.d.ts",
17
- "import": "./dist/resolvers/zod.esm.js",
22
+ "import": "./dist/resolvers/zod.mjs",
18
23
  "require": "./dist/resolvers/zod.cjs.js"
19
24
  },
20
25
  "./resolvers/yup": {
21
26
  "types": "./dist/resolvers/yup.d.ts",
22
- "import": "./dist/resolvers/yup.esm.js",
27
+ "import": "./dist/resolvers/yup.mjs",
23
28
  "require": "./dist/resolvers/yup.cjs.js"
29
+ },
30
+ "./devtools": {
31
+ "types": "./dist/devtools/index.d.ts",
32
+ "import": "./dist/devtools/index.mjs",
33
+ "require": "./dist/devtools/index.cjs.js"
24
34
  }
25
35
  },
26
36
  "types": "dist/index.d.ts",
@@ -62,7 +72,21 @@
62
72
  },
63
73
  "homepage": "https://github.com/wmzy/react-f0rm#readme",
64
74
  "peerDependencies": {
65
- "react": ">=16.8.0"
75
+ "react": ">=16.8.0",
76
+ "valibot": ">=1.0.0",
77
+ "yup": ">=0.32.0",
78
+ "zod": ">=3.0.0"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "valibot": {
82
+ "optional": true
83
+ },
84
+ "yup": {
85
+ "optional": true
86
+ },
87
+ "zod": {
88
+ "optional": true
89
+ }
66
90
  },
67
91
  "devDependencies": {
68
92
  "@babel/core": "^7.22.8",
@@ -110,6 +134,7 @@
110
134
  "prettier": "^3.0.0",
111
135
  "react": "^18.2.0",
112
136
  "react-dom": "^18.2.0",
137
+ "react-hook-form": "^7.85.0",
113
138
  "rimraf": "^5.0.1",
114
139
  "rollup": "^3.26.2",
115
140
  "rollup-plugin-dts": "^6.4.1",
@@ -120,11 +145,12 @@
120
145
  "vitest": "^3.0.0"
121
146
  },
122
147
  "dependencies": {
123
- "@for-fun/event-emitter": "^1.0.0"
148
+ "@for-fun/event-emitter": "^1.0.0",
149
+ "use-sync-external-store": "^1.6.0"
124
150
  },
125
151
  "size-limit": [
126
152
  {
127
- "path": "dist/index.esm.js",
153
+ "path": "dist/index.mjs",
128
154
  "limit": "10 KB"
129
155
  }
130
156
  ]