@fougere/svelte 0.16.0-alpha.0 → 0.16.2-alpha.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/useFormFor.d.ts +5 -5
- package/dist/useFormFor.d.ts.map +1 -1
- package/dist/useFormFor.js +1 -1
- package/dist/useFormFor.js.map +1 -1
- package/package.json +4 -4
- package/src/useFormFor.ts +12 -9
package/dist/useFormFor.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** The form contract — state, validation, submission, error mapping. */
|
|
2
2
|
import { type Readable, type Writable } from 'svelte/store';
|
|
3
|
-
import { type FormEntity, type FormField } from '@fougere/app/client';
|
|
3
|
+
import { type FormEntity, type FormField, type FormRow } from '@fougere/app/client';
|
|
4
4
|
export interface FormOptions {
|
|
5
5
|
/** Command the submit rides. Default: 'create'. */
|
|
6
6
|
op?: string;
|
|
@@ -9,14 +9,14 @@ export interface FormOptions {
|
|
|
9
9
|
/** Call params designating the target (edit mode: { id }). */
|
|
10
10
|
params?: Record<string, string>;
|
|
11
11
|
}
|
|
12
|
-
export declare function useFormFor<
|
|
12
|
+
export declare function useFormFor<E extends FormEntity>(entity: E, options?: FormOptions): {
|
|
13
13
|
fields: FormField[];
|
|
14
14
|
/** The same fields, keyed by name — spread `fieldsByName.email.attrs` on an input
|
|
15
15
|
* and the page states no rule of its own. */
|
|
16
16
|
fieldsByName: Record<string, FormField>;
|
|
17
|
-
values: Writable<
|
|
18
|
-
errors: Writable<Record<string, string
|
|
19
|
-
submit: () => Promise<
|
|
17
|
+
values: Writable<Partial<FormRow<E>>>;
|
|
18
|
+
errors: Writable<Partial<Record<keyof FormRow<E> & string, string>>>;
|
|
19
|
+
submit: () => Promise<FormRow<E> | null>;
|
|
20
20
|
validator: () => boolean;
|
|
21
21
|
valid: Readable<boolean>;
|
|
22
22
|
/** `{ loading, error }` of the underlying command. */
|
package/dist/useFormFor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFormFor.d.ts","sourceRoot":"","sources":["../src/useFormFor.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAA0B,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEpF,OAAO,EAML,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"useFormFor.d.ts","sourceRoot":"","sources":["../src/useFormFor.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAA0B,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEpF,OAAO,EAML,KAAK,UAAU,EAEf,KAAK,SAAS,EACd,KAAK,OAAO,EAEb,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAE,WAAgB;;IAyCjF;kDAC8C;kBACkC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;;;kBArBlF,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;qBAP7B,OAAO;;IAkC3B,sDAAsD;;EAGzD"}
|
package/dist/useFormFor.js
CHANGED
|
@@ -11,7 +11,7 @@ export function useFormFor(entity, options = {}) {
|
|
|
11
11
|
const values = writable(Object.fromEntries(fields.map((field) => [field.name, options.initial?.[field.name] ?? field.default])));
|
|
12
12
|
const errors = writable({});
|
|
13
13
|
// A form is designated by its ENTITY — it is a set of fields — so the facade it submits to is
|
|
14
|
-
// an address with no handler type behind it, and
|
|
14
|
+
// an address with no handler type behind it, and what it answers is the entity's row.
|
|
15
15
|
const command = useCommand(facadeOf(entity), options.op ?? 'create');
|
|
16
16
|
/** Local pre-verdict — same rules as the handler, saves a lost round-trip. */
|
|
17
17
|
function validator() {
|
package/dist/useFormFor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFormFor.js","sourceRoot":"","sources":["../src/useFormFor.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAgC,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACL,WAAW,EACX,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,SAAS,
|
|
1
|
+
{"version":3,"file":"useFormFor.js","sourceRoot":"","sources":["../src/useFormFor.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAgC,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACL,WAAW,EACX,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,SAAS,GAMV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAW9D,MAAM,UAAU,UAAU,CAAuB,MAAS,EAAE,OAAO,GAAgB,EAAE;IACnF,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,MAAM,GAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAE5D,8EAA8E;IAC9E,gFAAgF;IAChF,MAAM,MAAM,GAA4B,QAAQ,CAC9C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAkB,CACzH,CAAC;IACF,MAAM,MAAM,GAAG,QAAQ,CAAgB,EAAE,CAAC,CAAC;IAC3C,8FAA8F;IAC9F,sFAAsF;IACtF,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,IAAI,QAAQ,CAAC,CAAC;IAErE,8EAA8E;IAC9E,SAAS,SAAS;QAChB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAElE,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,UAAU,MAAM;QACnB,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,IAAI,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAe,CAAC;QAClH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,aAAa,CAAI,QAAQ,CAAC,CAAC,CAAC;gBAEvC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAsB,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IAEjG,OAAO;QACL,MAAM;QACN;sDAC8C;QAC9C,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAA8B;QACzG,MAAM;QACN,MAAM;QACN,MAAM;QACN,SAAS;QACT,KAAK;QACL,sDAAsD;QACtD,OAAO;KACR,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/svelte",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2-alpha.0",
|
|
4
4
|
"description": "Fougere's four primitives as Svelte stores — host-independent.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"template"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@fougere/app": "0.16.
|
|
35
|
-
"@fougere/core": "0.16.
|
|
34
|
+
"@fougere/app": "0.16.2-alpha.0",
|
|
35
|
+
"@fougere/core": "0.16.2-alpha.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"svelte": "^5.53.4",
|
|
39
39
|
"vitest": "^4.1.0",
|
|
40
|
-
"@fougere/schema": "0.16.
|
|
40
|
+
"@fougere/schema": "0.16.2-alpha.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"svelte": "^5.0.0"
|
package/src/useFormFor.ts
CHANGED
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
formFieldsOf,
|
|
9
9
|
payloadOf,
|
|
10
10
|
type FormEntity,
|
|
11
|
+
type FormErrors,
|
|
11
12
|
type FormField,
|
|
13
|
+
type FormRow,
|
|
14
|
+
type FormValues,
|
|
12
15
|
} from '@fougere/app/client';
|
|
13
16
|
import { useCommand } from './useFougereData/CommandStore.js';
|
|
14
17
|
|
|
@@ -21,36 +24,36 @@ export interface FormOptions {
|
|
|
21
24
|
params?: Record<string, string>;
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
export function useFormFor<
|
|
27
|
+
export function useFormFor<E extends FormEntity>(entity: E, options: FormOptions = {}) {
|
|
25
28
|
const entityKey = entityKeyOf(entity);
|
|
26
29
|
const fields: FormField[] = formFieldsOf(entity, entityKey);
|
|
27
30
|
|
|
28
31
|
// `initial` wins over the declared default: editing a row shows the row. On a
|
|
29
32
|
// create form there is none, so the field opens on what is about to be written.
|
|
30
|
-
const values: Writable<
|
|
31
|
-
Object.fromEntries(fields.map((field) => [field.name, options.initial?.[field.name] ?? field.default]))
|
|
33
|
+
const values: Writable<FormValues<E>> = writable(
|
|
34
|
+
Object.fromEntries(fields.map((field) => [field.name, options.initial?.[field.name] ?? field.default])) as FormValues<E>,
|
|
32
35
|
);
|
|
33
|
-
const errors = writable<
|
|
36
|
+
const errors = writable<FormErrors<E>>({});
|
|
34
37
|
// A form is designated by its ENTITY — it is a set of fields — so the facade it submits to is
|
|
35
|
-
// an address with no handler type behind it, and
|
|
38
|
+
// an address with no handler type behind it, and what it answers is the entity's row.
|
|
36
39
|
const command = useCommand(facadeOf(entity), options.op ?? 'create');
|
|
37
40
|
|
|
38
41
|
/** Local pre-verdict — same rules as the handler, saves a lost round-trip. */
|
|
39
42
|
function validator(): boolean {
|
|
40
43
|
const result = entity.validate(payloadOf(entity, get(values)));
|
|
41
|
-
errors.set(result.success ? {} : errorsByField(result.errors));
|
|
44
|
+
errors.set(result.success ? {} : errorsByField<E>(result.errors));
|
|
42
45
|
|
|
43
46
|
return result.success;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
async function submit(): Promise<
|
|
49
|
+
async function submit(): Promise<FormRow<E> | null> {
|
|
47
50
|
if (!validator()) return null;
|
|
48
51
|
try {
|
|
49
|
-
return (await command.execute({ params: options.params, input: payloadOf(entity, get(values)) })) as
|
|
52
|
+
return (await command.execute({ params: options.params, input: payloadOf(entity, get(values)) })) as FormRow<E>;
|
|
50
53
|
} catch (err) {
|
|
51
54
|
const refusals = validationErrorsOf(err);
|
|
52
55
|
if (refusals) {
|
|
53
|
-
errors.set(errorsByField(refusals));
|
|
56
|
+
errors.set(errorsByField<E>(refusals));
|
|
54
57
|
|
|
55
58
|
return null;
|
|
56
59
|
}
|