@tryghost/metafield-types 0.2.0 → 0.3.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 CHANGED
@@ -1,5 +1,53 @@
1
1
  # @tryghost/metafield-types
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Changed the catalog to describe each field type as a composition of building blocks, and to derive each type's rule from them.
8
+
9
+ - `FIELD_STRUCTURES` replaces `FIELD_PARTS`. A type is one leaf, `{ shape: 'scalar', leaf }`, or a record of named leaves, `{ shape: 'record', parts }`.
10
+ - A leaf is text of a size, `text(size)` with `TEXT_SIZES`, or a choice from a list, `choice(from)` with `LIST_SOURCES`. `country` is the choice from the list of countries.
11
+ - A part's type is now its leaf, so `PART_TYPE_IDS`, `PartType` and `partTypesOf` are removed. An address's postal code is `text('code')`, its country is `country`, and its other parts are `text('line')`.
12
+ - `FIELD_KINDS` and `FieldKind` are removed. A scalar's leaf says what it holds.
13
+ - `matchShape(type, { scalar, record })` and `matchLeaf(leaf, { text, choice })` call the handler for a type's shape or a leaf's kind, so a caller has to say what it does with every one. `matchShape` throws for a type the package doesn't know, so check a type from the wire with `isFieldType` first.
14
+ - `isRecordValue` tells whether a value is laid out as a record of parts.
15
+ - `StructureOf`, `ShapeOf`, `FieldTypeOfShape` and `PartsOf` name what a type is composed of, and `ValueOf` names the value it holds.
16
+ - `partsOf` names a record's parts as plain strings. Read one type's parts by name from `FIELD_STRUCTURES[type].parts`, whose keys are typed.
17
+ - `valueSchemaFor(field)` is the rule a value of one field must satisfy, derived from its type's composition. It replaces `FIELD_TYPES`, `FieldTypeDefinition`, `PART_TYPES` and `AddressValue`, which are removed. `FieldValue` and `Address` stay.
18
+
19
+ - Added helpers for editing a list field's answers.
20
+
21
+ - `inOptionOrder(settings, held)` is the answers among `held` that a list offers, in its order, and `editableAnswers(settings, held)` is what a form editing a list's answers starts from: none while a field taking one holds several.
22
+
23
+ - Added the list field type, whose field offers options of its own and takes one or several of them.
24
+
25
+ - `list` is `{ shape: 'set' }`: a value is the text of each option picked, as `string[]`, even when the field takes one. `matchShape` handlers take a `set` branch.
26
+ - A field now carries `settings` beside its `type`. `SettingsOf<T>` is what a type is set up with: `SetSettings` (`options`, in the order shown, and `multiple`) for a list, and nothing for every other type, so a field of another type has no settings. `TypedSettings` pairs a type with its settings. `withTypedSettings(base, settings)` builds what a field holds beside its type with that pair, a variant per shape, from how each shape's settings are held: `WRITTEN_SETTINGS` checks them against the rules, and `READ_SETTINGS` reads them back by `SetSettingsShape` alone, so a rule tightened later never hides a field set up under the old one. `TypedSettingsInputSchema` and `TypedSettingsSchema` are the pair on its own, and `MetafieldDefinitionSchema` is built the same way. `typesOfShape(shape)` lists the types of a shape.
27
+ - `MetafieldDefinitionSchema` reads `settings`, and `MetafieldDefinition` is typed by them, so a list definition always has its options.
28
+ - `valueSchemaFor(field)` takes the field's type and settings. A list's rule accepts only the options its field offers, and at most one when it takes one.
29
+ - `matchField(field, handlers)` calls a handler for the field's shape with the field narrowed, settings included.
30
+ - `optionText` is how an option's text is matched: trimmed, with accents encoded one way. `MIN_OPTIONS`, `MAX_OPTIONS` and `OPTION_SEPARATOR` are a list's limits and the character joining options in one CSV cell, which no option may contain.
31
+
32
+ - Added `SHAPE_SETTINGS`, each field shape's settings in one place: the shape a read is checked against, the rules a write is checked against on top of that shape, and the defaults a field starts with. `WRITTEN_SETTINGS` and `READ_SETTINGS` are now taken from it, and `SetSettingsSchema` is now built on `SetSettingsShape`.
33
+
34
+ - Added `refusedProperty(path)`, which names where a refusal points within what was sent by its path, with parts and positions joined by dots, such as `settings.options.2` for a field's third option. Ghost reports a custom field refusal's `property` this way, and a form can file the problems it finds under the same keys.
35
+
36
+ - Added the shape of a field definition as the Admin and Members APIs return it.
37
+
38
+ - `MetafieldDefinitionSchema` reads a definition (namespace, key, name, type, status, member access and dates) and `MetafieldDefinition` is the type it produces. Ghost writes every definition through it.
39
+ - `FIELD_STATUSES`, `FieldStatusSchema`, `FIELD_STATUS` and `FieldStatus` name whether a field is active or archived.
40
+
41
+ ### Patch Changes
42
+
43
+ - Pointed the README at a guide for Ghost contributors adding a field type.
44
+
45
+ - Updated dependencies
46
+
47
+ - Updated dependencies
48
+
49
+ - Updated dependencies
50
+
3
51
  ## 0.2.0
