@pyreon/validation 0.3.0 → 0.7.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.
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"95cef231-1","name":"utils.ts"},{"uid":"95cef231-3","name":"zod.ts"},{"uid":"95cef231-5","name":"valibot.ts"},{"uid":"95cef231-7","name":"arktype.ts"},{"uid":"95cef231-9","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"95cef231-1":{"renderedLength":452,"gzipLength":302,"brotliLength":0,"metaUid":"95cef231-0"},"95cef231-3":{"renderedLength":1636,"gzipLength":620,"brotliLength":0,"metaUid":"95cef231-2"},"95cef231-5":{"renderedLength":1879,"gzipLength":695,"brotliLength":0,"metaUid":"95cef231-4"},"95cef231-7":{"renderedLength":1677,"gzipLength":643,"brotliLength":0,"metaUid":"95cef231-6"},"95cef231-9":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"95cef231-8"}},"nodeMetas":{"95cef231-0":{"id":"/src/utils.ts","moduleParts":{"index.js":"95cef231-1"},"imported":[],"importedBy":[{"uid":"95cef231-8"},{"uid":"95cef231-2"},{"uid":"95cef231-4"},{"uid":"95cef231-6"}]},"95cef231-2":{"id":"/src/zod.ts","moduleParts":{"index.js":"95cef231-3"},"imported":[{"uid":"95cef231-0"}],"importedBy":[{"uid":"95cef231-8"}]},"95cef231-4":{"id":"/src/valibot.ts","moduleParts":{"index.js":"95cef231-5"},"imported":[{"uid":"95cef231-0"}],"importedBy":[{"uid":"95cef231-8"}]},"95cef231-6":{"id":"/src/arktype.ts","moduleParts":{"index.js":"95cef231-7"},"imported":[{"uid":"95cef231-0"}],"importedBy":[{"uid":"95cef231-8"}]},"95cef231-8":{"id":"/src/index.ts","moduleParts":{"index.js":"95cef231-9"},"imported":[{"uid":"95cef231-2"},{"uid":"95cef231-4"},{"uid":"95cef231-6"},{"uid":"95cef231-0"}],"importedBy":[],"isEntry":true}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"99584f89-1","name":"utils.ts"},{"uid":"99584f89-3","name":"arktype.ts"},{"uid":"99584f89-5","name":"valibot.ts"},{"uid":"99584f89-7","name":"zod.ts"},{"uid":"99584f89-9","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"99584f89-1":{"renderedLength":452,"gzipLength":302,"brotliLength":0,"metaUid":"99584f89-0"},"99584f89-3":{"renderedLength":1677,"gzipLength":643,"brotliLength":0,"metaUid":"99584f89-2"},"99584f89-5":{"renderedLength":1879,"gzipLength":695,"brotliLength":0,"metaUid":"99584f89-4"},"99584f89-7":{"renderedLength":1636,"gzipLength":620,"brotliLength":0,"metaUid":"99584f89-6"},"99584f89-9":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"99584f89-8"}},"nodeMetas":{"99584f89-0":{"id":"/src/utils.ts","moduleParts":{"index.js":"99584f89-1"},"imported":[],"importedBy":[{"uid":"99584f89-8"},{"uid":"99584f89-2"},{"uid":"99584f89-4"},{"uid":"99584f89-6"}]},"99584f89-2":{"id":"/src/arktype.ts","moduleParts":{"index.js":"99584f89-3"},"imported":[{"uid":"99584f89-0"}],"importedBy":[{"uid":"99584f89-8"}]},"99584f89-4":{"id":"/src/valibot.ts","moduleParts":{"index.js":"99584f89-5"},"imported":[{"uid":"99584f89-0"}],"importedBy":[{"uid":"99584f89-8"}]},"99584f89-6":{"id":"/src/zod.ts","moduleParts":{"index.js":"99584f89-7"},"imported":[{"uid":"99584f89-0"}],"importedBy":[{"uid":"99584f89-8"}]},"99584f89-8":{"id":"/src/index.ts","moduleParts":{"index.js":"99584f89-9"},"imported":[{"uid":"99584f89-2"},{"uid":"99584f89-0"},{"uid":"99584f89-4"},{"uid":"99584f89-6"}],"importedBy":[],"isEntry":true}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
@@ -1 +1 @@
1
- {"version":3,"file":"arktype.js","names":[],"sources":["../src/utils.ts","../src/arktype.ts"],"sourcesContent":["import type { ValidationError } from '@pyreon/form'\nimport type { ValidationIssue } from './types'\n\n/**\n * Convert an array of validation issues into a flat field → error record.\n * For nested paths like [\"address\", \"city\"], produces \"address.city\".\n * When multiple issues exist for the same path, the first message wins.\n */\nexport function issuesToRecord<TValues extends Record<string, unknown>>(\n issues: ValidationIssue[],\n): Partial<Record<keyof TValues, ValidationError>> {\n const errors = {} as Partial<Record<keyof TValues, ValidationError>>\n for (const issue of issues) {\n const key = issue.path as keyof TValues\n // First error per field wins\n if (errors[key] === undefined) {\n errors[key] = issue.message\n }\n }\n return errors\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal ArkType-compatible interfaces so we don't require arktype as a hard dep.\n */\ninterface ArkError {\n path: PropertyKey[]\n message: string\n}\n\ninterface ArkErrors extends Array<ArkError> {\n summary: string\n}\n\n/**\n * Internal callable interface matching ArkType's Type.\n * Not exposed publicly — consumers pass their ArkType schema directly.\n */\ninterface ArkTypeCallable {\n (data: unknown): unknown\n}\n\nfunction isArkErrors(result: unknown): result is ArkErrors {\n return Array.isArray(result) && 'summary' in (result as object)\n}\n\nfunction arkIssuesToGeneric(errors: ArkErrors): ValidationIssue[] {\n return errors.map((err) => ({\n path: err.path.map(String).join('.'),\n message: err.message,\n }))\n}\n\n/**\n * Create a form-level schema validator from an ArkType schema.\n *\n * Accepts any callable ArkType `Type` instance. The schema is duck-typed —\n * no ArkType import required.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeSchema } from '@pyreon/validation/arktype'\n *\n * const schema = type({\n * email: 'string.email',\n * password: 'string >= 8',\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: arktypeSchema(schema),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeSchema<TValues extends Record<string, unknown>>(\n schema: ArkTypeCallable,\n): SchemaValidateFn<TValues> {\n return (values: TValues) => {\n try {\n const result = schema(values)\n if (!isArkErrors(result))\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(arkIssuesToGeneric(result))\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from an ArkType schema.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeField } from '@pyreon/validation/arktype'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: arktypeField(type('string.email')),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeField<T>(schema: ArkTypeCallable): ValidateFn<T> {\n return (value: T) => {\n try {\n const result = schema(value)\n if (!isArkErrors(result)) return undefined\n return result[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,eACd,QACiD;CACjD,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,MAAM,MAAM;AAElB,MAAI,OAAO,SAAS,OAClB,QAAO,OAAO,MAAM;;AAGxB,QAAO;;;;;ACST,SAAS,YAAY,QAAsC;AACzD,QAAO,MAAM,QAAQ,OAAO,IAAI,aAAc;;AAGhD,SAAS,mBAAmB,QAAsC;AAChE,QAAO,OAAO,KAAK,SAAS;EAC1B,MAAM,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK,IAAI;EACpC,SAAS,IAAI;EACd,EAAE;;;;;;;;;;;;;;;;;;;;;;;AAwBL,SAAgB,cACd,QAC2B;AAC3B,SAAQ,WAAoB;AAC1B,MAAI;GACF,MAAM,SAAS,OAAO,OAAO;AAC7B,OAAI,CAAC,YAAY,OAAO,CACtB,QAAO,EAAE;AACX,UAAO,eAAwB,mBAAmB,OAAO,CAAC;WACnD,KAAK;AACZ,UAAO,EACL,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,EACrD;;;;;;;;;;;;;;;;;;;AAoBP,SAAgB,aAAgB,QAAwC;AACtE,SAAQ,UAAa;AACnB,MAAI;GACF,MAAM,SAAS,OAAO,MAAM;AAC5B,OAAI,CAAC,YAAY,OAAO,CAAE,QAAO;AACjC,UAAO,OAAO,IAAI;WACX,KAAK;AACZ,UAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI"}
1
+ {"version":3,"file":"arktype.js","names":[],"sources":["../src/utils.ts","../src/arktype.ts"],"sourcesContent":["import type { ValidationError } from '@pyreon/form'\nimport type { ValidationIssue } from './types'\n\n/**\n * Convert an array of validation issues into a flat field → error record.\n * For nested paths like [\"address\", \"city\"], produces \"address.city\".\n * When multiple issues exist for the same path, the first message wins.\n */\nexport function issuesToRecord<TValues extends Record<string, unknown>>(\n issues: ValidationIssue[],\n): Partial<Record<keyof TValues, ValidationError>> {\n const errors = {} as Partial<Record<keyof TValues, ValidationError>>\n for (const issue of issues) {\n const key = issue.path as keyof TValues\n // First error per field wins\n if (errors[key] === undefined) {\n errors[key] = issue.message\n }\n }\n return errors\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal ArkType-compatible interfaces so we don't require arktype as a hard dep.\n */\ninterface ArkError {\n path: PropertyKey[]\n message: string\n}\n\ninterface ArkErrors extends Array<ArkError> {\n summary: string\n}\n\n/**\n * Internal callable interface matching ArkType's Type.\n * Not exposed publicly — consumers pass their ArkType schema directly.\n */\ntype ArkTypeCallable = (data: unknown) => unknown\n\nfunction isArkErrors(result: unknown): result is ArkErrors {\n return Array.isArray(result) && 'summary' in (result as object)\n}\n\nfunction arkIssuesToGeneric(errors: ArkErrors): ValidationIssue[] {\n return errors.map((err) => ({\n path: err.path.map(String).join('.'),\n message: err.message,\n }))\n}\n\n/**\n * Create a form-level schema validator from an ArkType schema.\n *\n * Accepts any callable ArkType `Type` instance. The schema is duck-typed —\n * no ArkType import required.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeSchema } from '@pyreon/validation/arktype'\n *\n * const schema = type({\n * email: 'string.email',\n * password: 'string >= 8',\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: arktypeSchema(schema),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeSchema<TValues extends Record<string, unknown>>(\n schema: ArkTypeCallable,\n): SchemaValidateFn<TValues> {\n return (values: TValues) => {\n try {\n const result = schema(values)\n if (!isArkErrors(result))\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(arkIssuesToGeneric(result))\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from an ArkType schema.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeField } from '@pyreon/validation/arktype'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: arktypeField(type('string.email')),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeField<T>(schema: ArkTypeCallable): ValidateFn<T> {\n return (value: T) => {\n try {\n const result = schema(value)\n if (!isArkErrors(result)) return undefined\n return result[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,eACd,QACiD;CACjD,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,MAAM,MAAM;AAElB,MAAI,OAAO,SAAS,OAClB,QAAO,OAAO,MAAM;;AAGxB,QAAO;;;;;ACOT,SAAS,YAAY,QAAsC;AACzD,QAAO,MAAM,QAAQ,OAAO,IAAI,aAAc;;AAGhD,SAAS,mBAAmB,QAAsC;AAChE,QAAO,OAAO,KAAK,SAAS;EAC1B,MAAM,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK,IAAI;EACpC,SAAS,IAAI;EACd,EAAE;;;;;;;;;;;;;;;;;;;;;;;AAwBL,SAAgB,cACd,QAC2B;AAC3B,SAAQ,WAAoB;AAC1B,MAAI;GACF,MAAM,SAAS,OAAO,OAAO;AAC7B,OAAI,CAAC,YAAY,OAAO,CACtB,QAAO,EAAE;AACX,UAAO,eAAwB,mBAAmB,OAAO,CAAC;WACnD,KAAK;AACZ,UAAO,EACL,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,EACrD;;;;;;;;;;;;;;;;;;;AAoBP,SAAgB,aAAgB,QAAwC;AACtE,SAAQ,UAAa;AACnB,MAAI;GACF,MAAM,SAAS,OAAO,MAAM;AAC5B,OAAI,CAAC,YAAY,OAAO,CAAE,QAAO;AACjC,UAAO,OAAO,IAAI;WACX,KAAK;AACZ,UAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI"}
package/lib/index.js CHANGED
@@ -14,65 +14,69 @@ function issuesToRecord(issues) {
14
14
  }
15
15
 
16
16
  //#endregion
17
- //#region src/zod.ts
18
- function zodIssuesToGeneric(issues) {
19
- return issues.map((issue) => ({
20
- path: issue.path.map(String).join("."),
21
- message: issue.message
17
+ //#region src/arktype.ts
18
+ function isArkErrors(result) {
19
+ return Array.isArray(result) && "summary" in result;
20
+ }
21
+ function arkIssuesToGeneric(errors) {
22
+ return errors.map((err) => ({
23
+ path: err.path.map(String).join("."),
24
+ message: err.message
22
25
  }));
23
26
  }
24
27
  /**
25
- * Create a form-level schema validator from a Zod schema.
26
- * Supports both sync and async Zod schemas (uses `safeParseAsync`).
28
+ * Create a form-level schema validator from an ArkType schema.
29
+ *
30
+ * Accepts any callable ArkType `Type` instance. The schema is duck-typed —
31
+ * no ArkType import required.
27
32
  *
28
33
  * @example
29
- * import { z } from 'zod'
30
- * import { zodSchema } from '@pyreon/validation/zod'
34
+ * import { type } from 'arktype'
35
+ * import { arktypeSchema } from '@pyreon/validation/arktype'
31
36
  *
32
- * const schema = z.object({
33
- * email: z.string().email(),
34
- * password: z.string().min(8),
37
+ * const schema = type({
38
+ * email: 'string.email',
39
+ * password: 'string >= 8',
35
40
  * })
36
41
  *
37
42
  * const form = useForm({
38
43
  * initialValues: { email: '', password: '' },
39
- * schema: zodSchema(schema),
44
+ * schema: arktypeSchema(schema),
40
45
  * onSubmit: (values) => { ... },
41
46
  * })
42
47
  */
43
- function zodSchema(schema) {
44
- return async (values) => {
48
+ function arktypeSchema(schema) {
49
+ return (values) => {
45
50
  try {
46
- const result = await schema.safeParseAsync(values);
47
- if (result.success) return {};
48
- return issuesToRecord(zodIssuesToGeneric(result.error.issues));
51
+ const result = schema(values);
52
+ if (!isArkErrors(result)) return {};
53
+ return issuesToRecord(arkIssuesToGeneric(result));
49
54
  } catch (err) {
50
55
  return { "": err instanceof Error ? err.message : String(err) };
51
56
  }
52
57
  };
53
58
  }
54
59
  /**
55
- * Create a single-field validator from a Zod schema.
56
- * Supports both sync and async Zod refinements.
60
+ * Create a single-field validator from an ArkType schema.
57
61
  *
58
62
  * @example
59
- * import { z } from 'zod'
60
- * import { zodField } from '@pyreon/validation/zod'
63
+ * import { type } from 'arktype'
64
+ * import { arktypeField } from '@pyreon/validation/arktype'
61
65
  *
62
66
  * const form = useForm({
63
67
  * initialValues: { email: '' },
64
68
  * validators: {
65
- * email: zodField(z.string().email('Invalid email')),
69
+ * email: arktypeField(type('string.email')),
66
70
  * },
67
71
  * onSubmit: (values) => { ... },
68
72
  * })
69
73
  */
70
- function zodField(schema) {
71
- return async (value) => {
74
+ function arktypeField(schema) {
75
+ return (value) => {
72
76
  try {
73
- const result = await schema.safeParseAsync(value);
74
- if (result.success) return void 0;
75
- return result.error.issues[0]?.message;
77
+ const result = schema(value);
78
+ if (!isArkErrors(result)) return void 0;
79
+ return result[0]?.message;
76
80
  } catch (err) {
77
81
  return err instanceof Error ? err.message : String(err);
78
82
  }
@@ -149,69 +153,65 @@ function valibotField(schema, safeParseFn) {
149
153
  }
150
154
 
151
155
  //#endregion
152
- //#region src/arktype.ts
153
- function isArkErrors(result) {
154
- return Array.isArray(result) && "summary" in result;
155
- }
156
- function arkIssuesToGeneric(errors) {
157
- return errors.map((err) => ({
158
- path: err.path.map(String).join("."),
159
- message: err.message
156
+ //#region src/zod.ts
157
+ function zodIssuesToGeneric(issues) {
158
+ return issues.map((issue) => ({
159
+ path: issue.path.map(String).join("."),
160
+ message: issue.message
160
161
  }));
161
162
  }
162
163
  /**
163
- * Create a form-level schema validator from an ArkType schema.
164
- *
165
- * Accepts any callable ArkType `Type` instance. The schema is duck-typed —
166
- * no ArkType import required.
164
+ * Create a form-level schema validator from a Zod schema.
165
+ * Supports both sync and async Zod schemas (uses `safeParseAsync`).
167
166
  *
168
167
  * @example
169
- * import { type } from 'arktype'
170
- * import { arktypeSchema } from '@pyreon/validation/arktype'
168
+ * import { z } from 'zod'
169
+ * import { zodSchema } from '@pyreon/validation/zod'
171
170
  *
172
- * const schema = type({
173
- * email: 'string.email',
174
- * password: 'string >= 8',
171
+ * const schema = z.object({
172
+ * email: z.string().email(),
173
+ * password: z.string().min(8),
175
174
  * })
176
175
  *
177
176
  * const form = useForm({
178
177
  * initialValues: { email: '', password: '' },
179
- * schema: arktypeSchema(schema),
178
+ * schema: zodSchema(schema),
180
179
  * onSubmit: (values) => { ... },
181
180
  * })
182
181
  */
183
- function arktypeSchema(schema) {
184
- return (values) => {
182
+ function zodSchema(schema) {
183
+ return async (values) => {
185
184
  try {
186
- const result = schema(values);
187
- if (!isArkErrors(result)) return {};
188
- return issuesToRecord(arkIssuesToGeneric(result));
185
+ const result = await schema.safeParseAsync(values);
186
+ if (result.success) return {};
187
+ return issuesToRecord(zodIssuesToGeneric(result.error.issues));
189
188
  } catch (err) {
190
189
  return { "": err instanceof Error ? err.message : String(err) };
191
190
  }
192
191
  };
193
192
  }
194
193
  /**
195
- * Create a single-field validator from an ArkType schema.
194
+ * Create a single-field validator from a Zod schema.
195
+ * Supports both sync and async Zod refinements.
196
196
  *
197
197
  * @example
198
- * import { type } from 'arktype'
199
- * import { arktypeField } from '@pyreon/validation/arktype'
198
+ * import { z } from 'zod'
199
+ * import { zodField } from '@pyreon/validation/zod'
200
200
  *
201
201
  * const form = useForm({
202
202
  * initialValues: { email: '' },
203
203
  * validators: {
204
- * email: arktypeField(type('string.email')),
204
+ * email: zodField(z.string().email('Invalid email')),
205
205
  * },
206
206
  * onSubmit: (values) => { ... },
207
207
  * })
208
208
  */
209
- function arktypeField(schema) {
210
- return (value) => {
209
+ function zodField(schema) {
210
+ return async (value) => {
211
211
  try {
212
- const result = schema(value);
213
- if (!isArkErrors(result)) return void 0;
214
- return result[0]?.message;
212
+ const result = await schema.safeParseAsync(value);
213
+ if (result.success) return void 0;
214
+ return result.error.issues[0]?.message;
215
215
  } catch (err) {
216
216
  return err instanceof Error ? err.message : String(err);
217
217
  }
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/zod.ts","../src/valibot.ts","../src/arktype.ts"],"sourcesContent":["import type { ValidationError } from '@pyreon/form'\nimport type { ValidationIssue } from './types'\n\n/**\n * Convert an array of validation issues into a flat field → error record.\n * For nested paths like [\"address\", \"city\"], produces \"address.city\".\n * When multiple issues exist for the same path, the first message wins.\n */\nexport function issuesToRecord<TValues extends Record<string, unknown>>(\n issues: ValidationIssue[],\n): Partial<Record<keyof TValues, ValidationError>> {\n const errors = {} as Partial<Record<keyof TValues, ValidationError>>\n for (const issue of issues) {\n const key = issue.path as keyof TValues\n // First error per field wins\n if (errors[key] === undefined) {\n errors[key] = issue.message\n }\n }\n return errors\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal Zod-compatible interfaces so we don't require zod as a hard dep.\n * These match Zod v3's public API surface.\n */\ninterface ZodIssue {\n path: PropertyKey[]\n message: string\n}\n\n/**\n * Duck-typed Zod schema interface — works with both Zod v3 and v4.\n * Inlines the result shape to avoid version-specific type mismatches.\n */\ninterface ZodSchema<T = unknown> {\n safeParse(data: unknown): {\n success: boolean\n data?: T\n error?: { issues: ZodIssue[] }\n }\n safeParseAsync(\n data: unknown,\n ): Promise<{ success: boolean; data?: T; error?: { issues: ZodIssue[] } }>\n}\n\nfunction zodIssuesToGeneric(issues: ZodIssue[]): ValidationIssue[] {\n return issues.map((issue) => ({\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }))\n}\n\n/**\n * Create a form-level schema validator from a Zod schema.\n * Supports both sync and async Zod schemas (uses `safeParseAsync`).\n *\n * @example\n * import { z } from 'zod'\n * import { zodSchema } from '@pyreon/validation/zod'\n *\n * const schema = z.object({\n * email: z.string().email(),\n * password: z.string().min(8),\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: zodSchema(schema),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function zodSchema<TValues extends Record<string, unknown>>(\n schema: ZodSchema<TValues>,\n): SchemaValidateFn<TValues> {\n return async (values: TValues) => {\n try {\n const result = await schema.safeParseAsync(values)\n if (result.success)\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(zodIssuesToGeneric(result.error!.issues))\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from a Zod schema.\n * Supports both sync and async Zod refinements.\n *\n * @example\n * import { z } from 'zod'\n * import { zodField } from '@pyreon/validation/zod'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: zodField(z.string().email('Invalid email')),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function zodField<T>(schema: ZodSchema<T>): ValidateFn<T> {\n return async (value: T) => {\n try {\n const result = await schema.safeParseAsync(value)\n if (result.success) return undefined\n return result.error!.issues[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal Valibot-compatible interfaces so we don't require valibot as a hard dep.\n */\ninterface ValibotPathItem {\n key: string | number\n}\n\ninterface ValibotIssue {\n path?: ValibotPathItem[]\n message: string\n}\n\ninterface ValibotSafeParseResult {\n success: boolean\n output?: unknown\n issues?: ValibotIssue[]\n}\n\n/**\n * Any function that takes (schema, input, ...rest) and returns a parse result.\n * Valibot's safeParse/safeParseAsync have generic constraints on the schema\n * parameter that can't be expressed without importing Valibot types. We accept\n * any callable and cast internally.\n */\n// biome-ignore lint/complexity/noBannedTypes: must accept any valibot parse function\ntype GenericSafeParseFn = Function\n\nfunction valibotIssuesToGeneric(issues: ValibotIssue[]): ValidationIssue[] {\n return issues.map((issue) => ({\n path: issue.path?.map((p) => String(p.key)).join('.') ?? '',\n message: issue.message,\n }))\n}\n\ntype InternalParseFn = (\n schema: unknown,\n input: unknown,\n) => ValibotSafeParseResult | Promise<ValibotSafeParseResult>\n\n/**\n * Create a form-level schema validator from a Valibot schema.\n *\n * Valibot uses standalone functions rather than methods, so you must pass\n * the `safeParseAsync` (or `safeParse`) function from valibot.\n *\n * @example\n * import * as v from 'valibot'\n * import { valibotSchema } from '@pyreon/validation/valibot'\n *\n * const schema = v.object({\n * email: v.pipe(v.string(), v.email()),\n * password: v.pipe(v.string(), v.minLength(8)),\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: valibotSchema(schema, v.safeParseAsync),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function valibotSchema<TValues extends Record<string, unknown>>(\n schema: unknown,\n safeParseFn: GenericSafeParseFn,\n): SchemaValidateFn<TValues> {\n const parse = safeParseFn as InternalParseFn\n return async (values: TValues) => {\n try {\n const result = await parse(schema, values)\n if (result.success)\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(\n valibotIssuesToGeneric(result.issues ?? []),\n )\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from a Valibot schema.\n *\n * @example\n * import * as v from 'valibot'\n * import { valibotField } from '@pyreon/validation/valibot'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: valibotField(v.pipe(v.string(), v.email('Invalid email')), v.safeParseAsync),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function valibotField<T>(\n schema: unknown,\n safeParseFn: GenericSafeParseFn,\n): ValidateFn<T> {\n const parse = safeParseFn as InternalParseFn\n return async (value: T) => {\n try {\n const result = await parse(schema, value)\n if (result.success) return undefined\n return result.issues?.[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal ArkType-compatible interfaces so we don't require arktype as a hard dep.\n */\ninterface ArkError {\n path: PropertyKey[]\n message: string\n}\n\ninterface ArkErrors extends Array<ArkError> {\n summary: string\n}\n\n/**\n * Internal callable interface matching ArkType's Type.\n * Not exposed publicly — consumers pass their ArkType schema directly.\n */\ninterface ArkTypeCallable {\n (data: unknown): unknown\n}\n\nfunction isArkErrors(result: unknown): result is ArkErrors {\n return Array.isArray(result) && 'summary' in (result as object)\n}\n\nfunction arkIssuesToGeneric(errors: ArkErrors): ValidationIssue[] {\n return errors.map((err) => ({\n path: err.path.map(String).join('.'),\n message: err.message,\n }))\n}\n\n/**\n * Create a form-level schema validator from an ArkType schema.\n *\n * Accepts any callable ArkType `Type` instance. The schema is duck-typed —\n * no ArkType import required.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeSchema } from '@pyreon/validation/arktype'\n *\n * const schema = type({\n * email: 'string.email',\n * password: 'string >= 8',\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: arktypeSchema(schema),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeSchema<TValues extends Record<string, unknown>>(\n schema: ArkTypeCallable,\n): SchemaValidateFn<TValues> {\n return (values: TValues) => {\n try {\n const result = schema(values)\n if (!isArkErrors(result))\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(arkIssuesToGeneric(result))\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from an ArkType schema.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeField } from '@pyreon/validation/arktype'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: arktypeField(type('string.email')),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeField<T>(schema: ArkTypeCallable): ValidateFn<T> {\n return (value: T) => {\n try {\n const result = schema(value)\n if (!isArkErrors(result)) return undefined\n return result[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,eACd,QACiD;CACjD,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,MAAM,MAAM;AAElB,MAAI,OAAO,SAAS,OAClB,QAAO,OAAO,MAAM;;AAGxB,QAAO;;;;;ACaT,SAAS,mBAAmB,QAAuC;AACjE,QAAO,OAAO,KAAK,WAAW;EAC5B,MAAM,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,IAAI;EACtC,SAAS,MAAM;EAChB,EAAE;;;;;;;;;;;;;;;;;;;;;AAsBL,SAAgB,UACd,QAC2B;AAC3B,QAAO,OAAO,WAAoB;AAChC,MAAI;GACF,MAAM,SAAS,MAAM,OAAO,eAAe,OAAO;AAClD,OAAI,OAAO,QACT,QAAO,EAAE;AACX,UAAO,eAAwB,mBAAmB,OAAO,MAAO,OAAO,CAAC;WACjE,KAAK;AACZ,UAAO,EACL,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,EACrD;;;;;;;;;;;;;;;;;;;;AAqBP,SAAgB,SAAY,QAAqC;AAC/D,QAAO,OAAO,UAAa;AACzB,MAAI;GACF,MAAM,SAAS,MAAM,OAAO,eAAe,MAAM;AACjD,OAAI,OAAO,QAAS,QAAO;AAC3B,UAAO,OAAO,MAAO,OAAO,IAAI;WACzB,KAAK;AACZ,UAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;;;;;;;AC/D7D,SAAS,uBAAuB,QAA2C;AACzE,QAAO,OAAO,KAAK,WAAW;EAC5B,MAAM,MAAM,MAAM,KAAK,MAAM,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI;EACzD,SAAS,MAAM;EAChB,EAAE;;;;;;;;;;;;;;;;;;;;;;;AA6BL,SAAgB,cACd,QACA,aAC2B;CAC3B,MAAM,QAAQ;AACd,QAAO,OAAO,WAAoB;AAChC,MAAI;GACF,MAAM,SAAS,MAAM,MAAM,QAAQ,OAAO;AAC1C,OAAI,OAAO,QACT,QAAO,EAAE;AACX,UAAO,eACL,uBAAuB,OAAO,UAAU,EAAE,CAAC,CAC5C;WACM,KAAK;AACZ,UAAO,EACL,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,EACrD;;;;;;;;;;;;;;;;;;;AAoBP,SAAgB,aACd,QACA,aACe;CACf,MAAM,QAAQ;AACd,QAAO,OAAO,UAAa;AACzB,MAAI;GACF,MAAM,SAAS,MAAM,MAAM,QAAQ,MAAM;AACzC,OAAI,OAAO,QAAS,QAAO;AAC3B,UAAO,OAAO,SAAS,IAAI;WACpB,KAAK;AACZ,UAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;;;;;;;ACvF7D,SAAS,YAAY,QAAsC;AACzD,QAAO,MAAM,QAAQ,OAAO,IAAI,aAAc;;AAGhD,SAAS,mBAAmB,QAAsC;AAChE,QAAO,OAAO,KAAK,SAAS;EAC1B,MAAM,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK,IAAI;EACpC,SAAS,IAAI;EACd,EAAE;;;;;;;;;;;;;;;;;;;;;;;AAwBL,SAAgB,cACd,QAC2B;AAC3B,SAAQ,WAAoB;AAC1B,MAAI;GACF,MAAM,SAAS,OAAO,OAAO;AAC7B,OAAI,CAAC,YAAY,OAAO,CACtB,QAAO,EAAE;AACX,UAAO,eAAwB,mBAAmB,OAAO,CAAC;WACnD,KAAK;AACZ,UAAO,EACL,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,EACrD;;;;;;;;;;;;;;;;;;;AAoBP,SAAgB,aAAgB,QAAwC;AACtE,SAAQ,UAAa;AACnB,MAAI;GACF,MAAM,SAAS,OAAO,MAAM;AAC5B,OAAI,CAAC,YAAY,OAAO,CAAE,QAAO;AACjC,UAAO,OAAO,IAAI;WACX,KAAK;AACZ,UAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/arktype.ts","../src/valibot.ts","../src/zod.ts"],"sourcesContent":["import type { ValidationError } from '@pyreon/form'\nimport type { ValidationIssue } from './types'\n\n/**\n * Convert an array of validation issues into a flat field → error record.\n * For nested paths like [\"address\", \"city\"], produces \"address.city\".\n * When multiple issues exist for the same path, the first message wins.\n */\nexport function issuesToRecord<TValues extends Record<string, unknown>>(\n issues: ValidationIssue[],\n): Partial<Record<keyof TValues, ValidationError>> {\n const errors = {} as Partial<Record<keyof TValues, ValidationError>>\n for (const issue of issues) {\n const key = issue.path as keyof TValues\n // First error per field wins\n if (errors[key] === undefined) {\n errors[key] = issue.message\n }\n }\n return errors\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal ArkType-compatible interfaces so we don't require arktype as a hard dep.\n */\ninterface ArkError {\n path: PropertyKey[]\n message: string\n}\n\ninterface ArkErrors extends Array<ArkError> {\n summary: string\n}\n\n/**\n * Internal callable interface matching ArkType's Type.\n * Not exposed publicly — consumers pass their ArkType schema directly.\n */\ntype ArkTypeCallable = (data: unknown) => unknown\n\nfunction isArkErrors(result: unknown): result is ArkErrors {\n return Array.isArray(result) && 'summary' in (result as object)\n}\n\nfunction arkIssuesToGeneric(errors: ArkErrors): ValidationIssue[] {\n return errors.map((err) => ({\n path: err.path.map(String).join('.'),\n message: err.message,\n }))\n}\n\n/**\n * Create a form-level schema validator from an ArkType schema.\n *\n * Accepts any callable ArkType `Type` instance. The schema is duck-typed —\n * no ArkType import required.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeSchema } from '@pyreon/validation/arktype'\n *\n * const schema = type({\n * email: 'string.email',\n * password: 'string >= 8',\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: arktypeSchema(schema),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeSchema<TValues extends Record<string, unknown>>(\n schema: ArkTypeCallable,\n): SchemaValidateFn<TValues> {\n return (values: TValues) => {\n try {\n const result = schema(values)\n if (!isArkErrors(result))\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(arkIssuesToGeneric(result))\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from an ArkType schema.\n *\n * @example\n * import { type } from 'arktype'\n * import { arktypeField } from '@pyreon/validation/arktype'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: arktypeField(type('string.email')),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function arktypeField<T>(schema: ArkTypeCallable): ValidateFn<T> {\n return (value: T) => {\n try {\n const result = schema(value)\n if (!isArkErrors(result)) return undefined\n return result[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal Valibot-compatible interfaces so we don't require valibot as a hard dep.\n */\ninterface ValibotPathItem {\n key: string | number\n}\n\ninterface ValibotIssue {\n path?: ValibotPathItem[]\n message: string\n}\n\ninterface ValibotSafeParseResult {\n success: boolean\n output?: unknown\n issues?: ValibotIssue[]\n}\n\n/**\n * Any function that takes (schema, input, ...rest) and returns a parse result.\n * Valibot's safeParse/safeParseAsync have generic constraints on the schema\n * parameter that can't be expressed without importing Valibot types. We accept\n * any callable and cast internally.\n */\n// biome-ignore lint/complexity/noBannedTypes: must accept any valibot parse function\ntype GenericSafeParseFn = Function\n\nfunction valibotIssuesToGeneric(issues: ValibotIssue[]): ValidationIssue[] {\n return issues.map((issue) => ({\n path: issue.path?.map((p) => String(p.key)).join('.') ?? '',\n message: issue.message,\n }))\n}\n\ntype InternalParseFn = (\n schema: unknown,\n input: unknown,\n) => ValibotSafeParseResult | Promise<ValibotSafeParseResult>\n\n/**\n * Create a form-level schema validator from a Valibot schema.\n *\n * Valibot uses standalone functions rather than methods, so you must pass\n * the `safeParseAsync` (or `safeParse`) function from valibot.\n *\n * @example\n * import * as v from 'valibot'\n * import { valibotSchema } from '@pyreon/validation/valibot'\n *\n * const schema = v.object({\n * email: v.pipe(v.string(), v.email()),\n * password: v.pipe(v.string(), v.minLength(8)),\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: valibotSchema(schema, v.safeParseAsync),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function valibotSchema<TValues extends Record<string, unknown>>(\n schema: unknown,\n safeParseFn: GenericSafeParseFn,\n): SchemaValidateFn<TValues> {\n const parse = safeParseFn as InternalParseFn\n return async (values: TValues) => {\n try {\n const result = await parse(schema, values)\n if (result.success)\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(\n valibotIssuesToGeneric(result.issues ?? []),\n )\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from a Valibot schema.\n *\n * @example\n * import * as v from 'valibot'\n * import { valibotField } from '@pyreon/validation/valibot'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: valibotField(v.pipe(v.string(), v.email('Invalid email')), v.safeParseAsync),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function valibotField<T>(\n schema: unknown,\n safeParseFn: GenericSafeParseFn,\n): ValidateFn<T> {\n const parse = safeParseFn as InternalParseFn\n return async (value: T) => {\n try {\n const result = await parse(schema, value)\n if (result.success) return undefined\n return result.issues?.[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n","import type {\n SchemaValidateFn,\n ValidateFn,\n ValidationError,\n} from '@pyreon/form'\nimport type { ValidationIssue } from './types'\nimport { issuesToRecord } from './utils'\n\n/**\n * Minimal Zod-compatible interfaces so we don't require zod as a hard dep.\n * These match Zod v3's public API surface.\n */\ninterface ZodIssue {\n path: PropertyKey[]\n message: string\n}\n\n/**\n * Duck-typed Zod schema interface — works with both Zod v3 and v4.\n * Inlines the result shape to avoid version-specific type mismatches.\n */\ninterface ZodSchema<T = unknown> {\n safeParse(data: unknown): {\n success: boolean\n data?: T\n error?: { issues: ZodIssue[] }\n }\n safeParseAsync(\n data: unknown,\n ): Promise<{ success: boolean; data?: T; error?: { issues: ZodIssue[] } }>\n}\n\nfunction zodIssuesToGeneric(issues: ZodIssue[]): ValidationIssue[] {\n return issues.map((issue) => ({\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }))\n}\n\n/**\n * Create a form-level schema validator from a Zod schema.\n * Supports both sync and async Zod schemas (uses `safeParseAsync`).\n *\n * @example\n * import { z } from 'zod'\n * import { zodSchema } from '@pyreon/validation/zod'\n *\n * const schema = z.object({\n * email: z.string().email(),\n * password: z.string().min(8),\n * })\n *\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * schema: zodSchema(schema),\n * onSubmit: (values) => { ... },\n * })\n */\nexport function zodSchema<TValues extends Record<string, unknown>>(\n schema: ZodSchema<TValues>,\n): SchemaValidateFn<TValues> {\n return async (values: TValues) => {\n try {\n const result = await schema.safeParseAsync(values)\n if (result.success)\n return {} as Partial<Record<keyof TValues, ValidationError>>\n return issuesToRecord<TValues>(zodIssuesToGeneric(result.error!.issues))\n } catch (err) {\n return {\n '': err instanceof Error ? err.message : String(err),\n } as Partial<Record<keyof TValues, ValidationError>>\n }\n }\n}\n\n/**\n * Create a single-field validator from a Zod schema.\n * Supports both sync and async Zod refinements.\n *\n * @example\n * import { z } from 'zod'\n * import { zodField } from '@pyreon/validation/zod'\n *\n * const form = useForm({\n * initialValues: { email: '' },\n * validators: {\n * email: zodField(z.string().email('Invalid email')),\n * },\n * onSubmit: (values) => { ... },\n * })\n */\nexport function zodField<T>(schema: ZodSchema<T>): ValidateFn<T> {\n return async (value: T) => {\n try {\n const result = await schema.safeParseAsync(value)\n if (result.success) return undefined\n return result.error!.issues[0]?.message\n } catch (err) {\n return err instanceof Error ? err.message : String(err)\n }\n }\n}\n"],"mappings":"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"}
@@ -1,90 +1,49 @@
1
- //#region src/utils.ts
2
- /**
3
- * Convert an array of validation issues into a flat field → error record.
4
- * For nested paths like ["address", "city"], produces "address.city".
5
- * When multiple issues exist for the same path, the first message wins.
6
- */
7
- function issuesToRecord(issues) {
8
- const errors = {};
9
- for (const issue of issues) {
10
- const key = issue.path;
11
- if (errors[key] === void 0) errors[key] = issue.message;
12
- }
13
- return errors;
14
- }
1
+ import { SchemaValidateFn, ValidateFn } from "@pyreon/form";
15
2
 
16
- //#endregion
17
- //#region src/arktype.ts
18
- function isArkErrors(result) {
19
- return Array.isArray(result) && "summary" in result;
20
- }
21
- function arkIssuesToGeneric(errors) {
22
- return errors.map(err => ({
23
- path: err.path.map(String).join("."),
24
- message: err.message
25
- }));
26
- }
3
+ //#region src/arktype.d.ts
27
4
  /**
28
- * Create a form-level schema validator from an ArkType schema.
29
- *
30
- * Accepts any callable ArkType `Type` instance. The schema is duck-typed —
31
- * no ArkType import required.
32
- *
33
- * @example
34
- * import { type } from 'arktype'
35
- * import { arktypeSchema } from '@pyreon/validation/arktype'
36
- *
37
- * const schema = type({
38
- * email: 'string.email',
39
- * password: 'string >= 8',
40
- * })
41
- *
42
- * const form = useForm({
43
- * initialValues: { email: '', password: '' },
44
- * schema: arktypeSchema(schema),
45
- * onSubmit: (values) => { ... },
46
- * })
47
- */
48
- function arktypeSchema(schema) {
49
- return values => {
50
- try {
51
- const result = schema(values);
52
- if (!isArkErrors(result)) return {};
53
- return issuesToRecord(arkIssuesToGeneric(result));
54
- } catch (err) {
55
- return {
56
- "": err instanceof Error ? err.message : String(err)
57
- };
58
- }
59
- };
60
- }
5
+ * Internal callable interface matching ArkType's Type.
6
+ * Not exposed publicly — consumers pass their ArkType schema directly.
7
+ */
8
+ type ArkTypeCallable = (data: unknown) => unknown;
61
9
  /**
62
- * Create a single-field validator from an ArkType schema.
63
- *
64
- * @example
65
- * import { type } from 'arktype'
66
- * import { arktypeField } from '@pyreon/validation/arktype'
67
- *
68
- * const form = useForm({
69
- * initialValues: { email: '' },
70
- * validators: {
71
- * email: arktypeField(type('string.email')),
72
- * },
73
- * onSubmit: (values) => { ... },
74
- * })
75
- */
76
- function arktypeField(schema) {
77
- return value => {
78
- try {
79
- const result = schema(value);
80
- if (!isArkErrors(result)) return void 0;
81
- return result[0]?.message;
82
- } catch (err) {
83
- return err instanceof Error ? err.message : String(err);
84
- }
85
- };
86
- }
87
-
10
+ * Create a form-level schema validator from an ArkType schema.
11
+ *
12
+ * Accepts any callable ArkType `Type` instance. The schema is duck-typed —
13
+ * no ArkType import required.
14
+ *
15
+ * @example
16
+ * import { type } from 'arktype'
17
+ * import { arktypeSchema } from '@pyreon/validation/arktype'
18
+ *
19
+ * const schema = type({
20
+ * email: 'string.email',
21
+ * password: 'string >= 8',
22
+ * })
23
+ *
24
+ * const form = useForm({
25
+ * initialValues: { email: '', password: '' },
26
+ * schema: arktypeSchema(schema),
27
+ * onSubmit: (values) => { ... },
28
+ * })
29
+ */
30
+ declare function arktypeSchema<TValues extends Record<string, unknown>>(schema: ArkTypeCallable): SchemaValidateFn<TValues>;
31
+ /**
32
+ * Create a single-field validator from an ArkType schema.
33
+ *
34
+ * @example
35
+ * import { type } from 'arktype'
36
+ * import { arktypeField } from '@pyreon/validation/arktype'
37
+ *
38
+ * const form = useForm({
39
+ * initialValues: { email: '' },
40
+ * validators: {
41
+ * email: arktypeField(type('string.email')),
42
+ * },
43
+ * onSubmit: (values) => { ... },
44
+ * })
45
+ */
46
+ declare function arktypeField<T>(schema: ArkTypeCallable): ValidateFn<T>;
88
47
  //#endregion
89
48
  export { arktypeField, arktypeSchema };
90
- //# sourceMappingURL=arktype.d.ts.map
49
+ //# sourceMappingURL=arktype2.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"arktype.d.ts","names":[],"sources":["../../src/utils.ts","../../src/arktype.ts"],"mappings":";;;;;;AAQA,SAAgB,cAAA,CACd,MAAA,EACiD;EACjD,MAAM,MAAA,GAAS,CAAA,CAAE;EACjB,KAAK,MAAM,KAAA,IAAS,MAAA,EAAQ;IAC1B,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA;IAElB,IAAI,MAAA,CAAO,GAAA,CAAA,KAAS,KAAA,CAAA,EAClB,MAAA,CAAO,GAAA,CAAA,GAAO,KAAA,CAAM,OAAA;;EAGxB,OAAO,MAAA;;;;;ACST,SAAS,WAAA,CAAY,MAAA,EAAsC;EACzD,OAAO,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,SAAA,IAAc,MAAA;;AAGhD,SAAS,kBAAA,CAAmB,MAAA,EAAsC;EAChE,OAAO,MAAA,CAAO,GAAA,CAAK,GAAA,KAAS;IAC1B,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,CAAC,IAAA,CAAK,GAAA,CAAI;IACpC,OAAA,EAAS,GAAA,CAAI;GACd,CAAA,CAAE;;;;;;;;;;;;;;;;;;;;;;;AAwBL,SAAgB,aAAA,CACd,MAAA,EAC2B;EAC3B,OAAQ,MAAA,IAAoB;IAC1B,IAAI;MACF,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO;MAC7B,IAAI,CAAC,WAAA,CAAY,MAAA,CAAO,EACtB,OAAO,CAAA,CAAE;MACX,OAAO,cAAA,CAAwB,kBAAA,CAAmB,MAAA,CAAO,CAAC;aACnD,GAAA,EAAK;MACZ,OAAO;QACL,EAAA,EAAI,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAA;MAAI,CACrD;;;;;;;;;;;;;;;;;;;AAoBP,SAAgB,YAAA,CAAgB,MAAA,EAAwC;EACtE,OAAQ,KAAA,IAAa;IACnB,IAAI;MACF,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM;MAC5B,IAAI,CAAC,WAAA,CAAY,MAAA,CAAO,EAAE,OAAO,KAAA,CAAA;MACjC,OAAO,MAAA,CAAO,CAAA,CAAA,EAAI,OAAA;aACX,GAAA,EAAK;MACZ,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAA,CAAI"}
1
+ {"version":3,"file":"arktype2.d.ts","names":[],"sources":["../../../src/arktype.ts"],"mappings":";;;;;AAIqB;;KAoBhB,eAAA,IAAmB,IAAA;;;AAkCxB;;;;;;;;;;;;;;;;;AAgCA;;iBAhCgB,aAAA,iBAA8B,MAAA,kBAAA,CAC5C,MAAA,EAAQ,eAAA,GACP,gBAAA,CAAiB,OAAA;;;;;;;;;;;;;;;;iBA8BJ,YAAA,GAAA,CAAgB,MAAA,EAAQ,eAAA,GAAkB,UAAA,CAAW,CAAA"}