@tryghost/metafield-types 0.2.0 → 0.4.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 +66 -0
- package/README.md +26 -20
- package/build/index.d.ts +313 -63
- package/build/index.d.ts.map +1 -1
- package/build/index.js +325 -100
- package/build/index.js.map +1 -1
- package/build/shapes.d.ts +185 -0
- package/build/shapes.d.ts.map +1 -0
- package/build/shapes.js +262 -0
- package/build/shapes.js.map +1 -0
- package/build/structure.d.ts +283 -59
- package/build/structure.d.ts.map +1 -1
- package/build/structure.js +179 -59
- package/build/structure.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rules every field of a shape follows, whatever its type and settings, and the rules a field
|
|
3
|
+
* adds from its settings when a held value is read.
|
|
4
|
+
*
|
|
5
|
+
* A shape's rules look only at structure: they know a list is a list of strings, but not which
|
|
6
|
+
* strings a field offers. They also say what a write does to a held value, which is part of the
|
|
7
|
+
* API's contract rather than storage's choice: a client works out a write against the value its
|
|
8
|
+
* form loaded, and Ghost applies it to whatever is stored when it lands, which another writer may
|
|
9
|
+
* have changed in between. The two only agree because both read the rules here.
|
|
10
|
+
*
|
|
11
|
+
* Each table is keyed by shape, so a shape added to the catalog fails to compile here until it has
|
|
12
|
+
* an entry. Each translator of a shape into another domain's terms, such as the storage translator
|
|
13
|
+
* into rows or the CSV translator into cells, keeps its own table of the same form, which `shaped`
|
|
14
|
+
* lets it index without a cast.
|
|
15
|
+
*
|
|
16
|
+
* Zod-free, like `./structure`, so Portal can use it. The strict rule a write must meet is built
|
|
17
|
+
* from zod and lives in `./index` as `accept`.
|
|
18
|
+
*/
|
|
19
|
+
import { type FieldOfShape, type FieldShape, type FieldType, type FieldTypeOfShape, type Leaf, type LeafKind, type LeafValues, type TypedSettings, type ValueOf, type WriteOf } from './structure.js';
|
|
20
|
+
/** A leaf's value of any kind. */
|
|
21
|
+
export type AnyLeafValue = LeafValues[LeafKind];
|
|
22
|
+
/**
|
|
23
|
+
* What a value of each JSON kind is. Primitives only: the shape rules compare two leaf values with
|
|
24
|
+
* `===`, which a kind holding objects would break.
|
|
25
|
+
*/
|
|
26
|
+
interface KindValues {
|
|
27
|
+
string: string;
|
|
28
|
+
number: number;
|
|
29
|
+
boolean: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** The JSON kind a value comes in. */
|
|
32
|
+
type KindOf<V> = {
|
|
33
|
+
[K in keyof KindValues]: V extends KindValues[K] ? K : never;
|
|
34
|
+
}[keyof KindValues];
|
|
35
|
+
/**
|
|
36
|
+
* The JSON kinds the catalog's leaves' values come in, which is all that tells two leaves' values
|
|
37
|
+
* apart without their field: how storage picks a value's column, and a filter what to compare it
|
|
38
|
+
* in. Read from the leaves, so a leaf kind whose value is a new JSON kind widens it.
|
|
39
|
+
*/
|
|
40
|
+
export type ValueKind = KindOf<AnyLeafValue>;
|
|
41
|
+
/** The leaf values of one JSON kind. */
|
|
42
|
+
export type ValueOfKind<K extends ValueKind> = Extract<AnyLeafValue, KindValues[K]>;
|
|
43
|
+
/**
|
|
44
|
+
* What the domain knows about each kind of leaf beyond its rule, which needs zod and is
|
|
45
|
+
* `LEAF_RULES` in `./index`. Keyed by kind, so a kind added to the catalog fails to compile here
|
|
46
|
+
* until it says each.
|
|
47
|
+
*/
|
|
48
|
+
interface LeafKindRules<K extends LeafKind> {
|
|
49
|
+
/** The JSON kind its value comes in. */
|
|
50
|
+
readonly kind: KindOf<LeafValues[K]>;
|
|
51
|
+
/** A raw value read as this leaf's value, or undefined when it holds none. */
|
|
52
|
+
read(raw: unknown): LeafValues[K] | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Text, as a form's input or a CSV cell holds it, read as this leaf's value, or the text itself
|
|
55
|
+
* where it holds none, so the leaf's rule refuses it rather than it being dropped. Writing a
|
|
56
|
+
* value as text is `String` for every kind.
|
|
57
|
+
*/
|
|
58
|
+
fromText(text: string): LeafValues[K] | string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* What a value of each shape holds: whatever a type of that shape holds, read from the catalog, so a
|
|
62
|
+
* type's parts and leaves are typed the same way here. A value always holds something: a field
|
|
63
|
+
* holding nothing has no value at all, rather than an empty one, so `0` and an answer left blank are
|
|
64
|
+
* never confused. A record holds at least one part, and a set at least one option.
|
|
65
|
+
*/
|
|
66
|
+
export type ShapeValue = {
|
|
67
|
+
[S in FieldShape]: ValueOf<FieldTypeOfShape<S>>;
|
|
68
|
+
};
|
|
69
|
+
/** What a write to a field of each shape gives, from the catalog in the same way; see `WriteOf`. */
|
|
70
|
+
export type ShapeWrite = {
|
|
71
|
+
[S in FieldShape]: WriteOf<FieldTypeOfShape<S>>;
|
|
72
|
+
};
|
|
73
|
+
export interface ShapeRules<S extends FieldShape> {
|
|
74
|
+
/**
|
|
75
|
+
* What `raw` holds as a value of `type`, or undefined when it holds nothing of it. Lenient: a part
|
|
76
|
+
* the type doesn't declare, or one of another kind than its leaf, is left out.
|
|
77
|
+
*/
|
|
78
|
+
parse(type: FieldTypeOfShape<S>, raw: unknown): ShapeValue[S] | undefined;
|
|
79
|
+
/** Whether two values hold the same, which a write that changes nothing leaves alone. */
|
|
80
|
+
same(a: ShapeValue[S], b: ShapeValue[S]): boolean;
|
|
81
|
+
/** What a write does to what is held, which is nothing when a record's write clears every part. */
|
|
82
|
+
apply(held: ShapeValue[S] | undefined, write: ShapeWrite[S]): ShapeValue[S] | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* The smallest write that turns `held` into `next`: `null` when `next` holds nothing, and
|
|
85
|
+
* undefined when the two hold the same.
|
|
86
|
+
*/
|
|
87
|
+
diff(held: ShapeValue[S] | undefined, next: ShapeValue[S] | undefined): ShapeWrite[S] | null | undefined;
|
|
88
|
+
}
|
|
89
|
+
export declare const LEAVES: {
|
|
90
|
+
readonly [K in LeafKind]: LeafKindRules<K>;
|
|
91
|
+
};
|
|
92
|
+
/** Each shape's rules. A shape added to the catalog without rules doesn't compile. */
|
|
93
|
+
export declare const SHAPES: {
|
|
94
|
+
readonly [S in FieldShape]: ShapeRules<S>;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* A field together with its shape, as one of a union with a member per shape. Indexing a table
|
|
98
|
+
* keyed by shape with `shape` gives the entry for the same shape that `field` has, so a translator
|
|
99
|
+
* such as the storage translator can call its entry for a field without a cast or a branch per
|
|
100
|
+
* shape.
|
|
101
|
+
*/
|
|
102
|
+
export type ShapedField<F extends TypedSettings = TypedSettings, S extends FieldShape = FieldShape> = {
|
|
103
|
+
[K in S]: {
|
|
104
|
+
readonly shape: K;
|
|
105
|
+
readonly field: FieldOfShape<K, F>;
|
|
106
|
+
};
|
|
107
|
+
}[S];
|
|
108
|
+
/** A field paired with its shape: the one place a field's union is branched on by shape. */
|
|
109
|
+
export declare function shaped<F extends TypedSettings>(field: F): ShapedField<F>;
|
|
110
|
+
/**
|
|
111
|
+
* A type together with its shape, for a translator that knows a field's type but not its settings,
|
|
112
|
+
* as the CSV translator does.
|
|
113
|
+
*/
|
|
114
|
+
export type ShapedType<S extends FieldShape = FieldShape> = {
|
|
115
|
+
[K in S]: {
|
|
116
|
+
readonly shape: K;
|
|
117
|
+
readonly type: FieldTypeOfShape<K>;
|
|
118
|
+
};
|
|
119
|
+
}[S];
|
|
120
|
+
/** A type paired with its shape. */
|
|
121
|
+
export declare function shapedType(type: FieldType): ShapedType;
|
|
122
|
+
/** How a field of each shape reads a held value, using its type and settings. */
|
|
123
|
+
export interface FieldReading<S extends FieldShape> {
|
|
124
|
+
/**
|
|
125
|
+
* Lenient: what a field holds, read as the field gives it meaning. Keeps answers to options
|
|
126
|
+
* since removed, and parts saved under an older, looser rule, so tightening a rule never hides
|
|
127
|
+
* what members hold. Puts a list's answers in the field's order, then the removed ones.
|
|
128
|
+
*/
|
|
129
|
+
held(field: FieldOfShape<S>, value: ShapeValue[S]): ShapeValue[S] | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* What a form can show of a held value. A save that writes what the form shows drops an answer
|
|
132
|
+
* the form can't show.
|
|
133
|
+
*/
|
|
134
|
+
editable(field: FieldOfShape<S>, held: ShapeValue[S]): ShapeValue[S] | undefined;
|
|
135
|
+
}
|
|
136
|
+
export declare const FIELD_READING: {
|
|
137
|
+
readonly [S in FieldShape]: FieldReading<S>;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* What a held raw value reads as for its field: its structure checked, then read as the field
|
|
141
|
+
* gives it meaning. Undefined when the value isn't the field's structure.
|
|
142
|
+
*/
|
|
143
|
+
export declare function heldValue<S extends FieldShape>({ shape, field }: ShapedField<TypedSettings, S>, raw: unknown): ShapeValue[S] | undefined;
|
|
144
|
+
/** What a form can show of a held raw value, or undefined when it shows nothing. */
|
|
145
|
+
export declare function editableValue<S extends FieldShape>(of: ShapedField<TypedSettings, S>, raw: unknown): ShapeValue[S] | undefined;
|
|
146
|
+
/** A leaf's value as text gives it, or undefined for blank text, which holds nothing. */
|
|
147
|
+
export declare const leafFromText: (leaf: Leaf, text: string) => AnyLeafValue | undefined;
|
|
148
|
+
/**
|
|
149
|
+
* What a value given as text holds, such as a form's inputs or a row's cells: each leaf read from
|
|
150
|
+
* its text, then parsed as a value of its type, which drops blank text. Undefined when it holds
|
|
151
|
+
* nothing.
|
|
152
|
+
*/
|
|
153
|
+
export declare function valueFromText<S extends FieldShape>({ shape, type }: ShapedType<S>, raw: unknown): ShapeValue[S] | undefined;
|
|
154
|
+
/** A value of each shape as a form's inputs hold it: each leaf as its text. */
|
|
155
|
+
export interface ShapeText {
|
|
156
|
+
scalar: string;
|
|
157
|
+
record: {
|
|
158
|
+
readonly [part: string]: string;
|
|
159
|
+
};
|
|
160
|
+
set: string[];
|
|
161
|
+
}
|
|
162
|
+
/** A value as a form's inputs hold it, which `valueFromText` reads back as the same value. */
|
|
163
|
+
export declare function textOfValue<S extends FieldShape>(shape: S, value: ShapeValue[S]): ShapeText[S];
|
|
164
|
+
/** What a field holds, each leaf as its text, as a field shown but not edited draws it. */
|
|
165
|
+
export declare function heldTextOf<S extends FieldShape>(of: ShapedField<TypedSettings, S>, held: unknown): ShapeText[S] | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* What a form's inputs start from for a held raw value: what the form can show of it, each leaf as
|
|
168
|
+
* its text, or undefined when it shows nothing.
|
|
169
|
+
*/
|
|
170
|
+
export declare function formTextOf<S extends FieldShape>(of: ShapedField<TypedSettings, S>, held: unknown): ShapeText[S] | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* What a form's inputs show, read as the field reads a value: each leaf from its text, blank text
|
|
173
|
+
* holding nothing, and only what the form can show. Undefined when they show nothing.
|
|
174
|
+
*/
|
|
175
|
+
export declare function formShows<S extends FieldShape>(of: ShapedField<TypedSettings, S>, inputs: unknown): ShapeValue[S] | undefined;
|
|
176
|
+
/**
|
|
177
|
+
* The write that turns what a field holds into what a form's inputs show: `null` when the inputs
|
|
178
|
+
* show nothing of a replacing shape, and undefined when they show what the field holds. The held
|
|
179
|
+
* value is read as the field reads it first, so a part the form doesn't draw is never written, and
|
|
180
|
+
* an answer the form can't show, such as one to an option the field no longer offers, is cleared
|
|
181
|
+
* by the write.
|
|
182
|
+
*/
|
|
183
|
+
export declare function formWrite<S extends FieldShape>(of: ShapedField<TypedSettings, S>, inputs: unknown, held: unknown): ShapeWrite[S] | null | undefined;
|
|
184
|
+
export {};
|
|
185
|
+
//# sourceMappingURL=shapes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes.ts"],"names":[],"mappings":"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"}
|
package/build/shapes.js
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rules every field of a shape follows, whatever its type and settings, and the rules a field
|
|
3
|
+
* adds from its settings when a held value is read.
|
|
4
|
+
*
|
|
5
|
+
* A shape's rules look only at structure: they know a list is a list of strings, but not which
|
|
6
|
+
* strings a field offers. They also say what a write does to a held value, which is part of the
|
|
7
|
+
* API's contract rather than storage's choice: a client works out a write against the value its
|
|
8
|
+
* form loaded, and Ghost applies it to whatever is stored when it lands, which another writer may
|
|
9
|
+
* have changed in between. The two only agree because both read the rules here.
|
|
10
|
+
*
|
|
11
|
+
* Each table is keyed by shape, so a shape added to the catalog fails to compile here until it has
|
|
12
|
+
* an entry. Each translator of a shape into another domain's terms, such as the storage translator
|
|
13
|
+
* into rows or the CSV translator into cells, keeps its own table of the same form, which `shaped`
|
|
14
|
+
* lets it index without a cast.
|
|
15
|
+
*
|
|
16
|
+
* Zod-free, like `./structure`, so Portal can use it. The strict rule a write must meet is built
|
|
17
|
+
* from zod and lives in `./index` as `accept`.
|
|
18
|
+
*/
|
|
19
|
+
import { FIELD_STRUCTURES, editableAnswers, isRecordValue, matchField, matchShape, keysOf, } from './structure.js';
|
|
20
|
+
/**
|
|
21
|
+
* A leaf's value, or undefined for text of nothing but spaces, which holds nothing: a form's input
|
|
22
|
+
* or a CSV cell left blank says no more than one left out.
|
|
23
|
+
*/
|
|
24
|
+
const filled = (raw) => typeof raw === 'string' && raw.trim() === '' ? undefined : raw;
|
|
25
|
+
/** A value JSON carries as a string, without its padding, which every such leaf's rule trims too. */
|
|
26
|
+
const stringRules = {
|
|
27
|
+
kind: 'string',
|
|
28
|
+
read: (raw) => (typeof raw === 'string' ? filled(raw.trim()) : undefined),
|
|
29
|
+
fromText: (text) => text.trim(),
|
|
30
|
+
};
|
|
31
|
+
export const LEAVES = {
|
|
32
|
+
text: stringRules,
|
|
33
|
+
choice: stringRules,
|
|
34
|
+
};
|
|
35
|
+
/** A raw value read as its leaf's kind of value, typed by the leaf. */
|
|
36
|
+
const readLeaf = (leaf, raw) => LEAVES[leaf.leaf].read(raw);
|
|
37
|
+
/** A raw value read as a value of any kind of leaf, or undefined when no kind reads it. */
|
|
38
|
+
function readAnyLeaf(raw) {
|
|
39
|
+
for (const kind of keysOf(LEAVES)) {
|
|
40
|
+
const value = LEAVES[kind].read(raw);
|
|
41
|
+
if (value !== undefined) {
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const isTextList = (raw) => Array.isArray(raw) && raw.every((entry) => typeof entry === 'string');
|
|
48
|
+
/**
|
|
49
|
+
* The diff of a shape whose write replaces what is held, from how it compares two values that both
|
|
50
|
+
* hold something: a value going is the write `null`, and a value arriving is the whole value.
|
|
51
|
+
*/
|
|
52
|
+
const diffing = (change) => (held, next) => {
|
|
53
|
+
if (next === undefined) {
|
|
54
|
+
return held === undefined ? undefined : null;
|
|
55
|
+
}
|
|
56
|
+
return held === undefined ? next : change(held, next);
|
|
57
|
+
};
|
|
58
|
+
/** A record's parts that hold something, or undefined when none does: cleared parts are left out. */
|
|
59
|
+
const someParts = (parts) => {
|
|
60
|
+
const held = {};
|
|
61
|
+
for (const part of keysOf(parts)) {
|
|
62
|
+
const value = filled(parts[part] ?? undefined);
|
|
63
|
+
if (value !== undefined) {
|
|
64
|
+
held[part] = value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return keysOf(held).length > 0 ? held : undefined;
|
|
68
|
+
};
|
|
69
|
+
/** A set's options, or undefined when it has none. */
|
|
70
|
+
const someOptions = (options) => options.length > 0 ? options : undefined;
|
|
71
|
+
const scalar = {
|
|
72
|
+
// Any leaf's value rather than only its own leaf's, so text that holds no value of the leaf is
|
|
73
|
+
// kept for the leaf's rule to refuse; its type decides which kind it must be.
|
|
74
|
+
parse: (_type, raw) => readAnyLeaf(raw),
|
|
75
|
+
same: (a, b) => a === b,
|
|
76
|
+
apply: (_held, write) => write,
|
|
77
|
+
diff: diffing((held, next) => (held === next ? undefined : next)),
|
|
78
|
+
};
|
|
79
|
+
const record = {
|
|
80
|
+
// Only the parts the type declares, each read as its leaf's kind of value.
|
|
81
|
+
parse: (type, raw) => {
|
|
82
|
+
if (!isRecordValue(raw)) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const parts = FIELD_STRUCTURES[type].parts;
|
|
86
|
+
const value = {};
|
|
87
|
+
for (const part of keysOf(parts)) {
|
|
88
|
+
const held = readLeaf(parts[part], raw[part]);
|
|
89
|
+
if (held !== undefined) {
|
|
90
|
+
value[part] = held;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return keysOf(value).length > 0 ? value : undefined;
|
|
94
|
+
},
|
|
95
|
+
same: (a, b) => record.diff(a, b) === undefined,
|
|
96
|
+
// Merged, as JSON Merge Patch merges objects: a part the write names is set, `null` clears it,
|
|
97
|
+
// and a part it leaves out is left alone, so writes to different parts don't overwrite each
|
|
98
|
+
// other.
|
|
99
|
+
apply: (held, write) => {
|
|
100
|
+
const merged = { ...held };
|
|
101
|
+
for (const part of keysOf(write)) {
|
|
102
|
+
const value = write[part];
|
|
103
|
+
if (value !== undefined) {
|
|
104
|
+
merged[part] = value;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return someParts(merged);
|
|
108
|
+
},
|
|
109
|
+
// Never `null`, even when nothing is left: a merged write names only the parts its writer saw, so
|
|
110
|
+
// a writer clearing the city doesn't also clear a country someone else has just set.
|
|
111
|
+
diff: (held, next) => {
|
|
112
|
+
if (held === undefined) {
|
|
113
|
+
return next;
|
|
114
|
+
}
|
|
115
|
+
const now = next ?? {};
|
|
116
|
+
const write = {};
|
|
117
|
+
for (const part of keysOf({ ...held, ...now })) {
|
|
118
|
+
if (held[part] !== now[part]) {
|
|
119
|
+
write[part] = now[part] ?? null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return keysOf(write).length > 0 ? write : undefined;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
const set = {
|
|
126
|
+
parse: (_type, raw) => (isTextList(raw) ? someOptions(raw) : undefined),
|
|
127
|
+
same: (a, b) => {
|
|
128
|
+
const options = new Set(b);
|
|
129
|
+
return new Set(a).size === options.size && a.every((option) => options.has(option));
|
|
130
|
+
},
|
|
131
|
+
// Replaced, as JSON Merge Patch replaces arrays: a write states the whole answer.
|
|
132
|
+
apply: (_held, write) => write,
|
|
133
|
+
diff: diffing((held, next) => (set.same(held, next) ? undefined : next)),
|
|
134
|
+
};
|
|
135
|
+
/** Each shape's rules. A shape added to the catalog without rules doesn't compile. */
|
|
136
|
+
export const SHAPES = { scalar, record, set };
|
|
137
|
+
/** A field paired with its shape: the one place a field's union is branched on by shape. */
|
|
138
|
+
export function shaped(field) {
|
|
139
|
+
return matchField(field, {
|
|
140
|
+
scalar: (of) => ({ shape: 'scalar', field: of }),
|
|
141
|
+
record: (of) => ({ shape: 'record', field: of }),
|
|
142
|
+
set: (of) => ({ shape: 'set', field: of }),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/** A type paired with its shape. */
|
|
146
|
+
export function shapedType(type) {
|
|
147
|
+
return matchShape(type, {
|
|
148
|
+
scalar: (_structure, of) => ({ shape: 'scalar', type: of }),
|
|
149
|
+
record: (_structure, of) => ({ shape: 'record', type: of }),
|
|
150
|
+
set: (_structure, of) => ({ shape: 'set', type: of }),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/** A form shows everything the field holds: true of every shape but a set. */
|
|
154
|
+
const showsWhatItHolds = () => ({
|
|
155
|
+
editable: (_field, held) => held,
|
|
156
|
+
});
|
|
157
|
+
export const FIELD_READING = {
|
|
158
|
+
scalar: { held: (_field, value) => value, ...showsWhatItHolds() },
|
|
159
|
+
// Parsing already kept only the parts the type declares, which are all a client can draw.
|
|
160
|
+
record: { held: (_field, value) => value, ...showsWhatItHolds() },
|
|
161
|
+
set: {
|
|
162
|
+
held: ({ settings }, value) => {
|
|
163
|
+
const rank = (text) => {
|
|
164
|
+
const index = settings.options.indexOf(text);
|
|
165
|
+
return index === -1 ? settings.options.length : index;
|
|
166
|
+
};
|
|
167
|
+
return [...value].sort((a, b) => rank(a) - rank(b) || (a < b ? -1 : a > b ? 1 : 0));
|
|
168
|
+
},
|
|
169
|
+
editable: ({ settings }, held) => someOptions(editableAnswers(settings, held)),
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* What a held raw value reads as for its field: its structure checked, then read as the field
|
|
174
|
+
* gives it meaning. Undefined when the value isn't the field's structure.
|
|
175
|
+
*/
|
|
176
|
+
export function heldValue({ shape, field }, raw) {
|
|
177
|
+
const value = SHAPES[shape].parse(field.type, raw);
|
|
178
|
+
return value === undefined ? undefined : FIELD_READING[shape].held(field, value);
|
|
179
|
+
}
|
|
180
|
+
/** What a form can show of a held raw value, or undefined when it shows nothing. */
|
|
181
|
+
export function editableValue(of, raw) {
|
|
182
|
+
const held = heldValue(of, raw);
|
|
183
|
+
return held === undefined ? undefined : FIELD_READING[of.shape].editable(of.field, held);
|
|
184
|
+
}
|
|
185
|
+
/** A leaf's value as text gives it, or undefined for blank text, which holds nothing. */
|
|
186
|
+
export const leafFromText = (leaf, text) => {
|
|
187
|
+
const value = filled(text);
|
|
188
|
+
return value === undefined ? undefined : LEAVES[leaf.leaf].fromText(text);
|
|
189
|
+
};
|
|
190
|
+
/** A leaf read from its text, where it is text; blank text is kept, for parsing to drop. */
|
|
191
|
+
const leafOf = (leaf, raw) => typeof raw === 'string' ? (leafFromText(leaf, raw) ?? raw) : raw;
|
|
192
|
+
const SHAPE_TEXT = {
|
|
193
|
+
scalar: { fromText: (type, raw) => leafOf(FIELD_STRUCTURES[type].leaf, raw) },
|
|
194
|
+
record: {
|
|
195
|
+
fromText: (type, raw) => {
|
|
196
|
+
if (!isRecordValue(raw)) {
|
|
197
|
+
return raw;
|
|
198
|
+
}
|
|
199
|
+
const leaves = FIELD_STRUCTURES[type].parts;
|
|
200
|
+
return Object.fromEntries(Object.entries(raw).map(([part, held]) => {
|
|
201
|
+
const leaf = Object.prototype.hasOwnProperty.call(leaves, part)
|
|
202
|
+
? leaves[part]
|
|
203
|
+
: undefined;
|
|
204
|
+
return [part, leaf ? leafOf(leaf, held) : held];
|
|
205
|
+
}));
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
set: { fromText: (_type, raw) => raw },
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* What a value given as text holds, such as a form's inputs or a row's cells: each leaf read from
|
|
212
|
+
* its text, then parsed as a value of its type, which drops blank text. Undefined when it holds
|
|
213
|
+
* nothing.
|
|
214
|
+
*/
|
|
215
|
+
export function valueFromText({ shape, type }, raw) {
|
|
216
|
+
return SHAPES[shape].parse(type, SHAPE_TEXT[shape].fromText(type, raw));
|
|
217
|
+
}
|
|
218
|
+
/** How a value of each shape is held by a form's inputs, each leaf as `String` writes it. */
|
|
219
|
+
const VALUE_TEXT = {
|
|
220
|
+
scalar: (value) => String(value),
|
|
221
|
+
record: (value) => Object.fromEntries(keysOf(value).flatMap((part) => {
|
|
222
|
+
const held = value[part];
|
|
223
|
+
return held === undefined ? [] : [[part, String(held)]];
|
|
224
|
+
})),
|
|
225
|
+
set: (value) => value,
|
|
226
|
+
};
|
|
227
|
+
/** A value as a form's inputs hold it, which `valueFromText` reads back as the same value. */
|
|
228
|
+
export function textOfValue(shape, value) {
|
|
229
|
+
return VALUE_TEXT[shape](value);
|
|
230
|
+
}
|
|
231
|
+
/** What a field holds, each leaf as its text, as a field shown but not edited draws it. */
|
|
232
|
+
export function heldTextOf(of, held) {
|
|
233
|
+
const value = heldValue(of, held);
|
|
234
|
+
return value === undefined ? undefined : textOfValue(of.shape, value);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* What a form's inputs start from for a held raw value: what the form can show of it, each leaf as
|
|
238
|
+
* its text, or undefined when it shows nothing.
|
|
239
|
+
*/
|
|
240
|
+
export function formTextOf(of, held) {
|
|
241
|
+
const value = editableValue(of, held);
|
|
242
|
+
return value === undefined ? undefined : textOfValue(of.shape, value);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* What a form's inputs show, read as the field reads a value: each leaf from its text, blank text
|
|
246
|
+
* holding nothing, and only what the form can show. Undefined when they show nothing.
|
|
247
|
+
*/
|
|
248
|
+
export function formShows(of, inputs) {
|
|
249
|
+
const typed = valueFromText({ shape: of.shape, type: of.field.type }, inputs);
|
|
250
|
+
return typed === undefined ? undefined : editableValue(of, typed);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* The write that turns what a field holds into what a form's inputs show: `null` when the inputs
|
|
254
|
+
* show nothing of a replacing shape, and undefined when they show what the field holds. The held
|
|
255
|
+
* value is read as the field reads it first, so a part the form doesn't draw is never written, and
|
|
256
|
+
* an answer the form can't show, such as one to an option the field no longer offers, is cleared
|
|
257
|
+
* by the write.
|
|
258
|
+
*/
|
|
259
|
+
export function formWrite(of, inputs, held) {
|
|
260
|
+
return SHAPES[of.shape].diff(heldValue(of, held), formShows(of, inputs));
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=shapes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapes.js","sourceRoot":"","sources":["../src/shapes.ts"],"names":[],"mappings":"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"}
|