4
52
 
5
53
  ### Minor Changes
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # @tryghost/metafield-types
2
2
 
3
- The types of member custom field Ghost supports: which types exist, which parts a
4
- type is made of, the type of value each part holds, and how a value of each type is
5
- validated. Ghost, its Admin and Portal use it, and so can an integration that offers
6
- inputs for a site's custom fields, such as the Ghost Zapier integration.
3
+ The types of member custom field Ghost supports: which types exist, what each type
4
+ is composed of, and how a value of each type is validated. Ghost, its Admin and Portal
5
+ use it, and so can an integration that offers inputs for a site's custom fields, such
6
+ as the Ghost Zapier integration.
7
7
 
8
8
  ```bash
9
9
  npm install @tryghost/metafield-types
@@ -11,31 +11,37 @@ npm install @tryghost/metafield-types
11
11
 
12
12
  ## Entry points
13
13
 
14
- - `@tryghost/metafield-types/structure`: the type ids, each type's parts and the
15
- type of value each part holds. It depends on nothing.
16
- - `@tryghost/metafield-types/countries`: the two-letter country codes a country
17
- part accepts. It depends on nothing.
14
+ - `@tryghost/metafield-types/structure`: the type ids and what each type is composed
15
+ of. A type is one leaf, a record of named leaves, or a set of options its field
16
+ offers, and a leaf is text of a size or a choice from a list, such as a country. A
17
+ field of a set type is set up with its options, which a field carries as its
18
+ `settings`. It depends on nothing.
19
+ - `@tryghost/metafield-types/countries`: the two-letter country codes the list of
20
+ countries offers. It depends on nothing.
18
21
  - `@tryghost/metafield-types/identity`: how a field is named everywhere: its
19
22
  namespace, its key, the parts of a record value, and the identity they make
20
23
  together (`custom.shipping_address.country`). Each is a type that only its
21
24
  check produces. It loads `zod/mini`, a small fraction of zod's size, so a
22
25
  browser app can check identities without paying for the rest.
23
- - `@tryghost/metafield-types`: the structure above, plus the rules that validate
24
- a value of each type. These are built on [zod](https://zod.dev), and only this
25
- entry point loads all of it, so an integration that only draws inputs can use
26
- `./structure` and `./countries` without loading zod at all.
26
+ - `@tryghost/metafield-types`: the structure above, plus `valueSchemaFor(field)`,
27
+ the rule a value of a field must satisfy given its type and settings. The rules are built on
28
+ [zod](https://zod.dev), and only this entry point loads all of it, so an
29
+ integration that only draws inputs can use `./structure` and `./countries`
30
+ without loading zod at all.
27
31
 
28
32
  ## Compatibility
29
33
 
30
34
  An integration using this package talks to sites on many Ghost versions, so a type
31
- never changes once it has shipped: it keeps its parts and the type of value each
32
- holds. New structure arrives as a new type. An integration should skip a type it
33
- doesn't recognise, which is what happens when a site is on a newer Ghost than the
34
- package the integration was built with.
35
+ never changes once it has shipped. It keeps what it is composed of: its shape, its
36
+ leaves, and the names of any parts. New structure arrives as a new type. An integration
37
+ should skip a type it doesn't recognise, which is what happens when a site is on a newer
38
+ Ghost than the package the integration was built with.
35
39
 
36
40
  ## Develop
37
41
 
38
- This is a workspace package in the Ghost monorepo. From the repo root:
42
+ This is a workspace package in the Ghost monorepo. Adding a field type to Ghost is
43
+ covered in [`docs/adding-a-field-type.md`](docs/adding-a-field-type.md). From the repo
44
+ root:
39
45
 
40
46
  ```bash
