@shapio/schema 0.5.3 → 0.5.5
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/index.d.ts +107 -9
- package/dist/index.js +152 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare const createStableId: () => string;
|
|
|
17
17
|
//#endregion
|
|
18
18
|
//#region src/types/dataTypes.d.ts
|
|
19
19
|
/** Every stored data type. A field's data type is separate from the editor that renders it (brief §2.5). */
|
|
20
|
-
export declare const DATA_TYPES: readonly ["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"];
|
|
20
|
+
export declare const DATA_TYPES: readonly ["string", "text", "code", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"];
|
|
21
21
|
export type DataType = (typeof DATA_TYPES)[number];
|
|
22
22
|
export declare const isDataType: (value: unknown) => value is DataType;
|
|
23
23
|
/**
|
|
@@ -48,6 +48,9 @@ export type JsonObject = {
|
|
|
48
48
|
//#region src/types/settings.d.ts
|
|
49
49
|
export declare const MEDIA_KINDS: readonly ["image", "video", "audio", "document", "other"];
|
|
50
50
|
export declare const RELATION_CARDINALITIES: readonly ["one", "many"];
|
|
51
|
+
/** Languages a `code` field can hold. The language reaches the API (OpenAPI, GraphQL, generated types). */
|
|
52
|
+
export declare const CODE_LANGUAGES: readonly ["plain", "html", "css", "javascript", "json", "yaml", "markdown"];
|
|
53
|
+
export type CodeLanguage = (typeof CODE_LANGUAGES)[number];
|
|
51
54
|
export declare const EnumValueSchema: Type.TObject<{
|
|
52
55
|
value: Type.TString;
|
|
53
56
|
label: Type.TString;
|
|
@@ -62,6 +65,13 @@ export declare const SETTINGS_SCHEMAS: {
|
|
|
62
65
|
minLength: Type.TOptional<Type.TInteger>;
|
|
63
66
|
maxLength: Type.TOptional<Type.TInteger>;
|
|
64
67
|
}>;
|
|
68
|
+
code: Type.TObject<{
|
|
69
|
+
/** JSON only: a value that does not parse is refused. */
|
|
70
|
+
validate: Type.TOptional<Type.TBoolean>;
|
|
71
|
+
minLength: Type.TOptional<Type.TInteger>;
|
|
72
|
+
maxLength: Type.TOptional<Type.TInteger>;
|
|
73
|
+
language: Type.TOptional<Type.TEnum<["plain", "html", "css", "javascript", "json", "yaml", "markdown"]>>;
|
|
74
|
+
}>;
|
|
65
75
|
richtext: Type.TObject<{
|
|
66
76
|
formatVersion: Type.TOptional<Type.TInteger>;
|
|
67
77
|
maxLength: Type.TOptional<Type.TInteger>;
|
|
@@ -146,7 +156,10 @@ type SettingsSchemas = typeof SETTINGS_SCHEMAS;
|
|
|
146
156
|
/** Settings as authored (defaults may be missing). */
|
|
147
157
|
export type DataTypeSettingsInput = { [T in DataType]: Static<SettingsSchemas[T]>; };
|
|
148
158
|
/** Settings after normalization: the defaulted keys are always present. */
|
|
149
|
-
export type DataTypeSettings = Omit<DataTypeSettingsInput, 'richtext' | 'enum' | 'media' | 'component'> & {
|
|
159
|
+
export type DataTypeSettings = Omit<DataTypeSettingsInput, 'code' | 'richtext' | 'enum' | 'media' | 'component'> & {
|
|
160
|
+
code: DataTypeSettingsInput['code'] & {
|
|
161
|
+
language: CodeLanguage;
|
|
162
|
+
};
|
|
150
163
|
richtext: DataTypeSettingsInput['richtext'] & {
|
|
151
164
|
formatVersion: number;
|
|
152
165
|
};
|
|
@@ -168,6 +181,19 @@ export declare const DEFINITION_KINDS: readonly ["collection", "singleton", "com
|
|
|
168
181
|
export type DefinitionKind = (typeof DEFINITION_KINDS)[number];
|
|
169
182
|
export declare const SORT_DIRECTIONS: readonly ["asc", "desc"];
|
|
170
183
|
export type SortDirection = (typeof SORT_DIRECTIONS)[number];
|
|
184
|
+
/**
|
|
185
|
+
* How an entry of a model opens: `document` (title typed into the page, blocks in a canvas, properties in
|
|
186
|
+
* the strip and the settings drawer) or `form` (every field inline at its `width`, sections from
|
|
187
|
+
* `display.groups`). Unset means `document`; normalizing drops an explicit `document`.
|
|
188
|
+
*/
|
|
189
|
+
export declare const ENTRY_LAYOUTS: readonly ["document", "form"];
|
|
190
|
+
export type EntryLayout = (typeof ENTRY_LAYOUTS)[number];
|
|
191
|
+
/**
|
|
192
|
+
* A field's width in a form-layout entry, as a share of the row: rows fill in field order and wrap. Unset
|
|
193
|
+
* means `full`; normalizing drops an explicit `full`.
|
|
194
|
+
*/
|
|
195
|
+
export declare const FIELD_WIDTHS: readonly ["full", "two-thirds", "half", "third"];
|
|
196
|
+
export type FieldWidth = (typeof FIELD_WIDTHS)[number];
|
|
171
197
|
export declare const MAX_FIELDS_PER_DEFINITION = 500;
|
|
172
198
|
export declare const MAX_LABEL_LENGTH = 200;
|
|
173
199
|
export declare const MAX_DESCRIPTION_LENGTH = 2000;
|
|
@@ -181,7 +207,7 @@ export declare const FieldInputSchema: Type.TObject<{
|
|
|
181
207
|
label: Type.TString;
|
|
182
208
|
/** Help text shown under the control. */
|
|
183
209
|
description: Type.TOptional<Type.TString>;
|
|
184
|
-
type: Type.TEnum<["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
210
|
+
type: Type.TEnum<["string", "text", "code", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
185
211
|
required: Type.TOptional<Type.TBoolean>;
|
|
186
212
|
/** Per-locale value. Ignored (must be false) when the model is not localized. */
|
|
187
213
|
localized: Type.TOptional<Type.TBoolean>;
|
|
@@ -200,8 +226,15 @@ export declare const FieldInputSchema: Type.TObject<{
|
|
|
200
226
|
id: Type.TString;
|
|
201
227
|
options: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
202
228
|
}>>;
|
|
229
|
+
/**
|
|
230
|
+
* Width in a form-layout entry (`display.layout: 'form'`). Default `full`. Model fields only: the
|
|
231
|
+
* validator refuses it on a component's field.
|
|
232
|
+
*/
|
|
233
|
+
width: Type.TOptional<Type.TEnum<["full", "two-thirds", "half", "third"]>>;
|
|
203
234
|
}>;
|
|
204
235
|
export declare const ModelDisplayInputSchema: Type.TObject<{
|
|
236
|
+
/** How entries open: `document` (default) or `form`. See `ENTRY_LAYOUTS`. */
|
|
237
|
+
layout: Type.TOptional<Type.TEnum<["document", "form"]>>;
|
|
205
238
|
/** Field whose value labels an entry in lists, pickers and relation summaries. */
|
|
206
239
|
titleFieldId: Type.TOptional<Type.TString>;
|
|
207
240
|
/** Columns of the content list, in order. */
|
|
@@ -242,6 +275,8 @@ export declare const ModelDefinitionInputSchema: Type.TObject<{
|
|
|
242
275
|
/** Entries have separate draft and published states. Default true. */
|
|
243
276
|
draftAndPublish: Type.TOptional<Type.TBoolean>;
|
|
244
277
|
display: Type.TOptional<Type.TObject<{
|
|
278
|
+
/** How entries open: `document` (default) or `form`. See `ENTRY_LAYOUTS`. */
|
|
279
|
+
layout: Type.TOptional<Type.TEnum<["document", "form"]>>;
|
|
245
280
|
/** Field whose value labels an entry in lists, pickers and relation summaries. */
|
|
246
281
|
titleFieldId: Type.TOptional<Type.TString>;
|
|
247
282
|
/** Columns of the content list, in order. */
|
|
@@ -273,7 +308,7 @@ export declare const ModelDefinitionInputSchema: Type.TObject<{
|
|
|
273
308
|
label: Type.TString;
|
|
274
309
|
/** Help text shown under the control. */
|
|
275
310
|
description: Type.TOptional<Type.TString>;
|
|
276
|
-
type: Type.TEnum<["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
311
|
+
type: Type.TEnum<["string", "text", "code", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
277
312
|
required: Type.TOptional<Type.TBoolean>;
|
|
278
313
|
/** Per-locale value. Ignored (must be false) when the model is not localized. */
|
|
279
314
|
localized: Type.TOptional<Type.TBoolean>;
|
|
@@ -292,6 +327,11 @@ export declare const ModelDefinitionInputSchema: Type.TObject<{
|
|
|
292
327
|
id: Type.TString;
|
|
293
328
|
options: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
294
329
|
}>>;
|
|
330
|
+
/**
|
|
331
|
+
* Width in a form-layout entry (`display.layout: 'form'`). Default `full`. Model fields only: the
|
|
332
|
+
* validator refuses it on a component's field.
|
|
333
|
+
*/
|
|
334
|
+
width: Type.TOptional<Type.TEnum<["full", "two-thirds", "half", "third"]>>;
|
|
295
335
|
}>>;
|
|
296
336
|
}>;
|
|
297
337
|
export declare const ComponentDefinitionInputSchema: Type.TObject<{
|
|
@@ -316,7 +356,7 @@ export declare const ComponentDefinitionInputSchema: Type.TObject<{
|
|
|
316
356
|
label: Type.TString;
|
|
317
357
|
/** Help text shown under the control. */
|
|
318
358
|
description: Type.TOptional<Type.TString>;
|
|
319
|
-
type: Type.TEnum<["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
359
|
+
type: Type.TEnum<["string", "text", "code", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
320
360
|
required: Type.TOptional<Type.TBoolean>;
|
|
321
361
|
/** Per-locale value. Ignored (must be false) when the model is not localized. */
|
|
322
362
|
localized: Type.TOptional<Type.TBoolean>;
|
|
@@ -335,6 +375,11 @@ export declare const ComponentDefinitionInputSchema: Type.TObject<{
|
|
|
335
375
|
id: Type.TString;
|
|
336
376
|
options: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
337
377
|
}>>;
|
|
378
|
+
/**
|
|
379
|
+
* Width in a form-layout entry (`display.layout: 'form'`). Default `full`. Model fields only: the
|
|
380
|
+
* validator refuses it on a component's field.
|
|
381
|
+
*/
|
|
382
|
+
width: Type.TOptional<Type.TEnum<["full", "two-thirds", "half", "third"]>>;
|
|
338
383
|
}>>;
|
|
339
384
|
}>;
|
|
340
385
|
export declare const DefinitionInputSchema: Type.TUnion<[Type.TObject<{
|
|
@@ -348,6 +393,8 @@ export declare const DefinitionInputSchema: Type.TUnion<[Type.TObject<{
|
|
|
348
393
|
/** Entries have separate draft and published states. Default true. */
|
|
349
394
|
draftAndPublish: Type.TOptional<Type.TBoolean>;
|
|
350
395
|
display: Type.TOptional<Type.TObject<{
|
|
396
|
+
/** How entries open: `document` (default) or `form`. See `ENTRY_LAYOUTS`. */
|
|
397
|
+
layout: Type.TOptional<Type.TEnum<["document", "form"]>>;
|
|
351
398
|
/** Field whose value labels an entry in lists, pickers and relation summaries. */
|
|
352
399
|
titleFieldId: Type.TOptional<Type.TString>;
|
|
353
400
|
/** Columns of the content list, in order. */
|
|
@@ -379,7 +426,7 @@ export declare const DefinitionInputSchema: Type.TUnion<[Type.TObject<{
|
|
|
379
426
|
label: Type.TString;
|
|
380
427
|
/** Help text shown under the control. */
|
|
381
428
|
description: Type.TOptional<Type.TString>;
|
|
382
|
-
type: Type.TEnum<["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
429
|
+
type: Type.TEnum<["string", "text", "code", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
383
430
|
required: Type.TOptional<Type.TBoolean>;
|
|
384
431
|
/** Per-locale value. Ignored (must be false) when the model is not localized. */
|
|
385
432
|
localized: Type.TOptional<Type.TBoolean>;
|
|
@@ -398,6 +445,11 @@ export declare const DefinitionInputSchema: Type.TUnion<[Type.TObject<{
|
|
|
398
445
|
id: Type.TString;
|
|
399
446
|
options: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
400
447
|
}>>;
|
|
448
|
+
/**
|
|
449
|
+
* Width in a form-layout entry (`display.layout: 'form'`). Default `full`. Model fields only: the
|
|
450
|
+
* validator refuses it on a component's field.
|
|
451
|
+
*/
|
|
452
|
+
width: Type.TOptional<Type.TEnum<["full", "two-thirds", "half", "third"]>>;
|
|
401
453
|
}>>;
|
|
402
454
|
}>, Type.TObject<{
|
|
403
455
|
kind: Type.TLiteral<"component">;
|
|
@@ -421,7 +473,7 @@ export declare const DefinitionInputSchema: Type.TUnion<[Type.TObject<{
|
|
|
421
473
|
label: Type.TString;
|
|
422
474
|
/** Help text shown under the control. */
|
|
423
475
|
description: Type.TOptional<Type.TString>;
|
|
424
|
-
type: Type.TEnum<["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
476
|
+
type: Type.TEnum<["string", "text", "code", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"]>;
|
|
425
477
|
required: Type.TOptional<Type.TBoolean>;
|
|
426
478
|
/** Per-locale value. Ignored (must be false) when the model is not localized. */
|
|
427
479
|
localized: Type.TOptional<Type.TBoolean>;
|
|
@@ -440,6 +492,11 @@ export declare const DefinitionInputSchema: Type.TUnion<[Type.TObject<{
|
|
|
440
492
|
id: Type.TString;
|
|
441
493
|
options: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
442
494
|
}>>;
|
|
495
|
+
/**
|
|
496
|
+
* Width in a form-layout entry (`display.layout: 'form'`). Default `full`. Model fields only: the
|
|
497
|
+
* validator refuses it on a component's field.
|
|
498
|
+
*/
|
|
499
|
+
width: Type.TOptional<Type.TEnum<["full", "two-thirds", "half", "third"]>>;
|
|
443
500
|
}>>;
|
|
444
501
|
}>]>;
|
|
445
502
|
export type FieldInput = Static<typeof FieldInputSchema>;
|
|
@@ -464,6 +521,8 @@ type FieldBase = {
|
|
|
464
521
|
deprecated: boolean;
|
|
465
522
|
defaultValue?: JsonValue;
|
|
466
523
|
editor: EditorChoice;
|
|
524
|
+
/** Width in a form-layout entry; absent means `full`. */
|
|
525
|
+
width?: FieldWidth;
|
|
467
526
|
};
|
|
468
527
|
/** A normalized field. Narrow on `type` to get typed `settings`. */
|
|
469
528
|
export type FieldDefinition<T extends DataType = DataType> = { [K in T]: FieldBase & {
|
|
@@ -476,6 +535,8 @@ export type FieldGroup = {
|
|
|
476
535
|
fieldIds: string[];
|
|
477
536
|
};
|
|
478
537
|
export type ModelDisplay = {
|
|
538
|
+
/** Absent means `document`. */
|
|
539
|
+
layout?: EntryLayout;
|
|
479
540
|
titleFieldId?: string;
|
|
480
541
|
listFieldIds?: string[];
|
|
481
542
|
defaultSort?: {
|
|
@@ -644,6 +705,34 @@ export type DocumentLayout = {
|
|
|
644
705
|
export declare const effectiveLayout: (model: ModelDefinition) => DocumentLayout;
|
|
645
706
|
/** The strip's properties: the configured ones, or the first `limit` that `hasValue` says are non-empty. */
|
|
646
707
|
export declare const stripFieldsOf: (layout: DocumentLayout, hasValue: (field: FieldDefinition) => boolean, limit?: number) => FieldDefinition[];
|
|
708
|
+
/** How the model's entries open (`display.layout`): `document` unless set to `form`. */
|
|
709
|
+
export declare const entryLayoutOf: (model: ModelDefinition) => EntryLayout;
|
|
710
|
+
/**
|
|
711
|
+
* One section of a form-layout entry: a `display.groups` group (its `id` and `label`), or a run of
|
|
712
|
+
* consecutive ungrouped fields (`label` undefined). A run's `id` is `ungrouped-<ID of its first field>`:
|
|
713
|
+
* stable while that field stays first, and unique because a field starts one run at most. Should a group
|
|
714
|
+
* be given that very ID, the run's ID gets `~` prefixed until no group has it.
|
|
715
|
+
*/
|
|
716
|
+
export type FieldSection = PropertyGroup;
|
|
717
|
+
export type FormLayout = {
|
|
718
|
+
/** The field that labels the entry (`effectiveTitleField`): the page heading. It is also in `sections`. */
|
|
719
|
+
title: FieldDefinition | undefined;
|
|
720
|
+
/** Every live field, in sections. */
|
|
721
|
+
sections: FieldSection[];
|
|
722
|
+
};
|
|
723
|
+
/**
|
|
724
|
+
* The entry form's layout (`display.layout: 'form'`): every live field, the title included, in sections.
|
|
725
|
+
* Field order decides everything: a group's section sits where its first field appears, with its fields in
|
|
726
|
+
* field order, and every run of consecutive ungrouped fields is an unlabelled section of its own at its
|
|
727
|
+
* place. So name, price, sku, description with a Pricing group (price, sku) reads [name], Pricing [price,
|
|
728
|
+
* sku], [description]. Unknown and deprecated ids are skipped. Pure: no values, no I/O.
|
|
729
|
+
*/
|
|
730
|
+
export declare const effectiveFormLayout: (model: ModelDefinition) => FormLayout;
|
|
731
|
+
/**
|
|
732
|
+
* The entry's rich-text body, which "Summarize from body" reads: the document's rich-text canvas fields, or
|
|
733
|
+
* every live rich-text field of a form (a form has no canvas; its fields are all on the page).
|
|
734
|
+
*/
|
|
735
|
+
export declare const richTextBodyOf: (model: ModelDefinition) => FieldDefinition[];
|
|
647
736
|
//#endregion
|
|
648
737
|
//#region src/display/titleField.d.ts
|
|
649
738
|
/** Field types that may label entries: the only types `display.titleFieldId` accepts, and the fallback's. */
|
|
@@ -688,8 +777,9 @@ export type DefinitionInputWithIds = (WithIds<ModelDefinitionInput> & {
|
|
|
688
777
|
/**
|
|
689
778
|
* Applies defaults so that two definitions meaning the same thing are byte-identical once serialized
|
|
690
779
|
* canonically: a hand-written file that omits `public` hashes the same as one that says `public: true`.
|
|
691
|
-
* Empty optional strings and arrays are dropped
|
|
692
|
-
*
|
|
780
|
+
* Empty optional strings and arrays are dropped, and so are the defaults of keys added after definitions
|
|
781
|
+
* were first hashed (`width: 'full'`, `display.layout: 'document'`). A collection without a plural API ID
|
|
782
|
+
* gets the suggested one (`suggestPlural`), so files and definitions from before plural API IDs keep working.
|
|
693
783
|
*/
|
|
694
784
|
export declare const normalizeDefinition: (input: DefinitionInputWithIds) => SchemaDefinition;
|
|
695
785
|
/** Normalizes a definition that is already normalized-shaped (e.g. read back from the database). */
|
|
@@ -1167,6 +1257,14 @@ export declare const richTextToPlainText: (document: RichTextDocument) => string
|
|
|
1167
1257
|
/** Plain text → a document of paragraphs (blank lines split paragraphs; single newlines are hard breaks). */
|
|
1168
1258
|
export declare const plainTextToRichText: (text: string) => RichTextDocument;
|
|
1169
1259
|
//#endregion
|
|
1260
|
+
//#region src/richtext/plainText.d.ts
|
|
1261
|
+
/**
|
|
1262
|
+
* A stored rich text value (`{ format, version, doc }`) as one line of plain text: blocks separated by a
|
|
1263
|
+
* space, whitespace collapsed. For summaries (list cells, collapsed items, review rows), never for delivery.
|
|
1264
|
+
* Anything that is not a valid document (an unconverted value of a field that became rich text) reads as ''.
|
|
1265
|
+
*/
|
|
1266
|
+
export declare const richTextPlainText: (value: unknown) => string;
|
|
1267
|
+
//#endregion
|
|
1170
1268
|
//#region src/themes/tokens.d.ts
|
|
1171
1269
|
/**
|
|
1172
1270
|
* Admin themes (docs/plans/themes.md): a theme is a named, complete set of these tokens for a light variant, a
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { Value } from "typebox/value";
|
|
|
8
8
|
const DATA_TYPES = [
|
|
9
9
|
"string",
|
|
10
10
|
"text",
|
|
11
|
+
"code",
|
|
11
12
|
"richtext",
|
|
12
13
|
"number",
|
|
13
14
|
"integer",
|
|
@@ -74,6 +75,7 @@ const REFERENCE_DATA_TYPES = /* @__PURE__ */ new Set([
|
|
|
74
75
|
const STORAGE_FAMILY = {
|
|
75
76
|
string: "jsonString",
|
|
76
77
|
text: "jsonString",
|
|
78
|
+
code: "jsonString",
|
|
77
79
|
slug: "jsonString",
|
|
78
80
|
email: "jsonString",
|
|
79
81
|
url: "jsonString",
|
|
@@ -108,6 +110,22 @@ const closed$3 = { additionalProperties: false };
|
|
|
108
110
|
const MODEL_KINDS = ["collection", "singleton"];
|
|
109
111
|
const DEFINITION_KINDS = [...MODEL_KINDS, "component"];
|
|
110
112
|
const SORT_DIRECTIONS = ["asc", "desc"];
|
|
113
|
+
/**
|
|
114
|
+
* How an entry of a model opens: `document` (title typed into the page, blocks in a canvas, properties in
|
|
115
|
+
* the strip and the settings drawer) or `form` (every field inline at its `width`, sections from
|
|
116
|
+
* `display.groups`). Unset means `document`; normalizing drops an explicit `document`.
|
|
117
|
+
*/
|
|
118
|
+
const ENTRY_LAYOUTS = ["document", "form"];
|
|
119
|
+
/**
|
|
120
|
+
* A field's width in a form-layout entry, as a share of the row: rows fill in field order and wrap. Unset
|
|
121
|
+
* means `full`; normalizing drops an explicit `full`.
|
|
122
|
+
*/
|
|
123
|
+
const FIELD_WIDTHS = [
|
|
124
|
+
"full",
|
|
125
|
+
"two-thirds",
|
|
126
|
+
"half",
|
|
127
|
+
"third"
|
|
128
|
+
];
|
|
111
129
|
const MAX_FIELDS_PER_DEFINITION = 500;
|
|
112
130
|
const MAX_LABEL_LENGTH = 200;
|
|
113
131
|
const MAX_DESCRIPTION_LENGTH = 2e3;
|
|
@@ -144,7 +162,12 @@ const FieldInputSchema = Type.Object({
|
|
|
144
162
|
defaultValue: Type.Optional(Type.Unknown()),
|
|
145
163
|
/** Type-specific settings, validated against SETTINGS_SCHEMAS[type]. */
|
|
146
164
|
settings: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
|
|
147
|
-
editor: Type.Optional(EditorChoiceInputSchema)
|
|
165
|
+
editor: Type.Optional(EditorChoiceInputSchema),
|
|
166
|
+
/**
|
|
167
|
+
* Width in a form-layout entry (`display.layout: 'form'`). Default `full`. Model fields only: the
|
|
168
|
+
* validator refuses it on a component's field.
|
|
169
|
+
*/
|
|
170
|
+
width: Type.Optional(Type.Enum(FIELD_WIDTHS))
|
|
148
171
|
}, closed$3);
|
|
149
172
|
const FieldGroupSchema = Type.Object({
|
|
150
173
|
id: Type.String({
|
|
@@ -155,6 +178,8 @@ const FieldGroupSchema = Type.Object({
|
|
|
155
178
|
fieldIds: Type.Array(Type.String())
|
|
156
179
|
}, closed$3);
|
|
157
180
|
const ModelDisplayInputSchema = Type.Object({
|
|
181
|
+
/** How entries open: `document` (default) or `form`. See `ENTRY_LAYOUTS`. */
|
|
182
|
+
layout: Type.Optional(Type.Enum(ENTRY_LAYOUTS)),
|
|
158
183
|
/** Field whose value labels an entry in lists, pickers and relation summaries. */
|
|
159
184
|
titleFieldId: Type.Optional(Type.String()),
|
|
160
185
|
/** Columns of the content list, in order. */
|
|
@@ -255,6 +280,16 @@ const MEDIA_KINDS = [
|
|
|
255
280
|
"other"
|
|
256
281
|
];
|
|
257
282
|
const RELATION_CARDINALITIES = ["one", "many"];
|
|
283
|
+
/** Languages a `code` field can hold. The language reaches the API (OpenAPI, GraphQL, generated types). */
|
|
284
|
+
const CODE_LANGUAGES = [
|
|
285
|
+
"plain",
|
|
286
|
+
"html",
|
|
287
|
+
"css",
|
|
288
|
+
"javascript",
|
|
289
|
+
"json",
|
|
290
|
+
"yaml",
|
|
291
|
+
"markdown"
|
|
292
|
+
];
|
|
258
293
|
const EnumValueSchema = Type.Object({
|
|
259
294
|
value: Type.String({
|
|
260
295
|
minLength: 1,
|
|
@@ -274,6 +309,12 @@ const SETTINGS_SCHEMAS = {
|
|
|
274
309
|
}))
|
|
275
310
|
}, closed$2),
|
|
276
311
|
text: Type.Object(lengthRules, closed$2),
|
|
312
|
+
code: Type.Object({
|
|
313
|
+
language: Type.Optional(Type.Enum(CODE_LANGUAGES)),
|
|
314
|
+
...lengthRules,
|
|
315
|
+
/** JSON only: a value that does not parse is refused. */
|
|
316
|
+
validate: Type.Optional(Type.Boolean())
|
|
317
|
+
}, closed$2),
|
|
277
318
|
richtext: Type.Object({
|
|
278
319
|
formatVersion: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
279
320
|
maxLength: Type.Optional(Type.Integer({ minimum: 1 }))
|
|
@@ -482,6 +523,14 @@ const entries = [
|
|
|
482
523
|
maximum: 80
|
|
483
524
|
})) }, closed$1)
|
|
484
525
|
},
|
|
526
|
+
{
|
|
527
|
+
id: "codeEditor",
|
|
528
|
+
dataTypes: ["code"],
|
|
529
|
+
optionsSchema: Type.Object({ rows: Type.Optional(Type.Integer({
|
|
530
|
+
minimum: 3,
|
|
531
|
+
maximum: 80
|
|
532
|
+
})) }, closed$1)
|
|
533
|
+
},
|
|
485
534
|
{
|
|
486
535
|
id: "mediaPicker",
|
|
487
536
|
dataTypes: ["media"],
|
|
@@ -514,6 +563,7 @@ const EDITOR_CATALOGUE = new Map(entries.map((entry) => [entry.id, entry]));
|
|
|
514
563
|
const DEFAULT_EDITORS = {
|
|
515
564
|
string: "textInput",
|
|
516
565
|
text: "textarea",
|
|
566
|
+
code: "codeEditor",
|
|
517
567
|
richtext: "richText",
|
|
518
568
|
number: "numberInput",
|
|
519
569
|
integer: "numberInput",
|
|
@@ -666,6 +716,66 @@ const effectiveLayout = (model) => {
|
|
|
666
716
|
};
|
|
667
717
|
/** The strip's properties: the configured ones, or the first `limit` that `hasValue` says are non-empty. */
|
|
668
718
|
const stripFieldsOf = (layout, hasValue, limit = 5) => layout.strip ?? layout.properties.filter(hasValue).slice(0, limit);
|
|
719
|
+
/** How the model's entries open (`display.layout`): `document` unless set to `form`. */
|
|
720
|
+
const entryLayoutOf = (model) => model.display.layout ?? "document";
|
|
721
|
+
const ungroupedSectionId = (first, groupIds) => {
|
|
722
|
+
let candidate = `ungrouped-${first.id}`;
|
|
723
|
+
while (groupIds.has(candidate)) candidate = `~${candidate}`;
|
|
724
|
+
return candidate;
|
|
725
|
+
};
|
|
726
|
+
/**
|
|
727
|
+
* The entry form's layout (`display.layout: 'form'`): every live field, the title included, in sections.
|
|
728
|
+
* Field order decides everything: a group's section sits where its first field appears, with its fields in
|
|
729
|
+
* field order, and every run of consecutive ungrouped fields is an unlabelled section of its own at its
|
|
730
|
+
* place. So name, price, sku, description with a Pricing group (price, sku) reads [name], Pricing [price,
|
|
731
|
+
* sku], [description]. Unknown and deprecated ids are skipped. Pure: no values, no I/O.
|
|
732
|
+
*/
|
|
733
|
+
const effectiveFormLayout = (model) => {
|
|
734
|
+
const groups = model.display.groups ?? [];
|
|
735
|
+
const groupIds = new Set(groups.map((group) => group.id));
|
|
736
|
+
const groupOf = /* @__PURE__ */ new Map();
|
|
737
|
+
for (const group of groups) for (const fieldId of group.fieldIds) if (!groupOf.has(fieldId)) groupOf.set(fieldId, group);
|
|
738
|
+
const sections = [];
|
|
739
|
+
const groupSections = /* @__PURE__ */ new Map();
|
|
740
|
+
let run;
|
|
741
|
+
for (const field of model.fields) {
|
|
742
|
+
if (field.deprecated) continue;
|
|
743
|
+
const group = groupOf.get(field.id);
|
|
744
|
+
if (!group) {
|
|
745
|
+
if (!run) {
|
|
746
|
+
run = {
|
|
747
|
+
id: ungroupedSectionId(field, groupIds),
|
|
748
|
+
label: void 0,
|
|
749
|
+
fields: []
|
|
750
|
+
};
|
|
751
|
+
sections.push(run);
|
|
752
|
+
}
|
|
753
|
+
run.fields.push(field);
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
run = void 0;
|
|
757
|
+
let section = groupSections.get(group.id);
|
|
758
|
+
if (!section) {
|
|
759
|
+
section = {
|
|
760
|
+
id: group.id,
|
|
761
|
+
label: group.label,
|
|
762
|
+
fields: []
|
|
763
|
+
};
|
|
764
|
+
groupSections.set(group.id, section);
|
|
765
|
+
sections.push(section);
|
|
766
|
+
}
|
|
767
|
+
section.fields.push(field);
|
|
768
|
+
}
|
|
769
|
+
return {
|
|
770
|
+
title: effectiveTitleField(model),
|
|
771
|
+
sections
|
|
772
|
+
};
|
|
773
|
+
};
|
|
774
|
+
/**
|
|
775
|
+
* The entry's rich-text body, which "Summarize from body" reads: the document's rich-text canvas fields, or
|
|
776
|
+
* every live rich-text field of a form (a form has no canvas; its fields are all on the page).
|
|
777
|
+
*/
|
|
778
|
+
const richTextBodyOf = (model) => entryLayoutOf(model) === "form" ? model.fields.filter((field) => field.type === "richtext" && !field.deprecated) : effectiveLayout(model).canvas.filter((field) => field.type === "richtext");
|
|
669
779
|
//#endregion
|
|
670
780
|
//#region src/validators/apiKey.ts
|
|
671
781
|
/**
|
|
@@ -715,6 +825,7 @@ const suggestPlural = (apiKey) => {
|
|
|
715
825
|
//#endregion
|
|
716
826
|
//#region src/normalize.ts
|
|
717
827
|
const SETTINGS_DEFAULTS = {
|
|
828
|
+
code: { language: "plain" },
|
|
718
829
|
richtext: { formatVersion: 1 },
|
|
719
830
|
enum: { multiple: false },
|
|
720
831
|
media: { multiple: false },
|
|
@@ -768,17 +879,22 @@ const normalizeField = (field) => {
|
|
|
768
879
|
editor: {
|
|
769
880
|
id: field.editor?.id ?? DEFAULT_EDITORS[field.type],
|
|
770
881
|
options: field.editor?.options ?? {}
|
|
771
|
-
}
|
|
882
|
+
},
|
|
883
|
+
width: field.width === "full" ? void 0 : field.width
|
|
772
884
|
};
|
|
773
885
|
return withoutEmpty(normalized);
|
|
774
886
|
};
|
|
775
|
-
const normalizeModelDisplay = (display) => withoutEmpty({
|
|
887
|
+
const normalizeModelDisplay = (display) => withoutEmpty({
|
|
888
|
+
...display,
|
|
889
|
+
layout: display?.layout === "document" ? void 0 : display?.layout
|
|
890
|
+
});
|
|
776
891
|
const normalizeComponentDisplay = (display) => withoutEmpty({ ...display });
|
|
777
892
|
/**
|
|
778
893
|
* Applies defaults so that two definitions meaning the same thing are byte-identical once serialized
|
|
779
894
|
* canonically: a hand-written file that omits `public` hashes the same as one that says `public: true`.
|
|
780
|
-
* Empty optional strings and arrays are dropped
|
|
781
|
-
*
|
|
895
|
+
* Empty optional strings and arrays are dropped, and so are the defaults of keys added after definitions
|
|
896
|
+
* were first hashed (`width: 'full'`, `display.layout: 'document'`). A collection without a plural API ID
|
|
897
|
+
* gets the suggested one (`suggestPlural`), so files and definitions from before plural API IDs keep working.
|
|
782
898
|
*/
|
|
783
899
|
const normalizeDefinition = (input) => {
|
|
784
900
|
const fields = input.fields.map(normalizeField);
|
|
@@ -823,6 +939,7 @@ const checkDefaultValue = (field) => {
|
|
|
823
939
|
switch (field.type) {
|
|
824
940
|
case "string":
|
|
825
941
|
case "text":
|
|
942
|
+
case "code":
|
|
826
943
|
case "email":
|
|
827
944
|
case "url": return isString ? null : "must be a string";
|
|
828
945
|
case "slug": return matches(SLUG_PATTERN) ? null : "must be a lower-case slug";
|
|
@@ -1167,6 +1284,7 @@ const checkSettings = (field, path, definition) => {
|
|
|
1167
1284
|
if (!source) issues.push(issue(`${path}/settings/sourceFieldId`, "UNKNOWN_FIELD_REFERENCE", "refers to no field of this definition"));
|
|
1168
1285
|
else if (source.type !== "string" && source.type !== "text") issues.push(issue(`${path}/settings/sourceFieldId`, "INVALID_FIELD_REFERENCE", "must refer to a string or text field"));
|
|
1169
1286
|
}
|
|
1287
|
+
if (field.type === "code" && field.settings.validate && field.settings.language !== "json") issues.push(issue(`${path}/settings/validate`, "INVALID_SETTINGS", "only a json code field can be validated"));
|
|
1170
1288
|
if (field.type === "richtext" && field.settings.formatVersion !== 1) issues.push(issue(`${path}/settings/formatVersion`, "INVALID_SETTINGS", "unsupported rich-text format version"));
|
|
1171
1289
|
if (field.type === "relation" && !isStableId(field.settings.target)) issues.push(issue(`${path}/settings/target`, "INVALID_ID", "must be the ID of a model"));
|
|
1172
1290
|
if (field.type === "component" && !isStableId(field.settings.component)) issues.push(issue(`${path}/settings/component`, "INVALID_ID", "must be the ID of a component"));
|
|
@@ -1189,6 +1307,7 @@ const checkFlags = (field, path, isComponent) => {
|
|
|
1189
1307
|
"filterable",
|
|
1190
1308
|
"sortable"
|
|
1191
1309
|
]) if (field[flag]) reject(flag, `fields of a component cannot be ${flag}`);
|
|
1310
|
+
if (field.width !== void 0) reject("width", "fields of a component have no width");
|
|
1192
1311
|
}
|
|
1193
1312
|
if (field.deprecated && field.required) reject("required", "a deprecated field cannot be required");
|
|
1194
1313
|
return issues;
|
|
@@ -1642,7 +1761,8 @@ const DEFINITION_METADATA = [
|
|
|
1642
1761
|
const FIELD_METADATA = [
|
|
1643
1762
|
"label",
|
|
1644
1763
|
"description",
|
|
1645
|
-
"defaultValue"
|
|
1764
|
+
"defaultValue",
|
|
1765
|
+
"width"
|
|
1646
1766
|
];
|
|
1647
1767
|
const FIELD_FLAGS = [
|
|
1648
1768
|
["required", "field.required"],
|
|
@@ -1813,6 +1933,7 @@ const hasIndex = (field) => Boolean(field && (field.filterable || field.sortable
|
|
|
1813
1933
|
const API_SCALAR = {
|
|
1814
1934
|
string: "String",
|
|
1815
1935
|
text: "String",
|
|
1936
|
+
code: "String",
|
|
1816
1937
|
slug: "String",
|
|
1817
1938
|
email: "String",
|
|
1818
1939
|
url: "String",
|
|
@@ -1834,6 +1955,12 @@ const API_SCALAR = {
|
|
|
1834
1955
|
dynamiczone: "DynamicZone"
|
|
1835
1956
|
};
|
|
1836
1957
|
const PLAIN_TEXT_TYPES = /* @__PURE__ */ new Set(["string", "text"]);
|
|
1958
|
+
/** Types any string value is valid for, so a same-family change to one without constraints only widens. */
|
|
1959
|
+
const TEXT_TARGETS = /* @__PURE__ */ new Set([
|
|
1960
|
+
"string",
|
|
1961
|
+
"text",
|
|
1962
|
+
"code"
|
|
1963
|
+
]);
|
|
1837
1964
|
const SCALAR_FAMILIES = /* @__PURE__ */ new Set([
|
|
1838
1965
|
"jsonString",
|
|
1839
1966
|
"jsonNumber",
|
|
@@ -1842,23 +1969,23 @@ const SCALAR_FAMILIES = /* @__PURE__ */ new Set([
|
|
|
1842
1969
|
]);
|
|
1843
1970
|
const hasTextConstraints = (field) => {
|
|
1844
1971
|
const settings = field?.settings ?? {};
|
|
1845
|
-
return settings.minLength !== void 0 || settings.maxLength !== void 0 || settings.pattern !== void 0;
|
|
1972
|
+
return settings.minLength !== void 0 || settings.maxLength !== void 0 || settings.pattern !== void 0 || settings.validate === true;
|
|
1846
1973
|
};
|
|
1847
1974
|
/**
|
|
1848
1975
|
* A type change. Within one storage family the stored JSON stays as it is: widening is live, anything else
|
|
1849
1976
|
* re-validates existing values. Across families Shapio converts values with a job, for the pairs it knows.
|
|
1850
1977
|
*/
|
|
1851
1978
|
const classifyTypeChange = (from, to, after) => {
|
|
1852
|
-
const breaking = API_SCALAR[from] !== API_SCALAR[to];
|
|
1979
|
+
const breaking = API_SCALAR[from] !== API_SCALAR[to] || to === "code" && from !== "code";
|
|
1853
1980
|
const fromFamily = STORAGE_FAMILY[from];
|
|
1854
1981
|
const toFamily = STORAGE_FAMILY[to];
|
|
1855
|
-
if (fromFamily === toFamily) return fromFamily === "jsonString" &&
|
|
1982
|
+
if (fromFamily === toFamily) return fromFamily === "jsonString" && TEXT_TARGETS.has(to) && !hasTextConstraints(after) || from === "integer" && to === "number" || from === "biginteger" && to === "decimal" && after?.type === "decimal" && after.settings.precision === void 0 ? result("additive", { breaking }) : result("validation", {
|
|
1856
1983
|
breaking,
|
|
1857
1984
|
prerequisites: ["validateValues"]
|
|
1858
1985
|
});
|
|
1859
1986
|
const numericPair = fromFamily === "jsonNumber" && toFamily === "numericString" || fromFamily === "numericString" && toFamily === "jsonNumber";
|
|
1860
1987
|
const toText = SCALAR_FAMILIES.has(fromFamily) && PLAIN_TEXT_TYPES.has(to);
|
|
1861
|
-
const textToRichtext = fromFamily === "jsonString" && to === "richtext";
|
|
1988
|
+
const textToRichtext = fromFamily === "jsonString" && from !== "code" && to === "richtext";
|
|
1862
1989
|
const richtextToText = from === "richtext" && PLAIN_TEXT_TYPES.has(to);
|
|
1863
1990
|
const supported = numericPair || toText || textToRichtext || richtextToText;
|
|
1864
1991
|
return result("conversion", {
|
|
@@ -1905,7 +2032,9 @@ const classifySettingsChange = (change) => {
|
|
|
1905
2032
|
case "components":
|
|
1906
2033
|
case "allowedKinds":
|
|
1907
2034
|
case "protocols": return validation(to !== void 0 && (from === void 0 || removesAny(from, to)));
|
|
1908
|
-
case "sourceFieldId":
|
|
2035
|
+
case "sourceFieldId":
|
|
2036
|
+
case "language": return result("metadata");
|
|
2037
|
+
case "validate": return validation(to === true);
|
|
1909
2038
|
case "multiple":
|
|
1910
2039
|
case "repeatable":
|
|
1911
2040
|
case "cardinality": return result("conversion", {
|
|
@@ -2367,6 +2496,17 @@ const plainTextToRichText = (text) => {
|
|
|
2367
2496
|
};
|
|
2368
2497
|
};
|
|
2369
2498
|
//#endregion
|
|
2499
|
+
//#region src/richtext/plainText.ts
|
|
2500
|
+
/**
|
|
2501
|
+
* A stored rich text value (`{ format, version, doc }`) as one line of plain text: blocks separated by a
|
|
2502
|
+
* space, whitespace collapsed. For summaries (list cells, collapsed items, review rows), never for delivery.
|
|
2503
|
+
* Anything that is not a valid document (an unconverted value of a field that became rich text) reads as ''.
|
|
2504
|
+
*/
|
|
2505
|
+
const richTextPlainText = (value) => {
|
|
2506
|
+
const result = validateRichText(value);
|
|
2507
|
+
return result.ok ? richTextToPlainText(result.document).replace(/\s+/g, " ").trim() : "";
|
|
2508
|
+
};
|
|
2509
|
+
//#endregion
|
|
2370
2510
|
//#region src/themes/tokens.ts
|
|
2371
2511
|
/**
|
|
2372
2512
|
* Admin themes (docs/plans/themes.md): a theme is a named, complete set of these tokens for a light variant, a
|
|
@@ -2633,6 +2773,6 @@ const SeoDefaultsSchema = Type.Object({
|
|
|
2633
2773
|
twitterHandle: Type.Union([Type.String({ pattern: SEO_TWITTER_HANDLE_PATTERN.source }), Type.Null()])
|
|
2634
2774
|
}, closed);
|
|
2635
2775
|
//#endregion
|
|
2636
|
-
export { API_KEY_PATTERN, BIGINTEGER_PATTERN, BUILT_IN_THEME_KEYS, CANVAS_ELIGIBLE, CHANGE_KINDS, COMPONENT_TYPE_SUFFIXES, CUSTOM_EDITOR_ID_PATTERN, ComponentDefinitionInputSchema, ComponentDisplayInputSchema, DATA_TYPES, DATETIME_PATTERN, DATE_PATTERN, DECIMAL_PATTERN, DEFAULT_EDITORS, DEFAULT_SEO_KEYS, DEFINITION_KINDS, DefinitionInputSchema, EDITOR_CATALOGUE, EMPTY_SEO_DEFAULTS, EditorChoiceInputSchema, EnumValueSchema, FieldInputSchema, INLINE_TITLE_TYPES, LOCALE_CODE_PATTERN, LOCK_FILE_FORMAT_VERSION, LOCK_FILE_PATH, LocaleInputSchema, LockEntrySchema, LockFileError, LockFileSchema, MARK_RULES, MAX_API_KEY_LENGTH, MAX_COMPONENT_DEPTH, MAX_DESCRIPTION_LENGTH, MAX_FALLBACK_CHAIN, MAX_FIELDS_PER_DEFINITION, MAX_LABEL_LENGTH, MAX_RICHTEXT_DEPTH, MEDIA_KINDS, MODEL_KINDS, MODEL_TYPE_SUFFIXES, MUTATION_PREFIXES, ModelDefinitionInputSchema, ModelDisplayInputSchema, NODE_RULES, PLURAL_FALLBACK_SUFFIX, REFERENCE_DATA_TYPES, RELATION_CARDINALITIES, RESERVED_DEFINITION_API_KEYS, RESERVED_FIELD_API_KEYS, RESERVED_QUERY_NAMES, RESERVED_TYPE_NAMES, RICHTEXT_FORMAT, RICHTEXT_FORMAT_VERSION, SAFE_LINK_PATTERN, SCALAR_DATA_TYPES, SCHEMA_KIND_DIRECTORIES, SEO_COMPONENT_API_KEY, SEO_COMPONENT_ID, SEO_DESCRIPTION_SOFT_MAX, SEO_EDITOR_ID, SEO_FIELD_IDS, SEO_TITLE_PLACEHOLDER, SEO_TITLE_SOFT_MAX, SEO_TITLE_TEMPLATE_PATTERN, SEO_TWITTER_HANDLE_PATTERN, SETTINGS_SCHEMAS, SITES_DIRECTORY, SLUG_PATTERN, SORT_DIRECTIONS, STABLE_ID_PATTERN, STORAGE_FAMILY, STRIP_DEFAULT_COUNT, SchemaValidationError, SeoDefaultsSchema, SeoLocaleDefaultsSchema, TEXT_TITLE_FIELD_TYPES, THEME_BRAND_TOKENS, THEME_COLOUR_PATTERN, THEME_DARK_UI_PAIRS, THEME_KEY_PATTERN, THEME_SEMANTIC_TOKENS, THEME_TEXT_PAIRS, THEME_TOKENS, THEME_UI_PAIRS, THEME_VARIANTS, TIME_PATTERN, TITLE_FIELD_TYPES, UID_PATTERN, UNIQUE_CAPABLE_DATA_TYPES, applyTitleTemplate, assignIds, canonicalJson, checkApiKeySyntax, checkDefaultValue, checkThemeContrast, classifyChange, classifyChanges, classifyLocaleChange, collectionQueryName, contrastRatio, createStableId, decideSync, diffDefinitions, effectiveLayout, effectiveTitleField, embeddedComponentIds, escapeHtml, findDependentModels, findReferencingDefinitions, foldApiKey, generatedNames, hashDefinition, isApiKeySyntaxValid, isCanvasEligible, isComponentDefinition, isCoverEligible, isCustomEditorId, isDataType, isDocumentPlaceable, isEmptyRichText, isModelDefinition, isSeoField, isStableId, isValidTitleTemplate, issue, listCompatibleEditors, lockCoversSite, lockEntriesForSite, mergePulledLock, normalizeDefinition, parseDefinition, parseLockFile, plainTextToRichText, renderRichTextHtml, renormalizeDefinition, resolveSeo, richTextMediaIds, richTextToPlainText, routeKeyOf, schemaFilePath, scopeDirectory, scopeOfSchemaFilePath, seoComponentDefinition, seoDefaultsForLocale, serializeDefinition, serializeLockFile, sha256, stripFieldsOf, suggestPlural, summarizeChanges, toTypeName, upgradeLockFile, validateDefinition, validateRichText, validateSchema, withDerivedPlural, withSiteCovered };
|
|
2776
|
+
export { API_KEY_PATTERN, BIGINTEGER_PATTERN, BUILT_IN_THEME_KEYS, CANVAS_ELIGIBLE, CHANGE_KINDS, CODE_LANGUAGES, COMPONENT_TYPE_SUFFIXES, CUSTOM_EDITOR_ID_PATTERN, ComponentDefinitionInputSchema, ComponentDisplayInputSchema, DATA_TYPES, DATETIME_PATTERN, DATE_PATTERN, DECIMAL_PATTERN, DEFAULT_EDITORS, DEFAULT_SEO_KEYS, DEFINITION_KINDS, DefinitionInputSchema, EDITOR_CATALOGUE, EMPTY_SEO_DEFAULTS, ENTRY_LAYOUTS, EditorChoiceInputSchema, EnumValueSchema, FIELD_WIDTHS, FieldInputSchema, INLINE_TITLE_TYPES, LOCALE_CODE_PATTERN, LOCK_FILE_FORMAT_VERSION, LOCK_FILE_PATH, LocaleInputSchema, LockEntrySchema, LockFileError, LockFileSchema, MARK_RULES, MAX_API_KEY_LENGTH, MAX_COMPONENT_DEPTH, MAX_DESCRIPTION_LENGTH, MAX_FALLBACK_CHAIN, MAX_FIELDS_PER_DEFINITION, MAX_LABEL_LENGTH, MAX_RICHTEXT_DEPTH, MEDIA_KINDS, MODEL_KINDS, MODEL_TYPE_SUFFIXES, MUTATION_PREFIXES, ModelDefinitionInputSchema, ModelDisplayInputSchema, NODE_RULES, PLURAL_FALLBACK_SUFFIX, REFERENCE_DATA_TYPES, RELATION_CARDINALITIES, RESERVED_DEFINITION_API_KEYS, RESERVED_FIELD_API_KEYS, RESERVED_QUERY_NAMES, RESERVED_TYPE_NAMES, RICHTEXT_FORMAT, RICHTEXT_FORMAT_VERSION, SAFE_LINK_PATTERN, SCALAR_DATA_TYPES, SCHEMA_KIND_DIRECTORIES, SEO_COMPONENT_API_KEY, SEO_COMPONENT_ID, SEO_DESCRIPTION_SOFT_MAX, SEO_EDITOR_ID, SEO_FIELD_IDS, SEO_TITLE_PLACEHOLDER, SEO_TITLE_SOFT_MAX, SEO_TITLE_TEMPLATE_PATTERN, SEO_TWITTER_HANDLE_PATTERN, SETTINGS_SCHEMAS, SITES_DIRECTORY, SLUG_PATTERN, SORT_DIRECTIONS, STABLE_ID_PATTERN, STORAGE_FAMILY, STRIP_DEFAULT_COUNT, SchemaValidationError, SeoDefaultsSchema, SeoLocaleDefaultsSchema, TEXT_TITLE_FIELD_TYPES, THEME_BRAND_TOKENS, THEME_COLOUR_PATTERN, THEME_DARK_UI_PAIRS, THEME_KEY_PATTERN, THEME_SEMANTIC_TOKENS, THEME_TEXT_PAIRS, THEME_TOKENS, THEME_UI_PAIRS, THEME_VARIANTS, TIME_PATTERN, TITLE_FIELD_TYPES, UID_PATTERN, UNIQUE_CAPABLE_DATA_TYPES, applyTitleTemplate, assignIds, canonicalJson, checkApiKeySyntax, checkDefaultValue, checkThemeContrast, classifyChange, classifyChanges, classifyLocaleChange, collectionQueryName, contrastRatio, createStableId, decideSync, diffDefinitions, effectiveFormLayout, effectiveLayout, effectiveTitleField, embeddedComponentIds, entryLayoutOf, escapeHtml, findDependentModels, findReferencingDefinitions, foldApiKey, generatedNames, hashDefinition, isApiKeySyntaxValid, isCanvasEligible, isComponentDefinition, isCoverEligible, isCustomEditorId, isDataType, isDocumentPlaceable, isEmptyRichText, isModelDefinition, isSeoField, isStableId, isValidTitleTemplate, issue, listCompatibleEditors, lockCoversSite, lockEntriesForSite, mergePulledLock, normalizeDefinition, parseDefinition, parseLockFile, plainTextToRichText, renderRichTextHtml, renormalizeDefinition, resolveSeo, richTextBodyOf, richTextMediaIds, richTextPlainText, richTextToPlainText, routeKeyOf, schemaFilePath, scopeDirectory, scopeOfSchemaFilePath, seoComponentDefinition, seoDefaultsForLocale, serializeDefinition, serializeLockFile, sha256, stripFieldsOf, suggestPlural, summarizeChanges, toTypeName, upgradeLockFile, validateDefinition, validateRichText, validateSchema, withDerivedPlural, withSiteCovered };
|
|
2637
2777
|
|
|
2638
2778
|
//# sourceMappingURL=index.js.map
|