@shivaedev/form 0.9.0 → 0.10.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/CHANGELOG.md +6 -0
- package/README.md +12 -0
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +2 -2
- package/dist/form.js.map +1 -1
- package/dist/messages.d.ts +4 -4
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +30 -9
- package/dist/messages.js.map +1 -1
- package/dist/shape.d.ts +3 -0
- package/dist/shape.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/form.ts +4 -2
- package/src/messages.ts +39 -10
- package/src/shape.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.0 - 2026-10-31
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Configure `requiredMessages` per string field to replace the generic required message without rebuilding the schema. Field feedback, path feedback and invalid submission messages use the same wording; explicit schema messages keep precedence.
|
|
8
|
+
|
|
3
9
|
## 0.9.0 - 2026-10-30
|
|
4
10
|
|
|
5
11
|
### Added
|
package/README.md
CHANGED
|
@@ -67,6 +67,18 @@ try {
|
|
|
67
67
|
|
|
68
68
|
The input quantity is a string; the successful result contains quantity `350`. Invalid input fails with `Invalid` before `onSubmit` runs. The handler can fail a named field with `submitter.fail`; changing that field clears the rejection, and another submission uses the new input.
|
|
69
69
|
|
|
70
|
+
Set `requiredMessages` to give a top-level string field its own wording while keeping `Schema.NonEmptyString`:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const order = form(fields, {
|
|
74
|
+
initialValues: { name: "", quantity: "300" },
|
|
75
|
+
onSubmit: Effect.succeed,
|
|
76
|
+
requiredMessages: { name: "Enter the order name" },
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
An empty name shows that message after blur or submission, including through `errorAt(["name"])` and `Invalid.messages`. Entering a name clears it. Explicit schema messages take precedence; longer minimum lengths keep their validation message. Fields without a configured message keep the default `"Required"`.
|
|
81
|
+
|
|
70
82
|
The handler has three arguments: decoded values, the submitter, and the submitted encoded snapshot. Use the third argument when coordinating work against what was submitted, rather than reading live fields after an asynchronous decode. The `react` create adapter uses that snapshot to preserve input typed while decoding.
|
|
71
83
|
|
|
72
84
|
### In the UI: bind the same form
|
package/dist/form.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAkC,MAAM,QAAQ,CAAC;AAS9F,OAAO,EACN,KAAK,MAAM,EAIX,KAAK,MAAM,EACX,KAAK,IAAI,EAKT,MAAM,YAAY,CAAC;AAapB,wBAAgB,IAAI,CAAC,OAAO,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,aAAa,GAAG,KAAK,EACpG,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,GAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAkC,MAAM,QAAQ,CAAC;AAS9F,OAAO,EACN,KAAK,MAAM,EAIX,KAAK,MAAM,EACX,KAAK,IAAI,EAKT,MAAM,YAAY,CAAC;AAapB,wBAAgB,IAAI,CAAC,OAAO,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,aAAa,GAAG,KAAK,EACpG,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,GAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,CAgH9C"}
|
package/dist/form.js
CHANGED
|
@@ -38,7 +38,7 @@ export function form(schema, config) {
|
|
|
38
38
|
onFailure: (issue) => Result.fail(issue),
|
|
39
39
|
onSuccess: (value) => Result.succeed(value),
|
|
40
40
|
})));
|
|
41
|
-
const schemaErrors = schemaFeedback(decoded);
|
|
41
|
+
const schemaErrors = schemaFeedback(decoded, config.requiredMessages);
|
|
42
42
|
const checkError = Atom.family((name) => {
|
|
43
43
|
const check = checks.get(name);
|
|
44
44
|
if (check === undefined) {
|
|
@@ -72,7 +72,7 @@ export function form(schema, config) {
|
|
|
72
72
|
status.attempt();
|
|
73
73
|
const submission = editing.submission();
|
|
74
74
|
const submitted = submission.values;
|
|
75
|
-
const value = yield* decode(submitted).pipe(Effect.mapError((issue) => new Invalid({ messages: messagesByField(issue) })));
|
|
75
|
+
const value = yield* decode(submitted).pipe(Effect.mapError((issue) => new Invalid({ messages: messagesByField(issue, config.requiredMessages) })));
|
|
76
76
|
return yield* onSubmit(value, submitter, submitted).pipe(Effect.tapError(noted(submitted)), Effect.tap(() => Effect.sync(submission.accept)));
|
|
77
77
|
}));
|
|
78
78
|
return {
|
package/dist/form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"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"}
|
package/dist/messages.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
|
3
3
|
import * as Atom from "effect/reactivity/Atom";
|
|
4
4
|
export type FieldMessages = Readonly<Record<string, string>>;
|
|
5
5
|
export declare const noMessages: FieldMessages;
|
|
6
|
-
export declare function messagesByField(issue: SchemaIssue.Issue): FieldMessages;
|
|
7
|
-
export declare function messageAtPath(issue: SchemaIssue.Issue, path: readonly PropertyKey[]): string | undefined;
|
|
6
|
+
export declare function messagesByField(issue: SchemaIssue.Issue, requiredMessages?: Readonly<Partial<Record<string, string>>>): FieldMessages;
|
|
7
|
+
export declare function messageAtPath(issue: SchemaIssue.Issue, path: readonly PropertyKey[], requiredMessages?: Readonly<Partial<Record<string, string>>>): string | undefined;
|
|
8
8
|
export declare function withoutField(messages: FieldMessages, name: string): FieldMessages;
|
|
9
9
|
export declare function literalChoices(input: SchemaAST.AST): readonly SchemaAST.LiteralValue[] | undefined;
|
|
10
|
-
export declare function messageAt(messages:
|
|
11
|
-
export declare function schemaFeedback<A, E>(decoded: Atom.Atom<AsyncResult.AsyncResult<Result.Result<A, SchemaIssue.Issue>, E
|
|
10
|
+
export declare function messageAt(messages: Readonly<Partial<Record<string, string>>>, name: string): string | undefined;
|
|
11
|
+
export declare function schemaFeedback<A, E>(decoded: Atom.Atom<AsyncResult.AsyncResult<Result.Result<A, SchemaIssue.Issue>, E>>, requiredMessages?: Readonly<Partial<Record<string, string>>>): {
|
|
12
12
|
at: (path: readonly PropertyKey[]) => Atom.Atom<string | undefined>;
|
|
13
13
|
field: (arg: string) => Atom.Atom<string | undefined>;
|
|
14
14
|
};
|
package/dist/messages.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAE,SAAS,EAAE,WAAW,EAAuB,MAAM,QAAQ,CAAC;AACrF,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7D,eAAO,MAAM,UAAU,EAAE,aAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAE,SAAS,EAAE,WAAW,EAAuB,MAAM,QAAQ,CAAC;AACrF,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7D,eAAO,MAAM,UAAU,EAAE,aAAkB,CAAC;AAgD5C,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAc,GAAG,aAAa,CAajJ;AAED,wBAAgB,aAAa,CAC5B,KAAK,EAAE,WAAW,CAAC,KAAK,EACxB,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,gBAAgB,GAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAc,GACtE,MAAM,GAAG,SAAS,CAYpB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAWjF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,GAAG,SAAS,SAAS,CAAC,YAAY,EAAE,GAAG,SAAS,CAalG;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/G;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAClC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EACnF,gBAAgB,GAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAc;IASvE,EAAE,SAAS,SAAS,WAAW,EAAE;IAUjC,KAAK;EAEN"}
|
package/dist/messages.js
CHANGED
|
@@ -15,14 +15,35 @@ function refusesEmpty(check) {
|
|
|
15
15
|
}
|
|
16
16
|
return payload.minLength === 1;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
function formatter(required = REQUIRED) {
|
|
19
|
+
return SchemaIssue.makeFormatterStandardSchemaV1({
|
|
20
|
+
checkHook: (issue) => SchemaIssue.defaultCheckHook(issue) ?? (refusesEmpty(issue.filter) ? required : undefined),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const formatIssue = formatter();
|
|
24
|
+
function formattedIssues(issue, requiredMessages) {
|
|
25
|
+
const issues = formatIssue(issue).issues;
|
|
26
|
+
const customized = new Map();
|
|
27
|
+
return issues.map((entry, index) => {
|
|
28
|
+
const head = entry.path?.[0];
|
|
29
|
+
const required = head === undefined ? undefined : messageAt(requiredMessages, segmentKey(head));
|
|
30
|
+
if (required === undefined) {
|
|
31
|
+
return entry;
|
|
32
|
+
}
|
|
33
|
+
let entries = customized.get(required);
|
|
34
|
+
if (entries === undefined) {
|
|
35
|
+
entries = formatter(required)(issue).issues;
|
|
36
|
+
customized.set(required, entries);
|
|
37
|
+
}
|
|
38
|
+
return entries[index] ?? entry;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
20
41
|
function segmentKey(segment) {
|
|
21
42
|
return typeof segment === "object" ? String(segment.key) : String(segment);
|
|
22
43
|
}
|
|
23
|
-
export function messagesByField(issue) {
|
|
44
|
+
export function messagesByField(issue, requiredMessages = noMessages) {
|
|
24
45
|
const messages = Object.create(null);
|
|
25
|
-
for (const entry of
|
|
46
|
+
for (const entry of formattedIssues(issue, requiredMessages)) {
|
|
26
47
|
const head = entry.path?.[0];
|
|
27
48
|
if (head === undefined) {
|
|
28
49
|
continue;
|
|
@@ -34,8 +55,8 @@ export function messagesByField(issue) {
|
|
|
34
55
|
}
|
|
35
56
|
return messages;
|
|
36
57
|
}
|
|
37
|
-
export function messageAtPath(issue, path) {
|
|
38
|
-
for (const entry of
|
|
58
|
+
export function messageAtPath(issue, path, requiredMessages = noMessages) {
|
|
59
|
+
for (const entry of formattedIssues(issue, requiredMessages)) {
|
|
39
60
|
if (path.every((segment, index) => {
|
|
40
61
|
const found = entry.path?.[index];
|
|
41
62
|
return found !== undefined && segment === (typeof found === "object" ? found.key : found);
|
|
@@ -74,10 +95,10 @@ export function literalChoices(input) {
|
|
|
74
95
|
export function messageAt(messages, name) {
|
|
75
96
|
return Object.hasOwn(messages, name) ? messages[name] : undefined;
|
|
76
97
|
}
|
|
77
|
-
export function schemaFeedback(decoded) {
|
|
98
|
+
export function schemaFeedback(decoded, requiredMessages = noMessages) {
|
|
78
99
|
const messages = Atom.map(decoded, (result) => Option.match(AsyncResult.value(result), {
|
|
79
100
|
onNone: () => noMessages,
|
|
80
|
-
onSome: (value) => (Result.isFailure(value) ? messagesByField(value.failure) : noMessages),
|
|
101
|
+
onSome: (value) => (Result.isFailure(value) ? messagesByField(value.failure, requiredMessages) : noMessages),
|
|
81
102
|
}));
|
|
82
103
|
return {
|
|
83
104
|
at: (path) => Atom.map(decoded, (result) => {
|
|
@@ -86,7 +107,7 @@ export function schemaFeedback(decoded) {
|
|
|
86
107
|
}
|
|
87
108
|
return Option.match(AsyncResult.value(result), {
|
|
88
109
|
onNone: () => undefined,
|
|
89
|
-
onSome: (value) => (Result.isFailure(value) ? messageAtPath(value.failure, path) : undefined),
|
|
110
|
+
onSome: (value) => (Result.isFailure(value) ? messageAtPath(value.failure, path, requiredMessages) : undefined),
|
|
90
111
|
});
|
|
91
112
|
}),
|
|
92
113
|
field: Atom.family((name) => Atom.map(messages, (value) => messageAt(value, name))),
|
package/dist/messages.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAuB,MAAM,QAAQ,CAAC;AACrF,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAI/C,MAAM,CAAC,MAAM,UAAU,GAAkB,EAAE,CAAC;AAE5C,MAAM,QAAQ,GAAG,UAAU,CAAC;AAE5B,MAAM,cAAc,GAAG,2BAA2B,CAAC;AAEnD,SAAS,YAAY,CAAC,KAAgC;IACrD,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,EAAE,cAAc,CAAC;IACzD,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,CAAC,EAAE,KAAK,cAAc,EAAE,CAAC;QAC1E,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC;IACvC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,WAAW,IAAI,OAAO,CAAC,EAAE,CAAC;QAClF,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}
|
package/dist/shape.d.ts
CHANGED
|
@@ -43,6 +43,9 @@ export type Config<TFields extends Fields, A, E, R, TRuntimeError> = {
|
|
|
43
43
|
readonly initialValues: Encoded<TFields>;
|
|
44
44
|
readonly onSubmit: (values: Decoded<TFields>, submitter: Submitter<Name<TFields>>, submitted: Encoded<TFields>) => Effect.Effect<A, E, R | Scope.Scope | AtomRegistry | Reactivity>;
|
|
45
45
|
readonly persistedDraft?: PersistedDraftConfig | undefined;
|
|
46
|
+
readonly requiredMessages?: {
|
|
47
|
+
readonly [TKey in Name<TFields>]?: NonNullable<Encoded<TFields>[TKey]> extends string ? string : never;
|
|
48
|
+
};
|
|
46
49
|
} & ([Exclude<Services<TFields, R>, Scope.Scope | AtomRegistry | Reactivity>] extends [never] ? {
|
|
47
50
|
readonly runtime?: Atom.AtomRuntime<Services<TFields, R>, TRuntimeError>;
|
|
48
51
|
} : {
|
package/dist/shape.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../src/shape.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../src/shape.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/form",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Schema-derived Effect atom forms with optional React hooks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@effect/atom-react": "4.0.6",
|
|
47
47
|
"@effect/vitest": "4.0.6",
|
|
48
|
-
"@shivaedev/quality": "0.
|
|
48
|
+
"@shivaedev/quality": "0.50.0",
|
|
49
49
|
"@shivaedev/test": "0.12.0",
|
|
50
|
-
"@shivaedev/test-story": "0.
|
|
50
|
+
"@shivaedev/test-story": "0.30.0",
|
|
51
51
|
"@types/node": "24.19.2",
|
|
52
52
|
"@types/react": "19.3.0",
|
|
53
53
|
"effect": "4.0.6",
|
package/src/form.ts
CHANGED
|
@@ -69,7 +69,7 @@ export function form<TFields extends Fields, TValue, TError, TServices = never,
|
|
|
69
69
|
),
|
|
70
70
|
);
|
|
71
71
|
|
|
72
|
-
const schemaErrors = schemaFeedback(decoded);
|
|
72
|
+
const schemaErrors = schemaFeedback(decoded, config.requiredMessages);
|
|
73
73
|
|
|
74
74
|
const checkError = Atom.family((name: Name<TFields>): Atom.Atom<string | undefined> => {
|
|
75
75
|
const check = checks.get(name);
|
|
@@ -110,7 +110,9 @@ export function form<TFields extends Fields, TValue, TError, TServices = never,
|
|
|
110
110
|
status.attempt();
|
|
111
111
|
const submission = editing.submission();
|
|
112
112
|
const submitted = submission.values;
|
|
113
|
-
const value = yield* decode(submitted).pipe(
|
|
113
|
+
const value = yield* decode(submitted).pipe(
|
|
114
|
+
Effect.mapError((issue) => new Invalid({ messages: messagesByField(issue, config.requiredMessages) })),
|
|
115
|
+
);
|
|
114
116
|
return yield* onSubmit(value, submitter, submitted).pipe(
|
|
115
117
|
Effect.tapError(noted(submitted)),
|
|
116
118
|
Effect.tap(() => Effect.sync(submission.accept)),
|
package/src/messages.ts
CHANGED
|
@@ -22,17 +22,39 @@ function refusesEmpty(check: SchemaAST.Filter<unknown>): boolean {
|
|
|
22
22
|
return payload.minLength === 1;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
function formatter(required = REQUIRED) {
|
|
26
|
+
return SchemaIssue.makeFormatterStandardSchemaV1({
|
|
27
|
+
checkHook: (issue) => SchemaIssue.defaultCheckHook(issue) ?? (refusesEmpty(issue.filter) ? required : undefined),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const formatIssue = formatter();
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
function formattedIssues(issue: SchemaIssue.Issue, requiredMessages: Readonly<Partial<Record<string, string>>>) {
|
|
34
|
+
const issues = formatIssue(issue).issues;
|
|
35
|
+
const customized = new Map<string, ReturnType<typeof formatIssue>["issues"]>();
|
|
36
|
+
return issues.map((entry, index) => {
|
|
37
|
+
const head = entry.path?.[0];
|
|
38
|
+
const required = head === undefined ? undefined : messageAt(requiredMessages, segmentKey(head));
|
|
39
|
+
if (required === undefined) {
|
|
40
|
+
return entry;
|
|
41
|
+
}
|
|
42
|
+
let entries = customized.get(required);
|
|
43
|
+
if (entries === undefined) {
|
|
44
|
+
entries = formatter(required)(issue).issues;
|
|
45
|
+
customized.set(required, entries);
|
|
46
|
+
}
|
|
47
|
+
return entries[index] ?? entry;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
28
50
|
|
|
29
51
|
function segmentKey(segment: PropertyKey | StandardSchema.StandardSchemaV1.PathSegment): string {
|
|
30
52
|
return typeof segment === "object" ? String(segment.key) : String(segment);
|
|
31
53
|
}
|
|
32
54
|
|
|
33
|
-
export function messagesByField(issue: SchemaIssue.Issue): FieldMessages {
|
|
55
|
+
export function messagesByField(issue: SchemaIssue.Issue, requiredMessages: Readonly<Partial<Record<string, string>>> = noMessages): FieldMessages {
|
|
34
56
|
const messages: Record<string, string> = Object.create(null);
|
|
35
|
-
for (const entry of
|
|
57
|
+
for (const entry of formattedIssues(issue, requiredMessages)) {
|
|
36
58
|
const head = entry.path?.[0];
|
|
37
59
|
if (head === undefined) {
|
|
38
60
|
continue;
|
|
@@ -45,8 +67,12 @@ export function messagesByField(issue: SchemaIssue.Issue): FieldMessages {
|
|
|
45
67
|
return messages;
|
|
46
68
|
}
|
|
47
69
|
|
|
48
|
-
export function messageAtPath(
|
|
49
|
-
|
|
70
|
+
export function messageAtPath(
|
|
71
|
+
issue: SchemaIssue.Issue,
|
|
72
|
+
path: readonly PropertyKey[],
|
|
73
|
+
requiredMessages: Readonly<Partial<Record<string, string>>> = noMessages,
|
|
74
|
+
): string | undefined {
|
|
75
|
+
for (const entry of formattedIssues(issue, requiredMessages)) {
|
|
50
76
|
if (
|
|
51
77
|
path.every((segment, index) => {
|
|
52
78
|
const found = entry.path?.[index];
|
|
@@ -87,15 +113,18 @@ export function literalChoices(input: SchemaAST.AST): readonly SchemaAST.Literal
|
|
|
87
113
|
return choices;
|
|
88
114
|
}
|
|
89
115
|
|
|
90
|
-
export function messageAt(messages:
|
|
116
|
+
export function messageAt(messages: Readonly<Partial<Record<string, string>>>, name: string): string | undefined {
|
|
91
117
|
return Object.hasOwn(messages, name) ? messages[name] : undefined;
|
|
92
118
|
}
|
|
93
119
|
|
|
94
|
-
export function schemaFeedback<A, E>(
|
|
120
|
+
export function schemaFeedback<A, E>(
|
|
121
|
+
decoded: Atom.Atom<AsyncResult.AsyncResult<Result.Result<A, SchemaIssue.Issue>, E>>,
|
|
122
|
+
requiredMessages: Readonly<Partial<Record<string, string>>> = noMessages,
|
|
123
|
+
) {
|
|
95
124
|
const messages = Atom.map(decoded, (result) =>
|
|
96
125
|
Option.match(AsyncResult.value(result), {
|
|
97
126
|
onNone: () => noMessages,
|
|
98
|
-
onSome: (value) => (Result.isFailure(value) ? messagesByField(value.failure) : noMessages),
|
|
127
|
+
onSome: (value) => (Result.isFailure(value) ? messagesByField(value.failure, requiredMessages) : noMessages),
|
|
99
128
|
}),
|
|
100
129
|
);
|
|
101
130
|
return {
|
|
@@ -106,7 +135,7 @@ export function schemaFeedback<A, E>(decoded: Atom.Atom<AsyncResult.AsyncResult<
|
|
|
106
135
|
}
|
|
107
136
|
return Option.match(AsyncResult.value(result), {
|
|
108
137
|
onNone: () => undefined,
|
|
109
|
-
onSome: (value) => (Result.isFailure(value) ? messageAtPath(value.failure, path) : undefined),
|
|
138
|
+
onSome: (value) => (Result.isFailure(value) ? messageAtPath(value.failure, path, requiredMessages) : undefined),
|
|
110
139
|
});
|
|
111
140
|
}),
|
|
112
141
|
field: Atom.family((name: string) => Atom.map(messages, (value) => messageAt(value, name))),
|
package/src/shape.ts
CHANGED
|
@@ -53,6 +53,7 @@ export type Config<TFields extends Fields, A, E, R, TRuntimeError> = {
|
|
|
53
53
|
submitted: Encoded<TFields>,
|
|
54
54
|
) => Effect.Effect<A, E, R | Scope.Scope | AtomRegistry | Reactivity>;
|
|
55
55
|
readonly persistedDraft?: PersistedDraftConfig | undefined;
|
|
56
|
+
readonly requiredMessages?: { readonly [TKey in Name<TFields>]?: NonNullable<Encoded<TFields>[TKey]> extends string ? string : never };
|
|
56
57
|
} & ([Exclude<Services<TFields, R>, Scope.Scope | AtomRegistry | Reactivity>] extends [never]
|
|
57
58
|
? { readonly runtime?: Atom.AtomRuntime<Services<TFields, R>, TRuntimeError> }
|
|
58
59
|
: { readonly runtime: Atom.AtomRuntime<Services<TFields, R>, TRuntimeError> });
|