41
47
  pnpm --filter @tryghost/metafield-types build # compile to build/ with tsc (ESM)
@@ -52,9 +58,9 @@ imports in `src/` must carry an explicit extension; write the real `.ts` one —
52
58
  `import {x} from './x.ts'` — and `tsc` rewrites it to `.js` on emit
53
59
  (`rewriteRelativeImportExtensions`).
54
60
 
55
- `./structure` is the half of the catalog a renderer needs — which parts a field type
56
- has, and what each holds — and it stands apart from `./index` so that importing it
57
- costs a bundle almost nothing. The rules in `./index` are built on zod, some
61
+ `./structure` is the half of the catalog a renderer needs, what each field type is
62
+ composed of, and it stands apart from `./index` so that importing it costs a bundle
63
+ almost nothing. The rules in `./index` are built on zod, some
58
64
  seventeen kilobytes gzipped that a renderer never runs. Portal imports `./structure`
59
65
  and loads on every page view of every themed site, so the difference reaches every
60
66
  visitor of every Ghost site.
package/build/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- import { type FieldType } from './structure.js';
3
- export { FIELD_KINDS, FIELD_PARTS, FIELD_TYPE_IDS, PART_TYPE_IDS, partTypesOf, partsOf, type FieldKind, type FieldType, type PartsOf, type PartType, } from './structure.js';
2
+ import { type FieldType, type FieldShape, type TypedSettings, type ValueOf } from './structure.js';
3
+ export { FIELD_STRUCTURES, FIELD_TYPE_IDS, LIST_SOURCES, MAX_OPTIONS, MIN_OPTIONS, OPTION_SEPARATOR, TEXT_SIZES, choice, country, editableAnswers, inOptionOrder, isFieldType, isRecordValue, matchField, matchLeaf, matchShape, partsOf, text, type ChoiceLeaf, type FieldHandlers, type FieldOfShape, type FieldShape, type FieldStructure, type FieldType, type FieldTypeOfShape, type Leaf, type LeafHandlers, type LeafKind, type ListSource, type PartsOf, type RecordStructure, type ScalarStructure, type SetSettings, type SetStructure, type SettingsOf, type ShapeHandlers, type ShapeOf, type StructureOf, type TextLeaf, type TextSize, type TypedSettings, type ValueOf, } from './structure.js';
4
4
  /**
5
5
  * The shared catalog of member metafield types.
6
6
  *
@@ -10,10 +10,9 @@ export { FIELD_KINDS, FIELD_PARTS, FIELD_TYPE_IDS, PART_TYPE_IDS, partTypesOf, p
10
10
  * last statement lives here and nowhere else, so that Ghost core, which enforces it, and
11
11
  * admin, which gives instant feedback against it, cannot disagree about what is valid.
12
12
  *
13
- * A type is one of two things. Most are a value in their own right, declared as the
14
- * schema that value must satisfy. An address is a *record*: a set of named parts, each a
15
- * value in the same sense, from which the whole type's schema is derived. Nothing stops a
16
- * part being a record itself.
13
+ * A type is composed of leaves, each one value with its own rule. Most types are a single
14
+ * leaf. An address is a *record*: a set of named parts, each a leaf, from which the whole
15
+ * type's rule is derived. A part is always a leaf, never a record itself.
17
16
  *
18
17
  * ## What a write may say
19
18
  *
@@ -51,12 +50,13 @@ export { FIELD_KINDS, FIELD_PARTS, FIELD_TYPE_IDS, PART_TYPE_IDS, partTypesOf, p
51
50
  * answer and a disagreement between them is a file that silently stops round-tripping.
52
51
  *
53
52
  * The line is whether more than one renderer must agree on a string, not presentation
54
- * against validity — the sentences above are presentation. Admin is the only renderer
55
- * today, so a part's label lives there, held against this file by a type. A Portal
56
- * collection form, which cannot reach admin's packages, moves the labels here.
53
+ * against validity — the sentences above are presentation. Admin and Portal each label a
54
+ * record's parts in their own words, and each is held against the catalog by a type, so a
55
+ * part added there fails to compile in both until it has a label.
57
56
  */
