@logixjs/form 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Form.d.cts CHANGED
@@ -1,19 +1,11 @@
1
- import { r as rules } from './impl-Ccdm5eDF.cjs';
2
- export { f as FormAction, j as FormController, F as FormErrors, i as FormExtendDef, k as FormHandleExt, h as FormMakeConfig, d as FormMeta, l as FormModule, g as FormShape, e as FormState, c as FormUiState, n as RuleDescriptor, o as RuleScope, R as RulesDsl, p as RulesManifest, a as RulesNode, b as RulesSpec, m as make } from './impl-Ccdm5eDF.cjs';
1
+ import { R as RulesDsl } from './impl-DWIHAuQq.cjs';
2
+ export { f as FormAction, j as FormController, F as FormErrors, i as FormExtendDef, k as FormHandleExt, h as FormMakeConfig, d as FormMeta, l as FormModule, g as FormShape, e as FormState, c as FormUiState, n as RuleDescriptor, o as RuleScope, p as RulesManifest, a as RulesNode, b as RulesSpec, m as make, r as rules } from './impl-DWIHAuQq.cjs';
3
3
  import { Schema } from 'effect';
4
- import { D as DerivedSpec } from './Trait-Bu794ROY.cjs';
5
4
  import * as Logix from '@logixjs/core';
5
+ import { D as DerivedSpec } from './Trait-Bu794ROY.cjs';
6
6
  import { j as RuleEntry } from './Rule-BOAiSVz9.cjs';
7
7
  export { d as CanonicalListItem, c as CanonicalListPath, C as CanonicalPath, b as CanonicalValue, F as FieldPath, a as FieldValue } from './Rule-BOAiSVz9.cjs';
8
8
 
9
- /**
10
- * Form.derived:
11
- * - Provides "type narrowing based on the values schema" for derived specs, so you can compose derived fragments
12
- * without losing type information.
13
- * - Does no extra runtime normalization; final validation is still governed by Form.make guardrails.
14
- */
15
- declare const derived: <TValues extends object, I>(_valuesSchema: Schema.Schema<TValues, I>) => (spec: DerivedSpec<TValues>) => DerivedSpec<TValues>;
16
-
17
9
  type NonNull<T> = Exclude<T, null | undefined>;
18
10
  type ListItem<T> = NonNull<T> extends readonly (infer Item)[] ? Item : never;