58
57
  export declare const FieldTypeSchema: z.ZodEnum<{
59
58
  address: "address";
59
+ list: "list";
60
60
  long_text: "long_text";
61
61
  short_text: "short_text";
62
62
  }>;
@@ -81,6 +81,267 @@ export declare const MEMBER_ACCESS: {
81
81
  readonly read: 'read';
82
82
  readonly write: 'write';
83
83
  };
84
+ /**
85
+ * Whether a field is in use. An archived field keeps its definition and the values members
86
+ * hold for it, so it can be restored, but it takes no new values and members no longer see it.
87
+ */
88
+ export declare const FIELD_STATUSES: readonly ['active', 'archived'];
89
+ export type FieldStatus = (typeof FIELD_STATUSES)[number];
90
+ export declare const FieldStatusSchema: z.ZodEnum<{
91
+ active: "active";
92
+ archived: "archived";
93
+ }>;
94
+ export declare const FIELD_STATUS: {
95
+ readonly active: 'active';
96
+ readonly archived: 'archived';
97
+ };
98
+ /**
99
+ * A set field's settings as stored or sent back: their shape alone, which every read checks. A
100
+ * write checks the rules `SetSettingsSchema` layers on top, so a rule tightened later never hides
101
+ * a field set up under the old one, the way a value's rule never hides what a member already holds.
102
+ */
103
+ export declare const SetSettingsShape: z.ZodObject<{
104
+ options: z.ZodArray<z.ZodString>;
105
+ multiple: z.ZodBoolean;
106
+ }, z.core.$strip>;
107
+ /**
108
+ * What a set field is set up with: its shape, with each option's text tidied and the rules a write
109
+ * must meet on top. Options are a set as well, so the same text can't be offered twice; they are
110
+ * listed in the order they are shown.
111
+ */
112
+ export declare const SetSettingsSchema: z.ZodPipe<z.ZodObject<{
113
+ options: z.ZodArray<z.ZodString>;
114
+ multiple: z.ZodBoolean;
115
+ }, z.core.$strip>, z.ZodTransform<{
116
+ options: string[];
117
+ multiple: boolean;
118
+ }, {
119
+ options: string[];
120
+ multiple: boolean;
121
+ }>>;
122
+ /**
123
+ * What a field holds beside its type, `base`, with its type and the settings that type's shape
124
+ * takes, held as `settings` says for each shape: a set's options, and nothing for any other shape.
125
+ * One variant per shape, so a field's settings are always read against its type. Writes give the
126
+ * rules, reads the shape alone, and Ghost's table its column.
127
+ */
128
+ export declare const withTypedSettings: <Base extends z.ZodRawShape, ForScalar extends z.ZodType, ForRecord extends z.ZodType, ForSet extends z.ZodType>(base: Base, settings: {
129
+ scalar: ForScalar;
130
+ record: ForRecord;
131
+ set: ForSet;
132
+ } & { [S in FieldShape]: z.ZodType; }) => z.ZodDiscriminatedUnion<[z.ZodObject<Base & {
133
+ type: z.ZodEnum<{
134
+ long_text: "long_text";
135
+ short_text: "short_text";
136
+ }>;
137
+ settings: ForScalar & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
138
+ } extends infer T ? { -readonly [P in keyof T]: T[P]; } : never, z.core.$strip>, z.ZodObject<Base & {
139
+ type: z.ZodEnum<{
140
+ address: "address";
141
+ }>;
142
+ settings: ForRecord & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
143
+ } extends infer T_1 ? { -readonly [P in keyof T_1]: T_1[P]; } : never, z.core.$strip>, z.ZodObject<Base & {
144
+ type: z.ZodEnum<{
145
+ list: "list";
146
+ }>;
147
+ settings: ForSet & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
148
+ } extends infer T_2 ? { -readonly [P in keyof T_2]: T_2[P]; } : never, z.core.$strip>], "type">;
149
+ /**
150
+ * Each shape's settings in one place: a set's options and whether a member picks several, and
151
+ * nothing for any other shape. A list's defaults have no options, which a list's write rules
152
+ * refuse, so an edit of a list read with its defaults always writes the settings it is given.
153
+ * Keyed by shape, so a shape added to the catalog fails to compile until it has an entry.
154
+ */
155
+ export declare const SHAPE_SETTINGS: {
156
+ scalar: {
157
+ written: z.ZodOptional<z.ZodUndefined>;
158
+ read: z.ZodOptional<z.ZodUndefined>;
159
+ defaults: undefined;
160
+ };
161
+ record: {
162
+ written: z.ZodOptional<z.ZodUndefined>;
163
+ read: z.ZodOptional<z.ZodUndefined>;
164
+ defaults: undefined;
165
+ };
166
+ set: {
167
+ written: z.ZodPipe<z.ZodObject<{
168
+ options: z.ZodArray<z.ZodString>;
169
+ multiple: z.ZodBoolean;
170
+ }, z.core.$strip>, z.ZodTransform<{
171
+ options: string[];
172
+ multiple: boolean;
173
+ }, {
174
+ options: string[];
175
+ multiple: boolean;
176
+ }>>;
177
+ read: z.ZodObject<{
178
+ options: z.ZodArray<z.ZodString>;
179
+ multiple: z.ZodBoolean;
180
+ }, z.core.$strip>;
181
+ defaults: {
182
+ options: never[];
183
+ multiple: false;
184
+ };
185
+ };
186
+ };
187
+ /** Each shape's settings as a write states them, checked against the rules. */
188
+ export declare const WRITTEN_SETTINGS: {
189
+ scalar: z.ZodOptional<z.ZodUndefined>;
190
+ record: z.ZodOptional<z.ZodUndefined>;
191
+ set: z.ZodPipe<z.ZodObject<{
192
+ options: z.ZodArray<z.ZodString>;
193
+ multiple: z.ZodBoolean;
194
+ }, z.core.$strip>, z.ZodTransform<{
195
+ options: string[];
196
+ multiple: boolean;
197
+ }, {
198
+ options: string[];
199
+ multiple: boolean;
200
+ }>>;
201
+ };
202
+ /** Each shape's settings as they are read back, checked for their shape alone. */
203
+ export declare const READ_SETTINGS: {
204
+ scalar: z.ZodOptional<z.ZodUndefined>;
205
+ record: z.ZodOptional<z.ZodUndefined>;
206
+ set: z.ZodObject<{
207
+ options: z.ZodArray<z.ZodString>;
208
+ multiple: z.ZodBoolean;
209
+ }, z.core.$strip>;
210
+ };
211
+ /**
212
+ * Where a refusal points within what was sent: the path to the refused value, with its parts and
213
+ * positions joined by dots, such as `settings.options.2` for a field's third option. Ghost names
214
+ * a refusal's `property` this way, and a form files the problems it finds under the same keys, so
215
+ * each lands beside the input that set the value.
216
+ */
217
+ export declare function refusedProperty(path: readonly PropertyKey[]): string;
218
+ /**
219
+ * A field's type and settings as a write states them, checked together and against the rules:
220
+ * the settings must be what that type is set up with, so a list carries its options and
221
+ * nothing else carries any.
222
+ */
223
+ export declare const TypedSettingsInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
224
+ type: z.ZodEnum<{
225
+ long_text: "long_text";
226
+ short_text: "short_text";
227
+ }>;
228
+ settings: z.ZodOptional<z.ZodUndefined> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
229
+ }, z.core.$strip>, z.ZodObject<{
230
+ type: z.ZodEnum<{
231
+ address: "address";
232
+ }>;
233
+ settings: z.ZodOptional<z.ZodUndefined> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
234
+ }, z.core.$strip>, z.ZodObject<{
235
+ type: z.ZodEnum<{
236
+ list: "list";
237
+ }>;
238
+ settings: z.ZodPipe<z.ZodObject<{
239
+ options: z.ZodArray<z.ZodString>;
240
+ multiple: z.ZodBoolean;
241
+ }, z.core.$strip>, z.ZodTransform<{
242
+ options: string[];
243
+ multiple: boolean;
244
+ }, {
245
+ options: string[];
246
+ multiple: boolean;
247
+ }>> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
248
+ }, z.core.$strip>], "type">;
249
+ /** A field's type and settings as they are read back: paired, but checked for their shape alone. */
250
+ export declare const TypedSettingsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
251
+ type: z.ZodEnum<{
252
+ long_text: "long_text";
253
+ short_text: "short_text";
254
+ }>;
255
+ settings: z.ZodOptional<z.ZodUndefined> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
256
+ }, z.core.$strip>, z.ZodObject<{
257
+ type: z.ZodEnum<{
258
+ address: "address";
259
+ }>;
260
+ settings: z.ZodOptional<z.ZodUndefined> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
261
+ }, z.core.$strip>, z.ZodObject<{
262
+ type: z.ZodEnum<{
263
+ list: "list";
264
+ }>;
265
+ settings: z.ZodObject<{
266
+ options: z.ZodArray<z.ZodString>;
267
+ multiple: z.ZodBoolean;
268
+ }, z.core.$strip> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
269
+ }, z.core.$strip>], "type">;
270
+ /**
271
+ * A field definition as the Admin and Members APIs return it. Ghost writes every definition through
272
+ * this and Admin reads every one through it, so both ends are checked against one shape. Portal
273
+ * uses the type without the check, because zod would add to every page view on every site. Dates
274
+ * are ISO strings, as JSON carries them.
275
+ */
276
+ export declare const MetafieldDefinitionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
277
+ type: z.ZodEnum<{
278
+ long_text: "long_text";
279
+ short_text: "short_text";
280
+ }>;
281
+ settings: z.ZodOptional<z.ZodUndefined> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
282
+ namespace: z.core.$ZodBranded<import("zod/mini").ZodMiniString<string>, "Namespace", "out">;
283
+ key: z.core.$ZodBranded<import("zod/mini").ZodMiniString<string>, "Key", "out">;
284
+ name: z.ZodString;
285
+ status: z.ZodEnum<{
286
+ active: "active";
287
+ archived: "archived";
288
+ }>;
289
+ access: z.ZodObject<{
290
+ member: z.ZodEnum<{
291
+ none: "none";
292
+ read: "read";
293
+ write: "write";
294
+ }>;
295
+ }, z.core.$strip>;
296
+ created_at: z.ZodISODateTime;
297
+ updated_at: z.ZodNullable<z.ZodISODateTime>;
298
+ }, z.core.$strip>, z.ZodObject<{
299
+ type: z.ZodEnum<{
300
+ address: "address";
301
+ }>;
302
+ settings: z.ZodOptional<z.ZodUndefined> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
303
+ namespace: z.core.$ZodBranded<import("zod/mini").ZodMiniString<string>, "Namespace", "out">;
304
+ key: z.core.$ZodBranded<import("zod/mini").ZodMiniString<string>, "Key", "out">;
305
+ name: z.ZodString;
306
+ status: z.ZodEnum<{
307
+ active: "active";
308
+ archived: "archived";
309
+ }>;
310
+ access: z.ZodObject<{
311
+ member: z.ZodEnum<{
312
+ none: "none";
313
+ read: "read";
314
+ write: "write";
315
+ }>;
316
+ }, z.core.$strip>;
317
+ created_at: z.ZodISODateTime;
318
+ updated_at: z.ZodNullable<z.ZodISODateTime>;
319
+ }, z.core.$strip>, z.ZodObject<{
320
+ type: z.ZodEnum<{
321
+ list: "list";
322
+ }>;
323
+ settings: z.ZodObject<{
324
+ options: z.ZodArray<z.ZodString>;
325
+ multiple: z.ZodBoolean;
326
+ }, z.core.$strip> & z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
327
+ namespace: z.core.$ZodBranded<import("zod/mini").ZodMiniString<string>, "Namespace", "out">;
328
+ key: z.core.$ZodBranded<import("zod/mini").ZodMiniString<string>, "Key", "out">;
329
+ name: z.ZodString;
330
+ status: z.ZodEnum<{
331
+ active: "active";
332
+ archived: "archived";
333
+ }>;
334
+ access: z.ZodObject<{
335
+ member: z.ZodEnum<{
336
+ none: "none";
337
+ read: "read";
338
+ write: "write";
339
+ }>;
340
+ }, z.core.$strip>;
341
+ created_at: z.ZodISODateTime;
342
+ updated_at: z.ZodNullable<z.ZodISODateTime>;
343
+ }, z.core.$strip>], "type">;
344
+ export type MetafieldDefinition = z.output<typeof MetafieldDefinitionSchema>;
84
345
  /**
85
346
  * Where a change to a member's values was made, as a member's activity feed names it.
86
347
  * Shared so a place added on the server is one Admin has to be told how to describe.
@@ -117,59 +378,15 @@ export interface MetafieldChangeEntry<TDate = string> {
117
378
  */
118
379
  export declare const MAX_LONG_TEXT_BYTES = 65535;
119
380
  /**
120
- * The types a composite's parts can declare, each defined once with its rule. A country
121
- * code and a postal code both store short text, but they are different things — the
122
- * part's type is what a control or a filter dispatches on, the way a field's own type
123
- * is for a scalar.
381
+ * A value of any field type, as a caller holding a field of unknown type must accept it.
124
382
  */
125
- export declare const PART_TYPES: {
126
- short_text: z.ZodString;
127
- postal_code: z.ZodString;
128
- country_code: z.ZodString;
129
- };
130
- export interface FieldTypeDefinition {
131
- /** What kind of value this is, for anything that has to compare one. */
132
- kind: import('./structure.js').FieldKind;
133
- value: z.ZodType;
134
- }
135
- export declare const FIELD_TYPES: {
136
- short_text: {
137
- kind: "text";
138
- value: z.ZodString;
139
- };
140
- long_text: {
141
- kind: "text";
142
- value: z.ZodString;
143
- };
144
- address: {
145
- kind: 'record';
146
- value: z.ZodObject<{
147
- line1: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
148
- line2: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
149
- city: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
150
- state: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
151
- postal_code: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
152
- country: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
153
- }, z.core.$strict>;
154
- };
155
- };
156
- /** Named for the admin types built on it, which speak of an address rather than a record. */
157
- export declare const AddressValue: z.ZodObject<{
158
- line1: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
159
- line2: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
160
- city: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
161
- state: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
162
- postal_code: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
163
- country: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>>;
164
- }, z.core.$strict>;
165
- export type Address = z.infer<typeof AddressValue>;
383
+ export type FieldValue = ValueOf<FieldType>;
384
+ export type Address = ValueOf<'address'>;
166
385
  /**
167
- * A value of any field type, as a caller holding a field of unknown type must accept it.
168
- *
169
- * Derived from the schemas rather than listed, so a type added here widens it without
170
- * anyone remembering to.
386
+ * The rule a value of one field must satisfy. It takes the field rather than its type so that a
387
+ * rule depending on the field's own setup, such as the options a list field offers, changes here
388
+ * and nowhere else; such a rule is built from the field rather than kept per type. Throws for a
389
+ * type this build doesn't know.
171
390
  */