19
11
  type NodeSpec$1<Input = unknown, Ctx = unknown> = Omit<Logix.StateTrait.StateTraitNode<Input, Ctx>, '_tag' | 'check'> & {
@@ -38,17 +30,28 @@ type TraitsSpec<TValues extends object> = {
38
30
  * - Form defaults `check.deps=[]`; only declare deps when you need "cross-field linked validation triggers".
39
31
  * - Returns a StateTraitSpec fragment that can be spread directly (assembled by Form.make).
40
32
  */
41
- declare const traits: <TValues extends object, I>(_valuesSchema: Schema.Schema<TValues, I>) => {
33
+ declare const traits: <TValues extends object>(_valuesSchema: Schema.Schema<TValues>) => {
42
34
  (spec: TraitsSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
43
35
  (spec: Logix.StateTrait.StateTraitSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
44
36
  };
45
37
 
46
38
  type FormFrom<TValues extends object> = Readonly<{
47
- readonly derived: ReturnType<typeof derived<TValues, any>>;
48
- readonly rules: ReturnType<typeof rules<TValues, any>>;
49
- readonly traits: ReturnType<typeof traits<TValues, any>>;
39
+ readonly derived: (spec: DerivedSpec<TValues>) => DerivedSpec<TValues>;
40
+ readonly rules: RulesDsl<TValues>;
41
+ readonly traits: {
42
+ (spec: TraitsSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
43
+ (spec: Logix.StateTrait.StateTraitSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
44
+ };
50
45
  }>;
51
- declare const fromValues: <TValues extends object, I>(valuesSchema: Schema.Schema<TValues, I>) => FormFrom<TValues>;
46
+ declare const fromValues: <TValues extends object>(valuesSchema: Schema.Schema<TValues>) => FormFrom<TValues>;
47
+
48
+ /**
49
+ * Form.derived:
50
+ * - Provides "type narrowing based on the values schema" for derived specs, so you can compose derived fragments
51
+ * without losing type information.
52
+ * - Does no extra runtime normalization; final validation is still governed by Form.make guardrails.
53
+ */
54
+ declare const derived: <TValues extends object>(_valuesSchema: Schema.Schema<TValues>) => (spec: DerivedSpec<TValues>) => DerivedSpec<TValues>;
52
55
 
53
56
  type NodeSpec<Input = unknown, Ctx = unknown> = Omit<Logix.StateTrait.StateTraitNode<Input, Ctx>, '_tag' | 'check'> & {
54
57
  readonly check?: Readonly<Record<string, RuleEntry<Input, Ctx>>>;
@@ -61,4 +64,4 @@ type ListSpec<Item = unknown> = Omit<Logix.StateTrait.StateTraitList<Item>, '_ta
61
64
  };
62
65
  declare const list: <Item = unknown>(spec: ListSpec<Item>) => Logix.StateTrait.StateTraitList<Item>;
63
66
 
64
- export { type FormFrom, type ListSpec$1 as ListSpec, type NodeSpec$1 as NodeSpec, type TraitsSpec, derived, fromValues, list, node, rules, traits };
67
+ export { type FormFrom, type ListSpec$1 as ListSpec, type NodeSpec$1 as NodeSpec, RulesDsl, type TraitsSpec, derived, fromValues, list, node, traits };
package/dist/Form.d.ts CHANGED
@@ -1,19 +1,11 @@
1
- import { r as rules } from './impl-BfSlyM58.js';
2
- export { f as FormAction, j as FormController, F as FormErrors, i as FormExtendDef, k as FormHandleExt, h as FormMakeConfig, d as FormMeta, l as FormModule, g as FormShape, e as FormState, c as FormUiState, n as RuleDescriptor, o as RuleScope, R as RulesDsl, p as RulesManifest, a as RulesNode, b as RulesSpec, m as make } from './impl-BfSlyM58.js';
1
+ import { R as RulesDsl } from './impl-DXbfEc3o.js';
2
+ export { f as FormAction, j as FormController, F as FormErrors, i as FormExtendDef, k as FormHandleExt, h as FormMakeConfig, d as FormMeta, l as FormModule, g as FormShape, e as FormState, c as FormUiState, n as RuleDescriptor, o as RuleScope, p as RulesManifest, a as RulesNode, b as RulesSpec, m as make, r as rules } from './impl-DXbfEc3o.js';
3
3
  import { Schema } from 'effect';
4
- import { D as DerivedSpec } from './Trait-Bu794ROY.js';
5
4
  import * as Logix from '@logixjs/core';
5
+ import { D as DerivedSpec } from './Trait-Bu794ROY.js';
6
6
  import { j as RuleEntry } from './Rule-BOAiSVz9.js';
7
7
  export { d as CanonicalListItem, c as CanonicalListPath, C as CanonicalPath, b as CanonicalValue, F as FieldPath, a as FieldValue } from './Rule-BOAiSVz9.js';
8
8
 
9
- /**
10
- * Form.derived:
11
- * - Provides "type narrowing based on the values schema" for derived specs, so you can compose derived fragments
12
- * without losing type information.
13
- * - Does no extra runtime normalization; final validation is still governed by Form.make guardrails.
14
- */
15
- declare const derived: <TValues extends object, I>(_valuesSchema: Schema.Schema<TValues, I>) => (spec: DerivedSpec<TValues>) => DerivedSpec<TValues>;
16
-
17
9
  type NonNull<T> = Exclude<T, null | undefined>;
18
10
  type ListItem<T> = NonNull<T> extends readonly (infer Item)[] ? Item : never;
19
11
  type NodeSpec$1<Input = unknown, Ctx = unknown> = Omit<Logix.StateTrait.StateTraitNode<Input, Ctx>, '_tag' | 'check'> & {
@@ -38,17 +30,28 @@ type TraitsSpec<TValues extends object> = {
38
30
  * - Form defaults `check.deps=[]`; only declare deps when you need "cross-field linked validation triggers".
39
31
  * - Returns a StateTraitSpec fragment that can be spread directly (assembled by Form.make).
40
32
  */
41
- declare const traits: <TValues extends object, I>(_valuesSchema: Schema.Schema<TValues, I>) => {
33
+ declare const traits: <TValues extends object>(_valuesSchema: Schema.Schema<TValues>) => {
42
34
  (spec: TraitsSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
43
35
  (spec: Logix.StateTrait.StateTraitSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
44
36
  };
45
37
 
46
38
  type FormFrom<TValues extends object> = Readonly<{
47
- readonly derived: ReturnType<typeof derived<TValues, any>>;
48
- readonly rules: ReturnType<typeof rules<TValues, any>>;
49
- readonly traits: ReturnType<typeof traits<TValues, any>>;
39
+ readonly derived: (spec: DerivedSpec<TValues>) => DerivedSpec<TValues>;
40
+ readonly rules: RulesDsl<TValues>;
41
+ readonly traits: {
42
+ (spec: TraitsSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
43
+ (spec: Logix.StateTrait.StateTraitSpec<TValues>): Logix.StateTrait.StateTraitSpec<TValues>;
44
+ };
50
45
  }>;
51
- declare const fromValues: <TValues extends object, I>(valuesSchema: Schema.Schema<TValues, I>) => FormFrom<TValues>;
46
+ declare const fromValues: <TValues extends object>(valuesSchema: Schema.Schema<TValues>) => FormFrom<TValues>;
47
+
48
+ /**
49
+ * Form.derived:
50
+ * - Provides "type narrowing based on the values schema" for derived specs, so you can compose derived fragments
51
+ * without losing type information.
52
+ * - Does no extra runtime normalization; final validation is still governed by Form.make guardrails.
53
+ */
54
+ declare const derived: <TValues extends object>(_valuesSchema: Schema.Schema<TValues>) => (spec: DerivedSpec<TValues>) => DerivedSpec<TValues>;
52
55
 
53
56
  type NodeSpec<Input = unknown, Ctx = unknown> = Omit<Logix.StateTrait.StateTraitNode<Input, Ctx>, '_tag' | 'check'> & {
54
57
  readonly check?: Readonly<Record<string, RuleEntry<Input, Ctx>>>;
@@ -61,4 +64,4 @@ type ListSpec<Item = unknown> = Omit<Logix.StateTrait.StateTraitList<Item>, '_ta
61
64
  };
62
65
  declare const list: <Item = unknown>(spec: ListSpec<Item>) => Logix.StateTrait.StateTraitList<Item>;
63
66
 
64
- export { type FormFrom, type ListSpec$1 as ListSpec, type NodeSpec$1 as NodeSpec, type TraitsSpec, derived, fromValues, list, node, rules, traits };
67
+ export { type FormFrom, type ListSpec$1 as ListSpec, type NodeSpec$1 as NodeSpec, RulesDsl, type TraitsSpec, derived, fromValues, list, node, traits };
package/dist/Form.js CHANGED
@@ -6,8 +6,8 @@ import {
6
6
  node,
7
7
  rules,
8
8
  traits
9
- } from "./chunk-YHDEJ47V.js";
10
- import "./chunk-YVHXLY63.js";
9
+ } from "./chunk-WGBRLVRO.js";
10
+ import "./chunk-3U6VHYYQ.js";
11
11
  import "./chunk-JZ5FZKPJ.js";
12
12
  import "./chunk-5DRI5UGD.js";
13
13
  import "./chunk-OJVEZKU7.js";
package/dist/Rule.cjs CHANGED
@@ -38,7 +38,6 @@ __export(Rule_exports, {
38
38
  module.exports = __toCommonJS(Rule_exports);
39
39
 
40
40
  // src/internal/validators/index.ts
41
- var import_effect = require("effect");
42
41
  var ERROR_VALUE_MAX_BYTES = 256;
43
42
  var textEncoder = new TextEncoder();
44
43
  var jsonByteSize = (value) => {
package/dist/Rule.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Rule.ts","../src/internal/validators/index.ts"],"sourcesContent":["import type * as Logix from '@logixjs/core'\nimport * as Validators from './internal/validators/index.js'\nimport type { CanonicalPath } from './internal/form/types.js'\n\nexport type AutoValidateOn = 'onChange' | 'onBlur'\n\nexport type RuleValidateOn = ReadonlyArray<AutoValidateOn>\n\nexport type RuleFn<Input, Ctx = unknown> = (input: Input, ctx: Ctx) => unknown | undefined\n\ntype RuleDeps<Input> = Input extends object\n ? CanonicalPath<Input> extends never\n ? string\n : CanonicalPath<Input>\n : string\n\nexport type Rule<Input, Ctx = unknown> = Logix.StateTrait.CheckRule<Input, Ctx> & {\n /**\n * validateOn:\n * - Only affects the auto-validation phase (onChange/onBlur); submit/manual always runs.\n * - If an empty array, auto-validation is disabled (only submit/manual runs).\n */\n readonly validateOn?: RuleValidateOn\n}\n\nexport type RuleSet<Input, Ctx = unknown> = Readonly<Record<string, Rule<Input, Ctx>>>\n\nexport type RuleEntry<Input, Ctx = unknown> =\n | RuleFn<Input, Ctx>\n | (Omit<Rule<Input, Ctx>, 'deps'> & {\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n })\n\nexport type RuleGroup<Input, Ctx = unknown> = Readonly<{\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n readonly validateOn?: RuleValidateOn\n readonly validate: Readonly<Record<string, RuleEntry<Input, Ctx>>>\n}>\n\nexport type RuleConfig<Input, Ctx = unknown> = Readonly<{\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n readonly validateOn?: RuleValidateOn\n\n // RHF-like builtins (expanded at build time into equivalent pure functions)\n readonly required?: Validators.RequiredDecl\n readonly minLength?: Validators.MinLengthDecl\n readonly maxLength?: Validators.MaxLengthDecl\n readonly min?: Validators.MinDecl\n readonly max?: Validators.MaxDecl\n readonly pattern?: Validators.PatternDecl\n\n // RHF-like validate: a function or a named map of functions (RuleEntry form is also allowed to override deps/validateOn)\n readonly validate?: RuleFn<Input, Ctx> | Readonly<Record<string, RuleEntry<Input, Ctx>>>\n}>\n\nexport type RuleInput<Input, Ctx = unknown> = RuleFn<Input, Ctx> | RuleGroup<Input, Ctx> | RuleConfig<Input, Ctx>\n\nconst uniq = <T>(items: ReadonlyArray<T>): ReadonlyArray<T> => Array.from(new Set(items))\n\nconst normalizeValidateOn = (input: unknown): RuleValidateOn | undefined => {\n if (!Array.isArray(input)) return undefined\n const out: Array<AutoValidateOn> = []\n for (const x of input) {\n if (x === 'onChange' || x === 'onBlur') out.push(x)\n }\n return uniq(out)\n}\n\nconst normalizeDeps = (input: unknown): ReadonlyArray<string> | undefined => {\n if (!Array.isArray(input)) return undefined\n const out: Array<string> = []\n for (const x of input) {\n if (typeof x !== 'string') continue\n const v = x.trim()\n if (!v) continue\n out.push(v)\n }\n return uniq(out)\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/**\n * make:\n * - The result must be directly attachable to `StateTrait.node({ check })`.\n * - Does not introduce an extra wrapper (e.g. `{ rules: ... }`).\n */\nexport const make = <Input, Ctx = unknown>(input: RuleInput<Input, Ctx>): RuleSet<Input, Ctx> => {\n if (typeof input === 'function') {\n return {\n default: {\n deps: [],\n validate: input,\n },\n }\n }\n\n if (!isPlainObject(input)) {\n return {}\n }\n\n const baseDeps = normalizeDeps((input as any).deps) ?? []\n const baseValidateOn = normalizeValidateOn((input as any).validateOn)\n\n const byName = new Map<string, Rule<Input, Ctx>>()\n\n const addRule = (name: string, raw: unknown): void => {\n const ruleName = typeof name === 'string' ? name.trim() : ''\n if (!ruleName) return\n if (byName.has(ruleName)) {\n throw new Error(`[Form.Rule.make] Duplicate rule name \"${ruleName}\"`)\n }\n\n if (typeof raw === 'function') {\n byName.set(ruleName, {\n deps: baseDeps,\n validate: raw as any,\n ...(baseValidateOn !== undefined ? { validateOn: baseValidateOn } : {}),\n })\n return\n }\n\n if (!raw || typeof raw !== 'object') return\n const entry = raw as any\n const deps = normalizeDeps(entry.deps) ?? baseDeps\n const validateOn = normalizeValidateOn(entry.validateOn) ?? baseValidateOn\n const validate = entry.validate\n if (typeof validate !== 'function') return\n\n byName.set(ruleName, {\n ...entry,\n deps,\n validate,\n ...(validateOn !== undefined ? { validateOn } : {}),\n })\n }\n\n // RHF-like builtins (if declared, it will be expanded into an equivalent pure function)\n const requiredDecl = (input as any).required as Validators.RequiredDecl | undefined\n if (requiredDecl !== undefined && requiredDecl !== false) {\n const validate = Validators.required(requiredDecl)\n addRule('required', (value: Input) => validate(value))\n }\n\n const minLengthDecl = (input as any).minLength as Validators.MinLengthDecl | undefined\n if (minLengthDecl !== undefined) {\n const validate = Validators.minLength(minLengthDecl)\n addRule('minLength', (value: Input) => validate(value))\n }\n\n const maxLengthDecl = (input as any).maxLength as Validators.MaxLengthDecl | undefined\n if (maxLengthDecl !== undefined) {\n const validate = Validators.maxLength(maxLengthDecl)\n addRule('maxLength', (value: Input) => validate(value))\n }\n\n const minDecl = (input as any).min as Validators.MinDecl | undefined\n if (minDecl !== undefined) {\n const validate = Validators.min(minDecl)\n addRule('min', (value: Input) => validate(value))\n }\n\n const maxDecl = (input as any).max as Validators.MaxDecl | undefined\n if (maxDecl !== undefined) {\n const validate = Validators.max(maxDecl)\n addRule('max', (value: Input) => validate(value))\n }\n\n const patternDecl = (input as any).pattern as Validators.PatternDecl | undefined\n if (patternDecl !== undefined) {\n const validate = Validators.pattern(patternDecl)\n addRule('pattern', (value: Input) => validate(value))\n }\n\n // validate: supports both legacy RuleGroup `{ validate: Record<string, RuleEntry> }`\n // and RHF-style `validate: fn | Record<string, fn>`.\n const validateBlock = (input as any).validate as unknown\n if (typeof validateBlock === 'function') {\n addRule('validate', validateBlock)\n } else if (isPlainObject(validateBlock)) {\n const names = Object.keys(validateBlock).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n addRule(name, (validateBlock as any)[name])\n }\n }\n\n const out: Record<string, Rule<Input, Ctx>> = {}\n const names = Array.from(byName.keys()).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n out[name] = byName.get(name)!\n }\n return out\n}\n\nexport const merge = <Input, Ctx = unknown>(...rules: ReadonlyArray<RuleSet<Input, Ctx>>): RuleSet<Input, Ctx> => {\n const byName = new Map<string, Rule<Input, Ctx>>()\n const duplicates = new Set<string>()\n\n for (const ruleSet of rules) {\n for (const name of Object.keys(ruleSet)) {\n if (byName.has(name)) duplicates.add(name)\n else byName.set(name, ruleSet[name]!)\n }\n }\n\n if (duplicates.size > 0) {\n const list = Array.from(duplicates)\n .sort((a, b) => a.localeCompare(b))\n .join(', ')\n throw new Error(`[Form.Rule.merge] Duplicate rule name(s): ${list}`)\n }\n\n const merged: Record<string, Rule<Input, Ctx>> = {}\n const names = Array.from(byName.keys()).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n merged[name] = byName.get(name)!\n }\n\n return merged\n}\n\nexport type ErrorTarget = '$value' | '$self'\n\nexport type ListIdentityPolicy =\n | Readonly<{ readonly mode: 'trackBy'; readonly trackBy: string }>\n | Readonly<{ readonly mode: 'store' }>\n | Readonly<{ readonly mode: 'index' }>\n\nexport type FieldDecl<Input, Ctx = unknown> = Readonly<{\n readonly kind: 'field'\n readonly valuePath: string\n readonly rule: RuleInput<Input, Ctx>\n readonly errorTarget?: ErrorTarget\n}>\n\nexport type RootDecl<Input, Ctx = unknown> = Readonly<{\n readonly kind: 'root'\n readonly rule: RuleInput<Input, Ctx>\n}>\n\nexport type ListDecl<Item, Ctx = unknown> = Readonly<{\n readonly kind: 'list'\n readonly listPath: string\n readonly identity: ListIdentityPolicy\n readonly item?: RuleInput<Item, Ctx>\n readonly list?: RuleInput<ReadonlyArray<Item>, Ctx>\n}>\n\nexport type RulesDecl<TValues extends object = any> = FieldDecl<any> | RootDecl<TValues> | ListDecl<any>\n\nexport const field = <Input, Ctx = unknown>(\n valuePath: string,\n rule: RuleInput<Input, Ctx>,\n options?: { readonly errorTarget?: ErrorTarget },\n): FieldDecl<Input, Ctx> => ({\n kind: 'field',\n valuePath,\n rule,\n ...(options?.errorTarget !== undefined ? { errorTarget: options.errorTarget } : {}),\n})\n\nexport const root = <Input, Ctx = unknown>(rule: RuleInput<Input, Ctx>): RootDecl<Input, Ctx> => ({\n kind: 'root',\n rule,\n})\n\nexport const list = <Item, Ctx = unknown>(\n listPath: string,\n spec: {\n readonly identity: ListIdentityPolicy\n readonly item?: RuleInput<Item, Ctx>\n readonly list?: RuleInput<ReadonlyArray<Item>, Ctx>\n },\n): ListDecl<Item, Ctx> => ({\n kind: 'list',\n listPath,\n identity: spec.identity,\n ...(spec.item !== undefined ? { item: spec.item } : {}),\n ...(spec.list !== undefined ? { list: spec.list } : {}),\n})\n\nexport const fields = <Input, Ctx = unknown>(\n ...decls: ReadonlyArray<FieldDecl<Input, Ctx> | ReadonlyArray<FieldDecl<Input, Ctx>>>\n): Readonly<Record<string, RuleInput<Input, Ctx>>> => {\n const out: Record<string, RuleInput<Input, Ctx>> = {}\n const list: Array<FieldDecl<Input, Ctx>> = []\n\n const isDeclArray = (value: unknown): value is ReadonlyArray<FieldDecl<Input, Ctx>> => Array.isArray(value)\n\n for (const item of decls) {\n if (isDeclArray(item)) {\n list.push(...item)\n continue\n }\n list.push(item)\n }\n\n for (const decl of list) {\n const path = typeof decl?.valuePath === 'string' ? decl.valuePath.trim() : ''\n if (!path) continue\n if (path in out) {\n throw new Error(`[Form.Rule.fields] Duplicate valuePath \"${path}\"`)\n }\n out[path] = decl.rule\n }\n\n return out\n}\n\nexport {\n ERROR_VALUE_MAX_BYTES,\n assertErrorValueBudget,\n required,\n minLength,\n maxLength,\n min,\n max,\n pattern,\n} from './internal/validators/index.js'\n","import { ParseResult } from 'effect'\n\nexport const ERROR_VALUE_MAX_BYTES = 256\n\nconst textEncoder = new TextEncoder()\n\nconst jsonByteSize = (value: unknown): number => {\n const json = JSON.stringify(value)\n return textEncoder.encode(json).length\n}\n\nconst truncateToJsonByteBudget = (value: string, maxBytes: number): string => {\n if (jsonByteSize(value) <= maxBytes) return value\n\n let lo = 0\n let hi = value.length\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n const slice = value.slice(0, mid)\n if (jsonByteSize(slice) <= maxBytes) lo = mid\n else hi = mid - 1\n }\n return value.slice(0, lo)\n}\n\nexport const assertErrorValueBudget = (value: unknown, label: string): unknown => {\n const bytes = jsonByteSize(value)\n if (bytes <= ERROR_VALUE_MAX_BYTES) return value\n throw new Error(`[Form.validators] ErrorValue for \"${label}\" must be JSON ≤${ERROR_VALUE_MAX_BYTES}B (got ${bytes}B)`)\n}\n\nconst errorValue = (label: string, value: unknown): unknown => assertErrorValueBudget(value, label)\n\nexport type RequiredDecl =\n | boolean\n | string\n | Readonly<{\n readonly message?: string\n readonly trim?: boolean\n }>\n\nexport const required = (decl: RequiredDecl): ((value: unknown) => unknown | undefined) => {\n const trim = typeof decl === 'object' && decl !== null ? Boolean((decl as any).trim) : true\n const message =\n typeof decl === 'string'\n ? decl\n : typeof decl === 'object' && decl !== null && typeof (decl as any).message === 'string'\n ? (decl as any).message\n : 'required'\n\n const err = errorValue('required', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return err\n if (typeof value === 'string') {\n const v = trim ? value.trim() : value\n return v.length > 0 ? undefined : err\n }\n if (Array.isArray(value)) return value.length > 0 ? undefined : err\n if (typeof value === 'boolean') return value ? undefined : err\n return undefined\n }\n}\n\nexport type MinLengthDecl =\n | number\n | Readonly<{\n readonly min: number\n readonly message?: string\n }>\n\nexport const minLength = (decl: MinLengthDecl): ((value: unknown) => unknown | undefined) => {\n const min = typeof decl === 'number' ? decl : decl.min\n const message =\n typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'minLength'\n const err = errorValue('minLength', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'string') return value.length >= min ? undefined : err\n if (Array.isArray(value)) return value.length >= min ? undefined : err\n return undefined\n }\n}\n\nexport type MaxLengthDecl =\n | number\n | Readonly<{\n readonly max: number\n readonly message?: string\n }>\n\nexport const maxLength = (decl: MaxLengthDecl): ((value: unknown) => unknown | undefined) => {\n const max = typeof decl === 'number' ? decl : decl.max\n const message =\n typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'maxLength'\n const err = errorValue('maxLength', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'string') return value.length <= max ? undefined : err\n if (Array.isArray(value)) return value.length <= max ? undefined : err\n return undefined\n }\n}\n\nexport type MinDecl =\n | number\n | Readonly<{\n readonly min: number\n readonly message?: string\n }>\n\nexport const min = (decl: MinDecl): ((value: unknown) => unknown | undefined) => {\n const minValue = typeof decl === 'number' ? decl : decl.min\n const message = typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'min'\n const err = errorValue('min', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value >= minValue ? undefined : err\n return undefined\n }\n}\n\nexport type MaxDecl =\n | number\n | Readonly<{\n readonly max: number\n readonly message?: string\n }>\n\nexport const max = (decl: MaxDecl): ((value: unknown) => unknown | undefined) => {\n const maxValue = typeof decl === 'number' ? decl : decl.max\n const message = typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'max'\n const err = errorValue('max', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value <= maxValue ? undefined : err\n return undefined\n }\n}\n\nexport type PatternDecl =\n | RegExp\n | Readonly<{\n readonly re: RegExp\n readonly message?: string\n }>\n\nexport const pattern = (decl: PatternDecl): ((value: unknown) => unknown | undefined) => {\n const re = decl instanceof RegExp ? decl : decl.re\n const message =\n typeof decl === 'object' && decl !== null && typeof (decl as any).message === 'string'\n ? (decl as any).message\n : 'pattern'\n const err = errorValue('pattern', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value !== 'string') return undefined\n return re.test(value) ? undefined : err\n }\n}\n\nexport const schemaErrorMessage = (schemaError: unknown): string => {\n let message: string\n try {\n message = ParseResult.TreeFormatter.formatErrorSync(schemaError as any)\n } catch {\n message = 'schema invalid'\n }\n\n const truncated = truncateToJsonByteBudget(message, ERROR_VALUE_MAX_BYTES)\n return truncated.length > 0 ? truncated : 'schema invalid'\n}\n"],"mappings":"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","names":["min","max","names","list"]}
1
+ {"version":3,"sources":["../src/Rule.ts","../src/internal/validators/index.ts"],"sourcesContent":["import type * as Logix from '@logixjs/core'\nimport * as Validators from './internal/validators/index.js'\nimport type { CanonicalPath } from './internal/form/types.js'\n\nexport type AutoValidateOn = 'onChange' | 'onBlur'\n\nexport type RuleValidateOn = ReadonlyArray<AutoValidateOn>\n\nexport type RuleFn<Input, Ctx = unknown> = (input: Input, ctx: Ctx) => unknown | undefined\n\ntype RuleDeps<Input> = Input extends object\n ? CanonicalPath<Input> extends never\n ? string\n : CanonicalPath<Input>\n : string\n\nexport type Rule<Input, Ctx = unknown> = Logix.StateTrait.CheckRule<Input, Ctx> & {\n /**\n * validateOn:\n * - Only affects the auto-validation phase (onChange/onBlur); submit/manual always runs.\n * - If an empty array, auto-validation is disabled (only submit/manual runs).\n */\n readonly validateOn?: RuleValidateOn\n}\n\nexport type RuleSet<Input, Ctx = unknown> = Readonly<Record<string, Rule<Input, Ctx>>>\n\nexport type RuleEntry<Input, Ctx = unknown> =\n | RuleFn<Input, Ctx>\n | (Omit<Rule<Input, Ctx>, 'deps'> & {\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n })\n\nexport type RuleGroup<Input, Ctx = unknown> = Readonly<{\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n readonly validateOn?: RuleValidateOn\n readonly validate: Readonly<Record<string, RuleEntry<Input, Ctx>>>\n}>\n\nexport type RuleConfig<Input, Ctx = unknown> = Readonly<{\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n readonly validateOn?: RuleValidateOn\n\n // RHF-like builtins (expanded at build time into equivalent pure functions)\n readonly required?: Validators.RequiredDecl\n readonly minLength?: Validators.MinLengthDecl\n readonly maxLength?: Validators.MaxLengthDecl\n readonly min?: Validators.MinDecl\n readonly max?: Validators.MaxDecl\n readonly pattern?: Validators.PatternDecl\n\n // RHF-like validate: a function or a named map of functions (RuleEntry form is also allowed to override deps/validateOn)\n readonly validate?: RuleFn<Input, Ctx> | Readonly<Record<string, RuleEntry<Input, Ctx>>>\n}>\n\nexport type RuleInput<Input, Ctx = unknown> = RuleFn<Input, Ctx> | RuleGroup<Input, Ctx> | RuleConfig<Input, Ctx>\n\nconst uniq = <T>(items: ReadonlyArray<T>): ReadonlyArray<T> => Array.from(new Set(items))\n\nconst normalizeValidateOn = (input: unknown): RuleValidateOn | undefined => {\n if (!Array.isArray(input)) return undefined\n const out: Array<AutoValidateOn> = []\n for (const x of input) {\n if (x === 'onChange' || x === 'onBlur') out.push(x)\n }\n return uniq(out)\n}\n\nconst normalizeDeps = (input: unknown): ReadonlyArray<string> | undefined => {\n if (!Array.isArray(input)) return undefined\n const out: Array<string> = []\n for (const x of input) {\n if (typeof x !== 'string') continue\n const v = x.trim()\n if (!v) continue\n out.push(v)\n }\n return uniq(out)\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/**\n * make:\n * - The result must be directly attachable to `StateTrait.node({ check })`.\n * - Does not introduce an extra wrapper (e.g. `{ rules: ... }`).\n */\nexport const make = <Input, Ctx = unknown>(input: RuleInput<Input, Ctx>): RuleSet<Input, Ctx> => {\n if (typeof input === 'function') {\n return {\n default: {\n deps: [],\n validate: input,\n },\n }\n }\n\n if (!isPlainObject(input)) {\n return {}\n }\n\n const baseDeps = normalizeDeps((input as any).deps) ?? []\n const baseValidateOn = normalizeValidateOn((input as any).validateOn)\n\n const byName = new Map<string, Rule<Input, Ctx>>()\n\n const addRule = (name: string, raw: unknown): void => {\n const ruleName = typeof name === 'string' ? name.trim() : ''\n if (!ruleName) return\n if (byName.has(ruleName)) {\n throw new Error(`[Form.Rule.make] Duplicate rule name \"${ruleName}\"`)\n }\n\n if (typeof raw === 'function') {\n byName.set(ruleName, {\n deps: baseDeps,\n validate: raw as any,\n ...(baseValidateOn !== undefined ? { validateOn: baseValidateOn } : {}),\n })\n return\n }\n\n if (!raw || typeof raw !== 'object') return\n const entry = raw as any\n const deps = normalizeDeps(entry.deps) ?? baseDeps\n const validateOn = normalizeValidateOn(entry.validateOn) ?? baseValidateOn\n const validate = entry.validate\n if (typeof validate !== 'function') return\n\n byName.set(ruleName, {\n ...entry,\n deps,\n validate,\n ...(validateOn !== undefined ? { validateOn } : {}),\n })\n }\n\n // RHF-like builtins (if declared, it will be expanded into an equivalent pure function)\n const requiredDecl = (input as any).required as Validators.RequiredDecl | undefined\n if (requiredDecl !== undefined && requiredDecl !== false) {\n const validate = Validators.required(requiredDecl)\n addRule('required', (value: Input) => validate(value))\n }\n\n const minLengthDecl = (input as any).minLength as Validators.MinLengthDecl | undefined\n if (minLengthDecl !== undefined) {\n const validate = Validators.minLength(minLengthDecl)\n addRule('minLength', (value: Input) => validate(value))\n }\n\n const maxLengthDecl = (input as any).maxLength as Validators.MaxLengthDecl | undefined\n if (maxLengthDecl !== undefined) {\n const validate = Validators.maxLength(maxLengthDecl)\n addRule('maxLength', (value: Input) => validate(value))\n }\n\n const minDecl = (input as any).min as Validators.MinDecl | undefined\n if (minDecl !== undefined) {\n const validate = Validators.min(minDecl)\n addRule('min', (value: Input) => validate(value))\n }\n\n const maxDecl = (input as any).max as Validators.MaxDecl | undefined\n if (maxDecl !== undefined) {\n const validate = Validators.max(maxDecl)\n addRule('max', (value: Input) => validate(value))\n }\n\n const patternDecl = (input as any).pattern as Validators.PatternDecl | undefined\n if (patternDecl !== undefined) {\n const validate = Validators.pattern(patternDecl)\n addRule('pattern', (value: Input) => validate(value))\n }\n\n // validate: supports both legacy RuleGroup `{ validate: Record<string, RuleEntry> }`\n // and RHF-style `validate: fn | Record<string, fn>`.\n const validateBlock = (input as any).validate as unknown\n if (typeof validateBlock === 'function') {\n addRule('validate', validateBlock)\n } else if (isPlainObject(validateBlock)) {\n const names = Object.keys(validateBlock).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n addRule(name, (validateBlock as any)[name])\n }\n }\n\n const out: Record<string, Rule<Input, Ctx>> = {}\n const names = Array.from(byName.keys()).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n out[name] = byName.get(name)!\n }\n return out\n}\n\nexport const merge = <Input, Ctx = unknown>(...rules: ReadonlyArray<RuleSet<Input, Ctx>>): RuleSet<Input, Ctx> => {\n const byName = new Map<string, Rule<Input, Ctx>>()\n const duplicates = new Set<string>()\n\n for (const ruleSet of rules) {\n for (const name of Object.keys(ruleSet)) {\n if (byName.has(name)) duplicates.add(name)\n else byName.set(name, ruleSet[name]!)\n }\n }\n\n if (duplicates.size > 0) {\n const list = Array.from(duplicates)\n .sort((a, b) => a.localeCompare(b))\n .join(', ')\n throw new Error(`[Form.Rule.merge] Duplicate rule name(s): ${list}`)\n }\n\n const merged: Record<string, Rule<Input, Ctx>> = {}\n const names = Array.from(byName.keys()).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n merged[name] = byName.get(name)!\n }\n\n return merged\n}\n\nexport type ErrorTarget = '$value' | '$self'\n\nexport type ListIdentityPolicy =\n | Readonly<{ readonly mode: 'trackBy'; readonly trackBy: string }>\n | Readonly<{ readonly mode: 'store' }>\n | Readonly<{ readonly mode: 'index' }>\n\nexport type FieldDecl<Input, Ctx = unknown> = Readonly<{\n readonly kind: 'field'\n readonly valuePath: string\n readonly rule: RuleInput<Input, Ctx>\n readonly errorTarget?: ErrorTarget\n}>\n\nexport type RootDecl<Input, Ctx = unknown> = Readonly<{\n readonly kind: 'root'\n readonly rule: RuleInput<Input, Ctx>\n}>\n\nexport type ListDecl<Item, Ctx = unknown> = Readonly<{\n readonly kind: 'list'\n readonly listPath: string\n readonly identity: ListIdentityPolicy\n readonly item?: RuleInput<Item, Ctx>\n readonly list?: RuleInput<ReadonlyArray<Item>, Ctx>\n}>\n\nexport type RulesDecl<TValues extends object = any> = FieldDecl<any> | RootDecl<TValues> | ListDecl<any>\n\nexport const field = <Input, Ctx = unknown>(\n valuePath: string,\n rule: RuleInput<Input, Ctx>,\n options?: { readonly errorTarget?: ErrorTarget },\n): FieldDecl<Input, Ctx> => ({\n kind: 'field',\n valuePath,\n rule,\n ...(options?.errorTarget !== undefined ? { errorTarget: options.errorTarget } : {}),\n})\n\nexport const root = <Input, Ctx = unknown>(rule: RuleInput<Input, Ctx>): RootDecl<Input, Ctx> => ({\n kind: 'root',\n rule,\n})\n\nexport const list = <Item, Ctx = unknown>(\n listPath: string,\n spec: {\n readonly identity: ListIdentityPolicy\n readonly item?: RuleInput<Item, Ctx>\n readonly list?: RuleInput<ReadonlyArray<Item>, Ctx>\n },\n): ListDecl<Item, Ctx> => ({\n kind: 'list',\n listPath,\n identity: spec.identity,\n ...(spec.item !== undefined ? { item: spec.item } : {}),\n ...(spec.list !== undefined ? { list: spec.list } : {}),\n})\n\nexport const fields = <Input, Ctx = unknown>(\n ...decls: ReadonlyArray<FieldDecl<Input, Ctx> | ReadonlyArray<FieldDecl<Input, Ctx>>>\n): Readonly<Record<string, RuleInput<Input, Ctx>>> => {\n const out: Record<string, RuleInput<Input, Ctx>> = {}\n const list: Array<FieldDecl<Input, Ctx>> = []\n\n const isDeclArray = (value: unknown): value is ReadonlyArray<FieldDecl<Input, Ctx>> => Array.isArray(value)\n\n for (const item of decls) {\n if (isDeclArray(item)) {\n list.push(...item)\n continue\n }\n list.push(item)\n }\n\n for (const decl of list) {\n const path = typeof decl?.valuePath === 'string' ? decl.valuePath.trim() : ''\n if (!path) continue\n if (path in out) {\n throw new Error(`[Form.Rule.fields] Duplicate valuePath \"${path}\"`)\n }\n out[path] = decl.rule\n }\n\n return out\n}\n\nexport {\n ERROR_VALUE_MAX_BYTES,\n assertErrorValueBudget,\n required,\n minLength,\n maxLength,\n min,\n max,\n pattern,\n} from './internal/validators/index.js'\n","export const ERROR_VALUE_MAX_BYTES = 256\n\nconst textEncoder = new TextEncoder()\n\nconst jsonByteSize = (value: unknown): number => {\n const json = JSON.stringify(value)\n return textEncoder.encode(json).length\n}\n\nconst truncateToJsonByteBudget = (value: string, maxBytes: number): string => {\n if (jsonByteSize(value) <= maxBytes) return value\n\n let lo = 0\n let hi = value.length\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n const slice = value.slice(0, mid)\n if (jsonByteSize(slice) <= maxBytes) lo = mid\n else hi = mid - 1\n }\n return value.slice(0, lo)\n}\n\nexport const assertErrorValueBudget = (value: unknown, label: string): unknown => {\n const bytes = jsonByteSize(value)\n if (bytes <= ERROR_VALUE_MAX_BYTES) return value\n throw new Error(`[Form.validators] ErrorValue for \"${label}\" must be JSON ≤${ERROR_VALUE_MAX_BYTES}B (got ${bytes}B)`)\n}\n\nconst errorValue = (label: string, value: unknown): unknown => assertErrorValueBudget(value, label)\n\nexport type RequiredDecl =\n | boolean\n | string\n | Readonly<{\n readonly message?: string\n readonly trim?: boolean\n }>\n\nexport const required = (decl: RequiredDecl): ((value: unknown) => unknown | undefined) => {\n const trim = typeof decl === 'object' && decl !== null ? Boolean((decl as any).trim) : true\n const message =\n typeof decl === 'string'\n ? decl\n : typeof decl === 'object' && decl !== null && typeof (decl as any).message === 'string'\n ? (decl as any).message\n : 'required'\n\n const err = errorValue('required', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return err\n if (typeof value === 'string') {\n const v = trim ? value.trim() : value\n return v.length > 0 ? undefined : err\n }\n if (Array.isArray(value)) return value.length > 0 ? undefined : err\n if (typeof value === 'boolean') return value ? undefined : err\n return undefined\n }\n}\n\nexport type MinLengthDecl =\n | number\n | Readonly<{\n readonly min: number\n readonly message?: string\n }>\n\nexport const minLength = (decl: MinLengthDecl): ((value: unknown) => unknown | undefined) => {\n const min = typeof decl === 'number' ? decl : decl.min\n const message =\n typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'minLength'\n const err = errorValue('minLength', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'string') return value.length >= min ? undefined : err\n if (Array.isArray(value)) return value.length >= min ? undefined : err\n return undefined\n }\n}\n\nexport type MaxLengthDecl =\n | number\n | Readonly<{\n readonly max: number\n readonly message?: string\n }>\n\nexport const maxLength = (decl: MaxLengthDecl): ((value: unknown) => unknown | undefined) => {\n const max = typeof decl === 'number' ? decl : decl.max\n const message =\n typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'maxLength'\n const err = errorValue('maxLength', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'string') return value.length <= max ? undefined : err\n if (Array.isArray(value)) return value.length <= max ? undefined : err\n return undefined\n }\n}\n\nexport type MinDecl =\n | number\n | Readonly<{\n readonly min: number\n readonly message?: string\n }>\n\nexport const min = (decl: MinDecl): ((value: unknown) => unknown | undefined) => {\n const minValue = typeof decl === 'number' ? decl : decl.min\n const message = typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'min'\n const err = errorValue('min', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value >= minValue ? undefined : err\n return undefined\n }\n}\n\nexport type MaxDecl =\n | number\n | Readonly<{\n readonly max: number\n readonly message?: string\n }>\n\nexport const max = (decl: MaxDecl): ((value: unknown) => unknown | undefined) => {\n const maxValue = typeof decl === 'number' ? decl : decl.max\n const message = typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'max'\n const err = errorValue('max', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value <= maxValue ? undefined : err\n return undefined\n }\n}\n\nexport type PatternDecl =\n | RegExp\n | Readonly<{\n readonly re: RegExp\n readonly message?: string\n }>\n\nexport const pattern = (decl: PatternDecl): ((value: unknown) => unknown | undefined) => {\n const re = decl instanceof RegExp ? decl : decl.re\n const message =\n typeof decl === 'object' && decl !== null && typeof (decl as any).message === 'string'\n ? (decl as any).message\n : 'pattern'\n const err = errorValue('pattern', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value !== 'string') return undefined\n return re.test(value) ? undefined : err\n }\n}\n\nexport const schemaErrorMessage = (schemaError: unknown): string => {\n let message: string\n try {\n message = schemaError instanceof Error ? (schemaError.message || 'schema invalid') : String(schemaError)\n } catch {\n message = 'schema invalid'\n }\n\n const truncated = truncateToJsonByteBudget(message, ERROR_VALUE_MAX_BYTES)\n return truncated.length > 0 ? truncated : 'schema invalid'\n}\n"],"mappings":"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","names":["min","max","names","list"]}
package/dist/Rule.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  pattern,
14
14
  required,
15
15
  root
16
- } from "./chunk-YVHXLY63.js";
16
+ } from "./chunk-3U6VHYYQ.js";
17
17
  import "./chunk-PZ5AY32C.js";
18
18
  export {
19
19
  ERROR_VALUE_MAX_BYTES,
@@ -22,7 +22,6 @@ __export(Rule_exports, {
22
22
  });
23
23
 
24
24
  // src/internal/validators/index.ts
25
- import { ParseResult } from "effect";
26
25
  var ERROR_VALUE_MAX_BYTES = 256;
27
26
  var textEncoder = new TextEncoder();
28
27
  var jsonByteSize = (value) => {
@@ -117,7 +116,7 @@ var pattern = (decl) => {
117
116
  var schemaErrorMessage = (schemaError) => {
118
117
  let message;
119
118
  try {
120
- message = ParseResult.TreeFormatter.formatErrorSync(schemaError);
119
+ message = schemaError instanceof Error ? schemaError.message || "schema invalid" : String(schemaError);
121
120
  } catch {
122
121
  message = "schema invalid";
123
122
  }
@@ -312,4 +311,4 @@ export {
312
311
  fields,
313
312
  Rule_exports
314
313
  };
315
- //# sourceMappingURL=chunk-YVHXLY63.js.map
314
+ //# sourceMappingURL=chunk-3U6VHYYQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Rule.ts","../src/internal/validators/index.ts"],"sourcesContent":["import type * as Logix from '@logixjs/core'\nimport * as Validators from './internal/validators/index.js'\nimport type { CanonicalPath } from './internal/form/types.js'\n\nexport type AutoValidateOn = 'onChange' | 'onBlur'\n\nexport type RuleValidateOn = ReadonlyArray<AutoValidateOn>\n\nexport type RuleFn<Input, Ctx = unknown> = (input: Input, ctx: Ctx) => unknown | undefined\n\ntype RuleDeps<Input> = Input extends object\n ? CanonicalPath<Input> extends never\n ? string\n : CanonicalPath<Input>\n : string\n\nexport type Rule<Input, Ctx = unknown> = Logix.StateTrait.CheckRule<Input, Ctx> & {\n /**\n * validateOn:\n * - Only affects the auto-validation phase (onChange/onBlur); submit/manual always runs.\n * - If an empty array, auto-validation is disabled (only submit/manual runs).\n */\n readonly validateOn?: RuleValidateOn\n}\n\nexport type RuleSet<Input, Ctx = unknown> = Readonly<Record<string, Rule<Input, Ctx>>>\n\nexport type RuleEntry<Input, Ctx = unknown> =\n | RuleFn<Input, Ctx>\n | (Omit<Rule<Input, Ctx>, 'deps'> & {\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n })\n\nexport type RuleGroup<Input, Ctx = unknown> = Readonly<{\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n readonly validateOn?: RuleValidateOn\n readonly validate: Readonly<Record<string, RuleEntry<Input, Ctx>>>\n}>\n\nexport type RuleConfig<Input, Ctx = unknown> = Readonly<{\n readonly deps?: ReadonlyArray<RuleDeps<Input>>\n readonly validateOn?: RuleValidateOn\n\n // RHF-like builtins (expanded at build time into equivalent pure functions)\n readonly required?: Validators.RequiredDecl\n readonly minLength?: Validators.MinLengthDecl\n readonly maxLength?: Validators.MaxLengthDecl\n readonly min?: Validators.MinDecl\n readonly max?: Validators.MaxDecl\n readonly pattern?: Validators.PatternDecl\n\n // RHF-like validate: a function or a named map of functions (RuleEntry form is also allowed to override deps/validateOn)\n readonly validate?: RuleFn<Input, Ctx> | Readonly<Record<string, RuleEntry<Input, Ctx>>>\n}>\n\nexport type RuleInput<Input, Ctx = unknown> = RuleFn<Input, Ctx> | RuleGroup<Input, Ctx> | RuleConfig<Input, Ctx>\n\nconst uniq = <T>(items: ReadonlyArray<T>): ReadonlyArray<T> => Array.from(new Set(items))\n\nconst normalizeValidateOn = (input: unknown): RuleValidateOn | undefined => {\n if (!Array.isArray(input)) return undefined\n const out: Array<AutoValidateOn> = []\n for (const x of input) {\n if (x === 'onChange' || x === 'onBlur') out.push(x)\n }\n return uniq(out)\n}\n\nconst normalizeDeps = (input: unknown): ReadonlyArray<string> | undefined => {\n if (!Array.isArray(input)) return undefined\n const out: Array<string> = []\n for (const x of input) {\n if (typeof x !== 'string') continue\n const v = x.trim()\n if (!v) continue\n out.push(v)\n }\n return uniq(out)\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/**\n * make:\n * - The result must be directly attachable to `StateTrait.node({ check })`.\n * - Does not introduce an extra wrapper (e.g. `{ rules: ... }`).\n */\nexport const make = <Input, Ctx = unknown>(input: RuleInput<Input, Ctx>): RuleSet<Input, Ctx> => {\n if (typeof input === 'function') {\n return {\n default: {\n deps: [],\n validate: input,\n },\n }\n }\n\n if (!isPlainObject(input)) {\n return {}\n }\n\n const baseDeps = normalizeDeps((input as any).deps) ?? []\n const baseValidateOn = normalizeValidateOn((input as any).validateOn)\n\n const byName = new Map<string, Rule<Input, Ctx>>()\n\n const addRule = (name: string, raw: unknown): void => {\n const ruleName = typeof name === 'string' ? name.trim() : ''\n if (!ruleName) return\n if (byName.has(ruleName)) {\n throw new Error(`[Form.Rule.make] Duplicate rule name \"${ruleName}\"`)\n }\n\n if (typeof raw === 'function') {\n byName.set(ruleName, {\n deps: baseDeps,\n validate: raw as any,\n ...(baseValidateOn !== undefined ? { validateOn: baseValidateOn } : {}),\n })\n return\n }\n\n if (!raw || typeof raw !== 'object') return\n const entry = raw as any\n const deps = normalizeDeps(entry.deps) ?? baseDeps\n const validateOn = normalizeValidateOn(entry.validateOn) ?? baseValidateOn\n const validate = entry.validate\n if (typeof validate !== 'function') return\n\n byName.set(ruleName, {\n ...entry,\n deps,\n validate,\n ...(validateOn !== undefined ? { validateOn } : {}),\n })\n }\n\n // RHF-like builtins (if declared, it will be expanded into an equivalent pure function)\n const requiredDecl = (input as any).required as Validators.RequiredDecl | undefined\n if (requiredDecl !== undefined && requiredDecl !== false) {\n const validate = Validators.required(requiredDecl)\n addRule('required', (value: Input) => validate(value))\n }\n\n const minLengthDecl = (input as any).minLength as Validators.MinLengthDecl | undefined\n if (minLengthDecl !== undefined) {\n const validate = Validators.minLength(minLengthDecl)\n addRule('minLength', (value: Input) => validate(value))\n }\n\n const maxLengthDecl = (input as any).maxLength as Validators.MaxLengthDecl | undefined\n if (maxLengthDecl !== undefined) {\n const validate = Validators.maxLength(maxLengthDecl)\n addRule('maxLength', (value: Input) => validate(value))\n }\n\n const minDecl = (input as any).min as Validators.MinDecl | undefined\n if (minDecl !== undefined) {\n const validate = Validators.min(minDecl)\n addRule('min', (value: Input) => validate(value))\n }\n\n const maxDecl = (input as any).max as Validators.MaxDecl | undefined\n if (maxDecl !== undefined) {\n const validate = Validators.max(maxDecl)\n addRule('max', (value: Input) => validate(value))\n }\n\n const patternDecl = (input as any).pattern as Validators.PatternDecl | undefined\n if (patternDecl !== undefined) {\n const validate = Validators.pattern(patternDecl)\n addRule('pattern', (value: Input) => validate(value))\n }\n\n // validate: supports both legacy RuleGroup `{ validate: Record<string, RuleEntry> }`\n // and RHF-style `validate: fn | Record<string, fn>`.\n const validateBlock = (input as any).validate as unknown\n if (typeof validateBlock === 'function') {\n addRule('validate', validateBlock)\n } else if (isPlainObject(validateBlock)) {\n const names = Object.keys(validateBlock).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n addRule(name, (validateBlock as any)[name])\n }\n }\n\n const out: Record<string, Rule<Input, Ctx>> = {}\n const names = Array.from(byName.keys()).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n out[name] = byName.get(name)!\n }\n return out\n}\n\nexport const merge = <Input, Ctx = unknown>(...rules: ReadonlyArray<RuleSet<Input, Ctx>>): RuleSet<Input, Ctx> => {\n const byName = new Map<string, Rule<Input, Ctx>>()\n const duplicates = new Set<string>()\n\n for (const ruleSet of rules) {\n for (const name of Object.keys(ruleSet)) {\n if (byName.has(name)) duplicates.add(name)\n else byName.set(name, ruleSet[name]!)\n }\n }\n\n if (duplicates.size > 0) {\n const list = Array.from(duplicates)\n .sort((a, b) => a.localeCompare(b))\n .join(', ')\n throw new Error(`[Form.Rule.merge] Duplicate rule name(s): ${list}`)\n }\n\n const merged: Record<string, Rule<Input, Ctx>> = {}\n const names = Array.from(byName.keys()).sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n merged[name] = byName.get(name)!\n }\n\n return merged\n}\n\nexport type ErrorTarget = '$value' | '$self'\n\nexport type ListIdentityPolicy =\n | Readonly<{ readonly mode: 'trackBy'; readonly trackBy: string }>\n | Readonly<{ readonly mode: 'store' }>\n | Readonly<{ readonly mode: 'index' }>\n\nexport type FieldDecl<Input, Ctx = unknown> = Readonly<{\n readonly kind: 'field'\n readonly valuePath: string\n readonly rule: RuleInput<Input, Ctx>\n readonly errorTarget?: ErrorTarget\n}>\n\nexport type RootDecl<Input, Ctx = unknown> = Readonly<{\n readonly kind: 'root'\n readonly rule: RuleInput<Input, Ctx>\n}>\n\nexport type ListDecl<Item, Ctx = unknown> = Readonly<{\n readonly kind: 'list'\n readonly listPath: string\n readonly identity: ListIdentityPolicy\n readonly item?: RuleInput<Item, Ctx>\n readonly list?: RuleInput<ReadonlyArray<Item>, Ctx>\n}>\n\nexport type RulesDecl<TValues extends object = any> = FieldDecl<any> | RootDecl<TValues> | ListDecl<any>\n\nexport const field = <Input, Ctx = unknown>(\n valuePath: string,\n rule: RuleInput<Input, Ctx>,\n options?: { readonly errorTarget?: ErrorTarget },\n): FieldDecl<Input, Ctx> => ({\n kind: 'field',\n valuePath,\n rule,\n ...(options?.errorTarget !== undefined ? { errorTarget: options.errorTarget } : {}),\n})\n\nexport const root = <Input, Ctx = unknown>(rule: RuleInput<Input, Ctx>): RootDecl<Input, Ctx> => ({\n kind: 'root',\n rule,\n})\n\nexport const list = <Item, Ctx = unknown>(\n listPath: string,\n spec: {\n readonly identity: ListIdentityPolicy\n readonly item?: RuleInput<Item, Ctx>\n readonly list?: RuleInput<ReadonlyArray<Item>, Ctx>\n },\n): ListDecl<Item, Ctx> => ({\n kind: 'list',\n listPath,\n identity: spec.identity,\n ...(spec.item !== undefined ? { item: spec.item } : {}),\n ...(spec.list !== undefined ? { list: spec.list } : {}),\n})\n\nexport const fields = <Input, Ctx = unknown>(\n ...decls: ReadonlyArray<FieldDecl<Input, Ctx> | ReadonlyArray<FieldDecl<Input, Ctx>>>\n): Readonly<Record<string, RuleInput<Input, Ctx>>> => {\n const out: Record<string, RuleInput<Input, Ctx>> = {}\n const list: Array<FieldDecl<Input, Ctx>> = []\n\n const isDeclArray = (value: unknown): value is ReadonlyArray<FieldDecl<Input, Ctx>> => Array.isArray(value)\n\n for (const item of decls) {\n if (isDeclArray(item)) {\n list.push(...item)\n continue\n }\n list.push(item)\n }\n\n for (const decl of list) {\n const path = typeof decl?.valuePath === 'string' ? decl.valuePath.trim() : ''\n if (!path) continue\n if (path in out) {\n throw new Error(`[Form.Rule.fields] Duplicate valuePath \"${path}\"`)\n }\n out[path] = decl.rule\n }\n\n return out\n}\n\nexport {\n ERROR_VALUE_MAX_BYTES,\n assertErrorValueBudget,\n required,\n minLength,\n maxLength,\n min,\n max,\n pattern,\n} from './internal/validators/index.js'\n","export const ERROR_VALUE_MAX_BYTES = 256\n\nconst textEncoder = new TextEncoder()\n\nconst jsonByteSize = (value: unknown): number => {\n const json = JSON.stringify(value)\n return textEncoder.encode(json).length\n}\n\nconst truncateToJsonByteBudget = (value: string, maxBytes: number): string => {\n if (jsonByteSize(value) <= maxBytes) return value\n\n let lo = 0\n let hi = value.length\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n const slice = value.slice(0, mid)\n if (jsonByteSize(slice) <= maxBytes) lo = mid\n else hi = mid - 1\n }\n return value.slice(0, lo)\n}\n\nexport const assertErrorValueBudget = (value: unknown, label: string): unknown => {\n const bytes = jsonByteSize(value)\n if (bytes <= ERROR_VALUE_MAX_BYTES) return value\n throw new Error(`[Form.validators] ErrorValue for \"${label}\" must be JSON ≤${ERROR_VALUE_MAX_BYTES}B (got ${bytes}B)`)\n}\n\nconst errorValue = (label: string, value: unknown): unknown => assertErrorValueBudget(value, label)\n\nexport type RequiredDecl =\n | boolean\n | string\n | Readonly<{\n readonly message?: string\n readonly trim?: boolean\n }>\n\nexport const required = (decl: RequiredDecl): ((value: unknown) => unknown | undefined) => {\n const trim = typeof decl === 'object' && decl !== null ? Boolean((decl as any).trim) : true\n const message =\n typeof decl === 'string'\n ? decl\n : typeof decl === 'object' && decl !== null && typeof (decl as any).message === 'string'\n ? (decl as any).message\n : 'required'\n\n const err = errorValue('required', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return err\n if (typeof value === 'string') {\n const v = trim ? value.trim() : value\n return v.length > 0 ? undefined : err\n }\n if (Array.isArray(value)) return value.length > 0 ? undefined : err\n if (typeof value === 'boolean') return value ? undefined : err\n return undefined\n }\n}\n\nexport type MinLengthDecl =\n | number\n | Readonly<{\n readonly min: number\n readonly message?: string\n }>\n\nexport const minLength = (decl: MinLengthDecl): ((value: unknown) => unknown | undefined) => {\n const min = typeof decl === 'number' ? decl : decl.min\n const message =\n typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'minLength'\n const err = errorValue('minLength', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'string') return value.length >= min ? undefined : err\n if (Array.isArray(value)) return value.length >= min ? undefined : err\n return undefined\n }\n}\n\nexport type MaxLengthDecl =\n | number\n | Readonly<{\n readonly max: number\n readonly message?: string\n }>\n\nexport const maxLength = (decl: MaxLengthDecl): ((value: unknown) => unknown | undefined) => {\n const max = typeof decl === 'number' ? decl : decl.max\n const message =\n typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'maxLength'\n const err = errorValue('maxLength', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'string') return value.length <= max ? undefined : err\n if (Array.isArray(value)) return value.length <= max ? undefined : err\n return undefined\n }\n}\n\nexport type MinDecl =\n | number\n | Readonly<{\n readonly min: number\n readonly message?: string\n }>\n\nexport const min = (decl: MinDecl): ((value: unknown) => unknown | undefined) => {\n const minValue = typeof decl === 'number' ? decl : decl.min\n const message = typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'min'\n const err = errorValue('min', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value >= minValue ? undefined : err\n return undefined\n }\n}\n\nexport type MaxDecl =\n | number\n | Readonly<{\n readonly max: number\n readonly message?: string\n }>\n\nexport const max = (decl: MaxDecl): ((value: unknown) => unknown | undefined) => {\n const maxValue = typeof decl === 'number' ? decl : decl.max\n const message = typeof decl === 'object' && decl !== null && typeof decl.message === 'string' ? decl.message : 'max'\n const err = errorValue('max', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value <= maxValue ? undefined : err\n return undefined\n }\n}\n\nexport type PatternDecl =\n | RegExp\n | Readonly<{\n readonly re: RegExp\n readonly message?: string\n }>\n\nexport const pattern = (decl: PatternDecl): ((value: unknown) => unknown | undefined) => {\n const re = decl instanceof RegExp ? decl : decl.re\n const message =\n typeof decl === 'object' && decl !== null && typeof (decl as any).message === 'string'\n ? (decl as any).message\n : 'pattern'\n const err = errorValue('pattern', message)\n\n return (value: unknown) => {\n if (value === null || value === undefined) return undefined\n if (typeof value !== 'string') return undefined\n return re.test(value) ? undefined : err\n }\n}\n\nexport const schemaErrorMessage = (schemaError: unknown): string => {\n let message: string\n try {\n message = schemaError instanceof Error ? (schemaError.message || 'schema invalid') : String(schemaError)\n } catch {\n message = 'schema invalid'\n }\n\n const truncated = truncateToJsonByteBudget(message, ERROR_VALUE_MAX_BYTES)\n return truncated.length > 0 ? truncated : 'schema invalid'\n}\n"],"mappings":"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","names":["min","max","names","list"]}
@@ -4,7 +4,7 @@ import {
4
4
  make,
5
5
  root,
6
6
  schemaErrorMessage
7
- } from "./chunk-YVHXLY63.js";
7
+ } from "./chunk-3U6VHYYQ.js";
8
8
  import {
9
9
  toSchemaErrorTree
10
10
  } from "./chunk-JZ5FZKPJ.js";
@@ -668,8 +668,14 @@ var makeFormController = (params) => {
668
668
  });
669
669
  const state = yield* runtime.getState;
670
670
  const { errors: _errors, ui: _ui, $form: _meta, ...values } = state;
671
- const decoded = Schema.decodeUnknownEither(params.valuesSchema)(values);
672
- const schemaTree = decoded._tag === "Right" ? {} : toSchemaErrorTree(decoded.left);
671
+ const schemaTree = (() => {
672
+ try {
673
+ Schema.decodeUnknownSync(params.valuesSchema)(values);
674
+ return {};
675
+ } catch (error) {
676
+ return toSchemaErrorTree(error);
677
+ }
678
+ })();
673
679
  yield* runtime.dispatch({
674
680
  _tag: "setValue",
675
681
  payload: { path: "errors.$schema", value: schemaTree }
@@ -711,8 +717,14 @@ var makeFormController = (params) => {
711
717
  $form: _metaAfterRules,
712
718
  ...valuesAfterRules
713
719
  } = stateAfterRules;
714
- const decoded = Schema.decodeUnknownEither(params.valuesSchema)(valuesAfterRules);
715
- const schemaTree = decoded._tag === "Right" ? {} : toSchemaErrorTree(decoded.left);
720
+ const schemaTree = (() => {
721
+ try {
722
+ Schema.decodeUnknownSync(params.valuesSchema)(valuesAfterRules);
723
+ return {};
724
+ } catch (error) {
725
+ return toSchemaErrorTree(error);
726
+ }
727
+ })();
716
728
  yield* runtime.dispatch({
717
729
  _tag: "setValue",
718
730
  payload: { path: "errors.$schema", value: schemaTree }
@@ -828,7 +840,7 @@ var install = (module, config) => module.logic(($) => {
828
840
  const prev = pending.get(path);
829
841
  if (!prev) return;
830
842
  pending.delete(path);
831
- yield* Fiber.interruptFork(prev);
843
+ yield* Fiber.interrupt(prev);
832
844
  });
833
845
  const scheduleDebouncedValidate = (path) => Effect2.gen(function* () {
834
846
  const ms = debounceMs ?? 0;
@@ -839,9 +851,9 @@ var install = (module, config) => module.logic(($) => {
839
851
  yield* cancelPending(path);
840
852
  const fiber = yield* Effect2.forkScoped(
841
853
  Effect2.sleep(Duration.millis(ms)).pipe(
842
- Effect2.zipRight(validate("valueChange", path)),
854
+ Effect2.flatMap(() => validate("valueChange", path)),
843
855
  Effect2.ensuring(Effect2.sync(() => pending.delete(path))),
844
- Effect2.catchAllCause(() => Effect2.void)
856
+ Effect2.catchCause(() => Effect2.void)
845
857
  )
846
858
  );
847
859
  pending.set(path, fiber);
@@ -1018,14 +1030,12 @@ var make2 = (id, config, extend) => {
1018
1030
  isDirty: Schema2.Boolean,
1019
1031
  errorCount: Schema2.Number
1020
1032
  });
1021
- const StateSchema = Schema2.extend(
1022
- config.values,
1023
- Schema2.Struct({
1024
- errors: ErrorsSchema,
1025
- ui: UiSchema,
1026
- $form: MetaSchema
1027
- })
1028
- );
1033
+ const StateSchema = Schema2.Struct({
1034
+ ...config.values.fields ?? {},
1035
+ errors: ErrorsSchema,
1036
+ ui: UiSchema,
1037
+ $form: MetaSchema
1038
+ });
1029
1039
  const Actions = FormActions;
1030
1040
  const reducers = makeFormReducers({
1031
1041
  initialValues: config.initialValues
@@ -1067,67 +1077,60 @@ var make2 = (id, config, extend) => {
1067
1077
  if (mode === "store" || mode === "index") return;
1068
1078
  throw new Error(`[Form.make] Invalid identity.mode for "${listPath}" (got "${String(mode)}")`);
1069
1079
  };
1080
+ const isRelativeRuleDep = (dep, options) => {
1081
+ const allowNumericRelativeDep = options?.allowNumericRelativeDep ?? true;
1082
+ if (dep === "$root") return false;
1083
+ if (dep.includes("[") || dep.includes("]") || dep.includes(".")) return false;
1084
+ if (!allowNumericRelativeDep && /^[0-9]+$/.test(dep)) return false;
1085
+ return true;
1086
+ };
1087
+ const prefixRuleDeps = (deps, prefix, options) => {
1088
+ if (!Array.isArray(deps)) return void 0;
1089
+ const out = [];
1090
+ for (const raw of deps) {
1091
+ if (typeof raw !== "string") continue;
1092
+ const dep = raw.trim();
1093
+ if (!dep) continue;
1094
+ out.push(isRelativeRuleDep(dep, options) && prefix ? `${prefix}.${dep}` : dep);
1095
+ }
1096
+ return out;
1097
+ };
1098
+ const prefixRuleInputDeps = (input, prefix, options) => {
1099
+ if (!input || typeof input !== "object") return input;
1100
+ if (Array.isArray(input)) return input;
1101
+ const anyInput = input;
1102
+ const deps = prefixRuleDeps(anyInput.deps, prefix, options);
1103
+ const validate = anyInput.validate;
1104
+ if (typeof validate === "function") {
1105
+ return deps !== void 0 ? { ...anyInput, deps } : input;
1106
+ }
1107
+ if (validate && typeof validate === "object" && !Array.isArray(validate)) {
1108
+ const nextValidate = { ...validate };
1109
+ for (const [name, raw] of Object.entries(validate)) {
1110
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
1111
+ const entryDeps = prefixRuleDeps(raw.deps, prefix, options);
1112
+ if (entryDeps !== void 0) {
1113
+ nextValidate[name] = { ...raw, deps: entryDeps };
1114
+ }
1115
+ }
1116
+ return {
1117
+ ...anyInput,
1118
+ ...deps !== void 0 ? { deps } : {},
1119
+ validate: nextValidate
1120
+ };
1121
+ }
1122
+ return deps !== void 0 ? { ...anyInput, deps } : input;
1123
+ };
1070
1124
  const compileRulesToTraitSpec = (rulesSpec2) => {
1071
1125
  if (!rulesSpec2 || rulesSpec2._tag !== "FormRulesSpec") {
1072
1126
  throw new Error(`[Form.make] "rules" must be a FormRulesSpec (from Form.rules(...)/rules.schema(...))`);
1073
1127
  }
1074
- const joinPath2 = (prefix, suffix) => {
1075
- if (!prefix) return suffix;
1076
- if (!suffix) return prefix;
1077
- return `${prefix}.${suffix}`;
1078
- };
1079
1128
  const dirnamePath = (path) => {
1080
1129
  const p = String(path ?? "").trim();
1081
1130
  if (!p) return "";
1082
1131
  const idx = p.lastIndexOf(".");
1083
1132
  return idx >= 0 ? p.slice(0, idx) : "";
1084
1133
  };
1085
- const isRelativeDep = (dep) => {
1086
- if (typeof dep !== "string") return false;
1087
- const d = dep.trim();
1088
- if (!d) return false;
1089
- if (d === "$root") return false;
1090
- if (d.includes("[") || d.includes("]")) return false;
1091
- if (d.includes(".")) return false;
1092
- return true;
1093
- };
1094
- const prefixDeps = (deps, prefix) => {
1095
- if (!Array.isArray(deps)) return void 0;
1096
- const out = [];
1097
- for (const raw of deps) {
1098
- if (typeof raw !== "string") continue;
1099
- const d = raw.trim();
1100
- if (!d) continue;
1101
- out.push(isRelativeDep(d) ? joinPath2(prefix, d) : d);
1102
- }
1103
- return out;
1104
- };
1105
- const prefixRuleInputDeps = (input, prefix) => {
1106
- if (!input || typeof input !== "object") return input;
1107
- if (Array.isArray(input)) return input;
1108
- const anyInput = input;
1109
- const deps = prefixDeps(anyInput.deps, prefix);
1110
- const validate = anyInput.validate;
1111
- if (typeof validate === "function") {
1112
- return deps !== void 0 ? { ...anyInput, deps } : input;
1113
- }
1114
- if (validate && typeof validate === "object" && !Array.isArray(validate)) {
1115
- const nextValidate = { ...validate };
1116
- for (const [name, raw] of Object.entries(validate)) {
1117
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
1118
- const entryDeps = prefixDeps(raw.deps, prefix);
1119
- if (entryDeps !== void 0) {
1120
- nextValidate[name] = { ...raw, deps: entryDeps };
1121
- }
1122
- }
1123
- return {
1124
- ...anyInput,
1125
- ...deps !== void 0 ? { deps } : {},
1126
- validate: nextValidate
1127
- };
1128
- }
1129
- return deps !== void 0 ? { ...anyInput, deps } : input;
1130
- };
1131
1134
  const decls = Array.isArray(rulesSpec2.decls) ? rulesSpec2.decls : [];
1132
1135
  const spec = {};
1133
1136
  const declared = /* @__PURE__ */ new Set();
@@ -1302,45 +1305,9 @@ var make2 = (id, config, extend) => {
1302
1305
  const idx = valuePath.lastIndexOf(".");
1303
1306
  return idx >= 0 ? valuePath.slice(0, idx) : "";
1304
1307
  })();
1305
- const prefixDeps = (deps, prefix) => {
1306
- if (!Array.isArray(deps)) return void 0;
1307
- const out = [];
1308
- for (const raw of deps) {
1309
- if (typeof raw !== "string") continue;
1310
- const d = raw.trim();
1311
- if (!d) continue;
1312
- const isRelative = d !== "$root" && !d.includes("[") && !d.includes("]") && !d.includes(".") && !/^[0-9]+$/.test(d);
1313
- out.push(isRelative && prefix ? `${prefix}.${d}` : d);
1314
- }
1315
- return out;
1316
- };
1317
- const prefixRuleInputDeps = (input, prefix) => {
1318
- if (!input || typeof input !== "object") return input;
1319
- if (Array.isArray(input)) return input;
1320
- const anyInput = input;
1321
- const deps = prefixDeps(anyInput.deps, prefix);
1322
- const validate = anyInput.validate;
1323
- if (typeof validate === "function") {
1324
- return deps !== void 0 ? { ...anyInput, deps } : input;
1325
- }
1326
- if (validate && typeof validate === "object" && !Array.isArray(validate)) {
1327
- const nextValidate = { ...validate };
1328
- for (const [ruleName, raw] of Object.entries(validate)) {
1329
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
1330
- const entryDeps = prefixDeps(raw.deps, prefix);
1331
- if (entryDeps !== void 0) {
1332
- nextValidate[ruleName] = { ...raw, deps: entryDeps };
1333
- }
1334
- }
1335
- return {
1336
- ...anyInput,
1337
- ...deps !== void 0 ? { deps } : {},
1338
- validate: nextValidate
1339
- };
1340
- }
1341
- return deps !== void 0 ? { ...anyInput, deps } : input;
1342
- };
1343
- const ruleInput = prefixRuleInputDeps(decl.rule, depsPrefix);
1308
+ const ruleInput = prefixRuleInputDeps(decl.rule, depsPrefix, {
1309
+ allowNumericRelativeDep: false
1310
+ });
1344
1311
  const rules3 = make(ruleInput);
1345
1312
  emitRuleSet({
1346
1313
  source: "rules",
@@ -1620,8 +1587,12 @@ var makeFieldNode = (rule) => ({
1620
1587
  var fieldFromSchema = (schema) => ({
1621
1588
  validate: {
1622
1589
  schema: (value) => {
1623
- const decoded = Schema3.decodeUnknownEither(schema)(value);
1624
- return decoded._tag === "Right" ? void 0 : schemaErrorMessage(decoded.left);
1590
+ try {
1591
+ Schema3.decodeUnknownSync(schema)(value);
1592
+ return void 0;
1593
+ } catch (error) {
1594
+ return schemaErrorMessage(error);
1595
+ }
1625
1596
  }
1626
1597
  }
1627
1598
  });
@@ -1882,4 +1853,4 @@ export {
1882
1853
  node,
1883
1854
  list2 as list
1884
1855
  };
1885
- //# sourceMappingURL=chunk-YHDEJ47V.js.map
1856
+ //# sourceMappingURL=chunk-WGBRLVRO.js.map