172
- export type FieldValue = {
173
- [T in FieldType]: z.infer<(typeof FIELD_TYPES)[T]['value']>;
174
- }[FieldType];
391
+ export declare function valueSchemaFor(field: TypedSettings): z.ZodType<FieldValue>;
175
392
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAA+B,KAAK,SAAS,EAAiB,MAAM,gBAAgB,CAAC;AAI5F,OAAO,EACL,WAAW,EACX,WAAW,EACX,cAAc,EACd,aAAa,EACb,WAAW,EACX,OAAO,EACP,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,QAAQ,GACd,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,eAAO,MAAM,eAAe;;;;EAAyB,CAAC;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,YAAI,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AACvE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AACjE,eAAO,MAAM,kBAAkB;;;;EAA+B,CAAC;AAC/D,eAAO,MAAM,aAAa;mBAClB,MAAM;mBACN,MAAM;oBACL,OAAO;CACuC,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,wBAAwB,YACnC,OAAO,EACP,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,UAAU,CACF,CAAC;AACX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,4FAA4F;AAC5F,eAAO,MAAM,uBAAuB,WAAY,MAAM,KAAG,MAAM,IAAI,qBACD,CAAC;AAEnE,qGAAqG;AACrG,eAAO,MAAM,+BAA+B;;;;iBAI1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,KAAK,GAAG,MAAM;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,qBAAqB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC9C,UAAU,EAAE,yBAAyB,EAAE,CAAC;IACxC,UAAU,EAAE,KAAK,CAAC;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AA2BzC;;;;;GAKG;AACH,eAAO,MAAM,UAAU;;;;CAwBiB,CAAC;AA+BzC,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,IAAI,EAAE,OAAO,gBAAgB,EAAE,SAAS,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;CAClB;AA2CD,eAAO,MAAM,WAAW;;;;;;;;;;cAHP,QAAQ;;;;;;;;;;CAevB,CAAC;AAEH,6FAA6F;AAC7F,eAAO,MAAM,YAAY;;;;;;;kBAA4B,CAAC;AACtD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG;KAAG,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;CAAE,CAAC,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}