@createcms/core 0.1.1 → 0.2.1
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.cjs +105 -0
- package/dist/index.d.cts +81 -3
- package/dist/index.d.ts +81 -3
- package/dist/index.js +105 -0
- package/dist/next/index.d.cts +62 -1
- package/dist/next/index.d.ts +62 -1
- package/dist/plugins/ab-test/index.cjs +4 -0
- package/dist/plugins/ab-test/index.d.cts +62 -1
- package/dist/plugins/ab-test/index.d.ts +62 -1
- package/dist/plugins/ab-test/index.js +4 -0
- package/dist/plugins/consent/index.d.cts +62 -1
- package/dist/plugins/consent/index.d.ts +62 -1
- package/dist/plugins/i18n/index.cjs +4 -0
- package/dist/plugins/i18n/index.d.cts +62 -1
- package/dist/plugins/i18n/index.d.ts +62 -1
- package/dist/plugins/i18n/index.js +4 -0
- package/dist/plugins/multi-tenant/index.d.cts +62 -1
- package/dist/plugins/multi-tenant/index.d.ts +62 -1
- package/dist/react/blocks.cjs +2 -1
- package/dist/react/blocks.d.cts +79 -9
- package/dist/react/blocks.d.ts +79 -9
- package/dist/react/blocks.js +2 -1
- package/dist/react/index.cjs +4 -0
- package/dist/react/index.d.cts +66 -1
- package/dist/react/index.d.ts +66 -1
- package/dist/react/index.js +4 -0
- package/dist/react/tracking.d.cts +62 -1
- package/dist/react/tracking.d.ts +62 -1
- package/package.json +1 -1
package/dist/next/index.d.cts
CHANGED
|
@@ -62,18 +62,70 @@ type BlockDefinition<TProps extends Record<string, BlockProperty> = Record<strin
|
|
|
62
62
|
label: string;
|
|
63
63
|
description?: string;
|
|
64
64
|
previewImageUrl?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Editor hint: the block-picker category this block is shown under (e.g.
|
|
67
|
+
* `'Forms'`, `'Layout'`). Purely presentational — the editor groups blocks by
|
|
68
|
+
* this label; the package never acts on it. Free-form by design; for
|
|
69
|
+
* consistent, autocompleted group names across blocks, reference a shared
|
|
70
|
+
* `as const` object (e.g. `group: BLOCK_GROUPS.forms`).
|
|
71
|
+
*/
|
|
72
|
+
group?: string;
|
|
65
73
|
/** Events this (functional) block can emit — see {@link EventDeclaration}. */
|
|
66
74
|
events?: TEvents;
|
|
67
75
|
} & ({
|
|
68
76
|
allowChildren?: false;
|
|
69
77
|
} | {
|
|
70
78
|
allowChildren: true;
|
|
71
|
-
allowedChildBlocks?: string[];
|
|
72
79
|
});
|
|
73
80
|
type AnyBlockDefinition = BlockDefinition<Record<string, BlockProperty>, Record<string, EventDeclaration>>;
|
|
74
81
|
type RootDefinition<TProps extends Record<string, BlockProperty> = Record<string, BlockProperty>> = {
|
|
75
82
|
properties: TProps;
|
|
76
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* One PARENT's placement rule inside a collection's {@link CollectionStructure}
|
|
86
|
+
* — declares which child block types that parent (or the literal `'root'`) may
|
|
87
|
+
* contain. There are three mutually-exclusive modes, enforced by the type:
|
|
88
|
+
*
|
|
89
|
+
* - **open** — `{}` or `{ accepts: '*' }`: holds any block. (Same as having no
|
|
90
|
+
* entry at all; `'*'` is just an explicit, readable form.)
|
|
91
|
+
* - **whitelist** — `{ accepts: ['a', 'b'] }`: holds ONLY `a`/`b`. Fail-closed —
|
|
92
|
+
* a block added to the collection later is rejected until listed. `excludes`
|
|
93
|
+
* is forbidden here (a concrete `accepts` already says exactly what's allowed).
|
|
94
|
+
* - **blacklist** — `{ excludes: ['z'] }` (or `{ accepts: '*', excludes: ['z'] }`):
|
|
95
|
+
* holds anything EXCEPT `z`. Fail-open — a block added later is accepted.
|
|
96
|
+
*
|
|
97
|
+
* Whether a parent accepts children AT ALL is the separate, coarser
|
|
98
|
+
* `allowChildren` gate on the block (the root always accepts children); these
|
|
99
|
+
* rules only refine WHICH children an accepting parent may hold.
|
|
100
|
+
*/
|
|
101
|
+
type BlockStructureEntry<TBlockName extends string> = {
|
|
102
|
+
/** `'*'` = open base (optional, for readability). */
|
|
103
|
+
accepts?: '*';
|
|
104
|
+
/** Holds anything except these. */
|
|
105
|
+
excludes?: readonly TBlockName[];
|
|
106
|
+
} | {
|
|
107
|
+
/** Holds ONLY these block types. */
|
|
108
|
+
accepts: readonly TBlockName[];
|
|
109
|
+
/**
|
|
110
|
+
* Forbidden alongside a concrete `accepts` list — the list already names
|
|
111
|
+
* exactly what is allowed, so `excludes` would be ignored.
|
|
112
|
+
*/
|
|
113
|
+
excludes?: "Remove 'excludes': a concrete 'accepts' list already defines exactly which blocks are allowed. Use accepts: '*' with excludes for an all-except list.";
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Placement rules for a collection, keyed by PARENT block name (or the literal
|
|
117
|
+
* `'root'` for the top level). Open by default: a parent with no entry holds any
|
|
118
|
+
* block. The keys and the `accepts` / `excludes` block names autocomplete against
|
|
119
|
+
* the collection's block names and are checked at compile time by
|
|
120
|
+
* {@link defineCollection} (the field type alone enforces this — no extra step).
|
|
121
|
+
*
|
|
122
|
+
* This is the single source of truth that the visual editor (drop-zone gating)
|
|
123
|
+
* and the server guard (createBlock / moveBlock / duplicateBlock) both read,
|
|
124
|
+
* alongside each block's `allowChildren` flag, so they can never diverge.
|
|
125
|
+
*/
|
|
126
|
+
type CollectionStructure<TBlocks extends Record<string, AnyBlockDefinition>> = {
|
|
127
|
+
[K in keyof TBlocks | 'root']?: BlockStructureEntry<keyof TBlocks & string>;
|
|
128
|
+
};
|
|
77
129
|
type SlugConfig = {
|
|
78
130
|
enabled: false;
|
|
79
131
|
} | {
|
|
@@ -97,6 +149,15 @@ type CollectionDefinition<TProps extends Record<string, BlockProperty> = Record<
|
|
|
97
149
|
* regardless of this flag). Any collection can still be a reference target.
|
|
98
150
|
*/
|
|
99
151
|
reusableBlock?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Placement rules keyed by PARENT block name (or `'root'`) — which children
|
|
154
|
+
* each container may hold, via `accepts` (whitelist) / `excludes` (blacklist)
|
|
155
|
+
* (see {@link CollectionStructure}). Read by the editor and the server guard
|
|
156
|
+
* together with each block's `allowChildren` flag. Open by default; block
|
|
157
|
+
* names are checked at compile time by the field type itself, so a typo is a
|
|
158
|
+
* compile error at the `defineCollection` call site.
|
|
159
|
+
*/
|
|
160
|
+
structure?: CollectionStructure<TBlocks>;
|
|
100
161
|
};
|
|
101
162
|
type AnyCollectionDefinition = CollectionDefinition<Record<string, BlockProperty>, Record<string, AnyBlockDefinition>>;
|
|
102
163
|
type RevalidateEvent<TCollections extends Record<string, AnyCollectionDefinition> = Record<string, AnyCollectionDefinition>> = {
|
package/dist/next/index.d.ts
CHANGED
|
@@ -62,18 +62,70 @@ type BlockDefinition<TProps extends Record<string, BlockProperty> = Record<strin
|
|
|
62
62
|
label: string;
|
|
63
63
|
description?: string;
|
|
64
64
|
previewImageUrl?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Editor hint: the block-picker category this block is shown under (e.g.
|
|
67
|
+
* `'Forms'`, `'Layout'`). Purely presentational — the editor groups blocks by
|
|
68
|
+
* this label; the package never acts on it. Free-form by design; for
|
|
69
|
+
* consistent, autocompleted group names across blocks, reference a shared
|
|
70
|
+
* `as const` object (e.g. `group: BLOCK_GROUPS.forms`).
|
|
71
|
+
*/
|
|
72
|
+
group?: string;
|
|
65
73
|
/** Events this (functional) block can emit — see {@link EventDeclaration}. */
|
|
66
74
|
events?: TEvents;
|
|
67
75
|
} & ({
|
|
68
76
|
allowChildren?: false;
|
|
69
77
|
} | {
|
|
70
78
|
allowChildren: true;
|
|
71
|
-
allowedChildBlocks?: string[];
|
|
72
79
|
});
|
|
73
80
|
type AnyBlockDefinition = BlockDefinition<Record<string, BlockProperty>, Record<string, EventDeclaration>>;
|
|
74
81
|
type RootDefinition<TProps extends Record<string, BlockProperty> = Record<string, BlockProperty>> = {
|
|
75
82
|
properties: TProps;
|
|
76
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* One PARENT's placement rule inside a collection's {@link CollectionStructure}
|
|
86
|
+
* — declares which child block types that parent (or the literal `'root'`) may
|
|
87
|
+
* contain. There are three mutually-exclusive modes, enforced by the type:
|
|
88
|
+
*
|
|
89
|
+
* - **open** — `{}` or `{ accepts: '*' }`: holds any block. (Same as having no
|
|
90
|
+
* entry at all; `'*'` is just an explicit, readable form.)
|
|
91
|
+
* - **whitelist** — `{ accepts: ['a', 'b'] }`: holds ONLY `a`/`b`. Fail-closed —
|
|
92
|
+
* a block added to the collection later is rejected until listed. `excludes`
|
|
93
|
+
* is forbidden here (a concrete `accepts` already says exactly what's allowed).
|
|
94
|
+
* - **blacklist** — `{ excludes: ['z'] }` (or `{ accepts: '*', excludes: ['z'] }`):
|
|
95
|
+
* holds anything EXCEPT `z`. Fail-open — a block added later is accepted.
|
|
96
|
+
*
|
|
97
|
+
* Whether a parent accepts children AT ALL is the separate, coarser
|
|
98
|
+
* `allowChildren` gate on the block (the root always accepts children); these
|
|
99
|
+
* rules only refine WHICH children an accepting parent may hold.
|
|
100
|
+
*/
|
|
101
|
+
type BlockStructureEntry<TBlockName extends string> = {
|
|
102
|
+
/** `'*'` = open base (optional, for readability). */
|
|
103
|
+
accepts?: '*';
|
|
104
|
+
/** Holds anything except these. */
|
|
105
|
+
excludes?: readonly TBlockName[];
|
|
106
|
+
} | {
|
|
107
|
+
/** Holds ONLY these block types. */
|
|
108
|
+
accepts: readonly TBlockName[];
|
|
109
|
+
/**
|
|
110
|
+
* Forbidden alongside a concrete `accepts` list — the list already names
|
|
111
|
+
* exactly what is allowed, so `excludes` would be ignored.
|
|
112
|
+
*/
|
|
113
|
+
excludes?: "Remove 'excludes': a concrete 'accepts' list already defines exactly which blocks are allowed. Use accepts: '*' with excludes for an all-except list.";
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Placement rules for a collection, keyed by PARENT block name (or the literal
|
|
117
|
+
* `'root'` for the top level). Open by default: a parent with no entry holds any
|
|
118
|
+
* block. The keys and the `accepts` / `excludes` block names autocomplete against
|
|
119
|
+
* the collection's block names and are checked at compile time by
|
|
120
|
+
* {@link defineCollection} (the field type alone enforces this — no extra step).
|
|
121
|
+
*
|
|
122
|
+
* This is the single source of truth that the visual editor (drop-zone gating)
|
|
123
|
+
* and the server guard (createBlock / moveBlock / duplicateBlock) both read,
|
|
124
|
+
* alongside each block's `allowChildren` flag, so they can never diverge.
|
|
125
|
+
*/
|
|
126
|
+
type CollectionStructure<TBlocks extends Record<string, AnyBlockDefinition>> = {
|
|
127
|
+
[K in keyof TBlocks | 'root']?: BlockStructureEntry<keyof TBlocks & string>;
|
|
128
|
+
};
|
|
77
129
|
type SlugConfig = {
|
|
78
130
|
enabled: false;
|
|
79
131
|
} | {
|
|
@@ -97,6 +149,15 @@ type CollectionDefinition<TProps extends Record<string, BlockProperty> = Record<
|
|
|
97
149
|
* regardless of this flag). Any collection can still be a reference target.
|
|
98
150
|
*/
|
|
99
151
|
reusableBlock?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Placement rules keyed by PARENT block name (or `'root'`) — which children
|
|
154
|
+
* each container may hold, via `accepts` (whitelist) / `excludes` (blacklist)
|
|
155
|
+
* (see {@link CollectionStructure}). Read by the editor and the server guard
|
|
156
|
+
* together with each block's `allowChildren` flag. Open by default; block
|
|
157
|
+
* names are checked at compile time by the field type itself, so a typo is a
|
|
158
|
+
* compile error at the `defineCollection` call site.
|
|
159
|
+
*/
|
|
160
|
+
structure?: CollectionStructure<TBlocks>;
|
|
100
161
|
};
|
|
101
162
|
type AnyCollectionDefinition = CollectionDefinition<Record<string, BlockProperty>, Record<string, AnyBlockDefinition>>;
|
|
102
163
|
type RevalidateEvent<TCollections extends Record<string, AnyCollectionDefinition> = Record<string, AnyCollectionDefinition>> = {
|
|
@@ -2455,6 +2455,10 @@ const CMS_ERRORS = {
|
|
|
2455
2455
|
status: 404,
|
|
2456
2456
|
message: 'Parent block not found'
|
|
2457
2457
|
},
|
|
2458
|
+
BLOCK_NOT_ALLOWED_IN_PARENT: {
|
|
2459
|
+
status: 400,
|
|
2460
|
+
message: 'This block type is not allowed inside the target parent'
|
|
2461
|
+
},
|
|
2458
2462
|
ROOT_NOT_FOUND: {
|
|
2459
2463
|
status: 404,
|
|
2460
2464
|
message: 'Root block not found in snapshot'
|
|
@@ -323,18 +323,70 @@ type BlockDefinition<TProps extends Record<string, BlockProperty> = Record<strin
|
|
|
323
323
|
label: string;
|
|
324
324
|
description?: string;
|
|
325
325
|
previewImageUrl?: string;
|
|
326
|
+
/**
|
|
327
|
+
* Editor hint: the block-picker category this block is shown under (e.g.
|
|
328
|
+
* `'Forms'`, `'Layout'`). Purely presentational — the editor groups blocks by
|
|
329
|
+
* this label; the package never acts on it. Free-form by design; for
|
|
330
|
+
* consistent, autocompleted group names across blocks, reference a shared
|
|
331
|
+
* `as const` object (e.g. `group: BLOCK_GROUPS.forms`).
|
|
332
|
+
*/
|
|
333
|
+
group?: string;
|
|
326
334
|
/** Events this (functional) block can emit — see {@link EventDeclaration}. */
|
|
327
335
|
events?: TEvents;
|
|
328
336
|
} & ({
|
|
329
337
|
allowChildren?: false;
|
|
330
338
|
} | {
|
|
331
339
|
allowChildren: true;
|
|
332
|
-
allowedChildBlocks?: string[];
|
|
333
340
|
});
|
|
334
341
|
type AnyBlockDefinition = BlockDefinition<Record<string, BlockProperty>, Record<string, EventDeclaration>>;
|
|
335
342
|
type RootDefinition<TProps extends Record<string, BlockProperty> = Record<string, BlockProperty>> = {
|
|
336
343
|
properties: TProps;
|
|
337
344
|
};
|
|
345
|
+
/**
|
|
346
|
+
* One PARENT's placement rule inside a collection's {@link CollectionStructure}
|
|
347
|
+
* — declares which child block types that parent (or the literal `'root'`) may
|
|
348
|
+
* contain. There are three mutually-exclusive modes, enforced by the type:
|
|
349
|
+
*
|
|
350
|
+
* - **open** — `{}` or `{ accepts: '*' }`: holds any block. (Same as having no
|
|
351
|
+
* entry at all; `'*'` is just an explicit, readable form.)
|
|
352
|
+
* - **whitelist** — `{ accepts: ['a', 'b'] }`: holds ONLY `a`/`b`. Fail-closed —
|
|
353
|
+
* a block added to the collection later is rejected until listed. `excludes`
|
|
354
|
+
* is forbidden here (a concrete `accepts` already says exactly what's allowed).
|
|
355
|
+
* - **blacklist** — `{ excludes: ['z'] }` (or `{ accepts: '*', excludes: ['z'] }`):
|
|
356
|
+
* holds anything EXCEPT `z`. Fail-open — a block added later is accepted.
|
|
357
|
+
*
|
|
358
|
+
* Whether a parent accepts children AT ALL is the separate, coarser
|
|
359
|
+
* `allowChildren` gate on the block (the root always accepts children); these
|
|
360
|
+
* rules only refine WHICH children an accepting parent may hold.
|
|
361
|
+
*/
|
|
362
|
+
type BlockStructureEntry<TBlockName extends string> = {
|
|
363
|
+
/** `'*'` = open base (optional, for readability). */
|
|
364
|
+
accepts?: '*';
|
|
365
|
+
/** Holds anything except these. */
|
|
366
|
+
excludes?: readonly TBlockName[];
|
|
367
|
+
} | {
|
|
368
|
+
/** Holds ONLY these block types. */
|
|
369
|
+
accepts: readonly TBlockName[];
|
|
370
|
+
/**
|
|
371
|
+
* Forbidden alongside a concrete `accepts` list — the list already names
|
|
372
|
+
* exactly what is allowed, so `excludes` would be ignored.
|
|
373
|
+
*/
|
|
374
|
+
excludes?: "Remove 'excludes': a concrete 'accepts' list already defines exactly which blocks are allowed. Use accepts: '*' with excludes for an all-except list.";
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* Placement rules for a collection, keyed by PARENT block name (or the literal
|
|
378
|
+
* `'root'` for the top level). Open by default: a parent with no entry holds any
|
|
379
|
+
* block. The keys and the `accepts` / `excludes` block names autocomplete against
|
|
380
|
+
* the collection's block names and are checked at compile time by
|
|
381
|
+
* {@link defineCollection} (the field type alone enforces this — no extra step).
|
|
382
|
+
*
|
|
383
|
+
* This is the single source of truth that the visual editor (drop-zone gating)
|
|
384
|
+
* and the server guard (createBlock / moveBlock / duplicateBlock) both read,
|
|
385
|
+
* alongside each block's `allowChildren` flag, so they can never diverge.
|
|
386
|
+
*/
|
|
387
|
+
type CollectionStructure<TBlocks extends Record<string, AnyBlockDefinition>> = {
|
|
388
|
+
[K in keyof TBlocks | 'root']?: BlockStructureEntry<keyof TBlocks & string>;
|
|
389
|
+
};
|
|
338
390
|
type SlugConfig = {
|
|
339
391
|
enabled: false;
|
|
340
392
|
} | {
|
|
@@ -358,6 +410,15 @@ type CollectionDefinition<TProps extends Record<string, BlockProperty> = Record<
|
|
|
358
410
|
* regardless of this flag). Any collection can still be a reference target.
|
|
359
411
|
*/
|
|
360
412
|
reusableBlock?: boolean;
|
|
413
|
+
/**
|
|
414
|
+
* Placement rules keyed by PARENT block name (or `'root'`) — which children
|
|
415
|
+
* each container may hold, via `accepts` (whitelist) / `excludes` (blacklist)
|
|
416
|
+
* (see {@link CollectionStructure}). Read by the editor and the server guard
|
|
417
|
+
* together with each block's `allowChildren` flag. Open by default; block
|
|
418
|
+
* names are checked at compile time by the field type itself, so a typo is a
|
|
419
|
+
* compile error at the `defineCollection` call site.
|
|
420
|
+
*/
|
|
421
|
+
structure?: CollectionStructure<TBlocks>;
|
|
361
422
|
};
|
|
362
423
|
type AnyCollectionDefinition = CollectionDefinition<Record<string, BlockProperty>, Record<string, AnyBlockDefinition>>;
|
|
363
424
|
type CollectionWithName = Omit<AnyCollectionDefinition, 'blocks'> & {
|
|
@@ -323,18 +323,70 @@ type BlockDefinition<TProps extends Record<string, BlockProperty> = Record<strin
|
|
|
323
323
|
label: string;
|
|
324
324
|
description?: string;
|
|
325
325
|
previewImageUrl?: string;
|
|
326
|
+
/**
|
|
327
|
+
* Editor hint: the block-picker category this block is shown under (e.g.
|
|
328
|
+
* `'Forms'`, `'Layout'`). Purely presentational — the editor groups blocks by
|
|
329
|
+
* this label; the package never acts on it. Free-form by design; for
|
|
330
|
+
* consistent, autocompleted group names across blocks, reference a shared
|
|
331
|
+
* `as const` object (e.g. `group: BLOCK_GROUPS.forms`).
|
|
332
|
+
*/
|
|
333
|
+
group?: string;
|
|
326
334
|
/** Events this (functional) block can emit — see {@link EventDeclaration}. */
|
|
327
335
|
events?: TEvents;
|
|
328
336
|
} & ({
|
|
329
337
|
allowChildren?: false;
|
|
330
338
|
} | {
|
|
331
339
|
allowChildren: true;
|
|
332
|
-
allowedChildBlocks?: string[];
|
|
333
340
|
});
|
|
334
341
|
type AnyBlockDefinition = BlockDefinition<Record<string, BlockProperty>, Record<string, EventDeclaration>>;
|
|
335
342
|
type RootDefinition<TProps extends Record<string, BlockProperty> = Record<string, BlockProperty>> = {
|
|
336
343
|
properties: TProps;
|
|
337
344
|
};
|
|
345
|
+
/**
|
|
346
|
+
* One PARENT's placement rule inside a collection's {@link CollectionStructure}
|
|
347
|
+
* — declares which child block types that parent (or the literal `'root'`) may
|
|
348
|
+
* contain. There are three mutually-exclusive modes, enforced by the type:
|
|
349
|
+
*
|
|
350
|
+
* - **open** — `{}` or `{ accepts: '*' }`: holds any block. (Same as having no
|
|
351
|
+
* entry at all; `'*'` is just an explicit, readable form.)
|
|
352
|
+
* - **whitelist** — `{ accepts: ['a', 'b'] }`: holds ONLY `a`/`b`. Fail-closed —
|
|
353
|
+
* a block added to the collection later is rejected until listed. `excludes`
|
|
354
|
+
* is forbidden here (a concrete `accepts` already says exactly what's allowed).
|
|
355
|
+
* - **blacklist** — `{ excludes: ['z'] }` (or `{ accepts: '*', excludes: ['z'] }`):
|
|
356
|
+
* holds anything EXCEPT `z`. Fail-open — a block added later is accepted.
|
|
357
|
+
*
|
|
358
|
+
* Whether a parent accepts children AT ALL is the separate, coarser
|
|
359
|
+
* `allowChildren` gate on the block (the root always accepts children); these
|
|
360
|
+
* rules only refine WHICH children an accepting parent may hold.
|
|
361
|
+
*/
|
|
362
|
+
type BlockStructureEntry<TBlockName extends string> = {
|
|
363
|
+
/** `'*'` = open base (optional, for readability). */
|
|
364
|
+
accepts?: '*';
|
|
365
|
+
/** Holds anything except these. */
|
|
366
|
+
excludes?: readonly TBlockName[];
|
|
367
|
+
} | {
|
|
368
|
+
/** Holds ONLY these block types. */
|
|
369
|
+
accepts: readonly TBlockName[];
|
|
370
|
+
/**
|
|
371
|
+
* Forbidden alongside a concrete `accepts` list — the list already names
|
|
372
|
+
* exactly what is allowed, so `excludes` would be ignored.
|
|
373
|
+
*/
|
|
374
|
+
excludes?: "Remove 'excludes': a concrete 'accepts' list already defines exactly which blocks are allowed. Use accepts: '*' with excludes for an all-except list.";
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* Placement rules for a collection, keyed by PARENT block name (or the literal
|
|
378
|
+
* `'root'` for the top level). Open by default: a parent with no entry holds any
|
|
379
|
+
* block. The keys and the `accepts` / `excludes` block names autocomplete against
|
|
380
|
+
* the collection's block names and are checked at compile time by
|
|
381
|
+
* {@link defineCollection} (the field type alone enforces this — no extra step).
|
|
382
|
+
*
|
|
383
|
+
* This is the single source of truth that the visual editor (drop-zone gating)
|
|
384
|
+
* and the server guard (createBlock / moveBlock / duplicateBlock) both read,
|
|
385
|
+
* alongside each block's `allowChildren` flag, so they can never diverge.
|
|
386
|
+
*/
|
|
387
|
+
type CollectionStructure<TBlocks extends Record<string, AnyBlockDefinition>> = {
|
|
388
|
+
[K in keyof TBlocks | 'root']?: BlockStructureEntry<keyof TBlocks & string>;
|
|
389
|
+
};
|
|
338
390
|
type SlugConfig = {
|
|
339
391
|
enabled: false;
|
|
340
392
|
} | {
|
|
@@ -358,6 +410,15 @@ type CollectionDefinition<TProps extends Record<string, BlockProperty> = Record<
|
|
|
358
410
|
* regardless of this flag). Any collection can still be a reference target.
|
|
359
411
|
*/
|
|
360
412
|
reusableBlock?: boolean;
|
|
413
|
+
/**
|
|
414
|
+
* Placement rules keyed by PARENT block name (or `'root'`) — which children
|
|
415
|
+
* each container may hold, via `accepts` (whitelist) / `excludes` (blacklist)
|
|
416
|
+
* (see {@link CollectionStructure}). Read by the editor and the server guard
|
|
417
|
+
* together with each block's `allowChildren` flag. Open by default; block
|
|
418
|
+
* names are checked at compile time by the field type itself, so a typo is a
|
|
419
|
+
* compile error at the `defineCollection` call site.
|
|
420
|
+
*/
|
|
421
|
+
structure?: CollectionStructure<TBlocks>;
|
|
361
422
|
};
|
|
362
423
|
type AnyCollectionDefinition = CollectionDefinition<Record<string, BlockProperty>, Record<string, AnyBlockDefinition>>;
|
|
363
424
|
type CollectionWithName = Omit<AnyCollectionDefinition, 'blocks'> & {
|
|
@@ -2430,6 +2430,10 @@ const CMS_ERRORS = {
|
|
|
2430
2430
|
status: 404,
|
|
2431
2431
|
message: 'Parent block not found'
|
|
2432
2432
|
},
|
|
2433
|
+
BLOCK_NOT_ALLOWED_IN_PARENT: {
|
|
2434
|
+
status: 400,
|
|
2435
|
+
message: 'This block type is not allowed inside the target parent'
|
|
2436
|
+
},
|
|
2433
2437
|
ROOT_NOT_FOUND: {
|
|
2434
2438
|
status: 404,
|
|
2435
2439
|
message: 'Root block not found in snapshot'
|
|
@@ -226,18 +226,70 @@ type BlockDefinition<TProps extends Record<string, BlockProperty> = Record<strin
|
|
|
226
226
|
label: string;
|
|
227
227
|
description?: string;
|
|
228
228
|
previewImageUrl?: string;
|
|
229
|
+
/**
|
|
230
|
+
* Editor hint: the block-picker category this block is shown under (e.g.
|
|
231
|
+
* `'Forms'`, `'Layout'`). Purely presentational — the editor groups blocks by
|
|
232
|
+
* this label; the package never acts on it. Free-form by design; for
|
|
233
|
+
* consistent, autocompleted group names across blocks, reference a shared
|
|
234
|
+
* `as const` object (e.g. `group: BLOCK_GROUPS.forms`).
|
|
235
|
+
*/
|
|
236
|
+
group?: string;
|
|
229
237
|
/** Events this (functional) block can emit — see {@link EventDeclaration}. */
|
|
230
238
|
events?: TEvents;
|
|
231
239
|
} & ({
|
|
232
240
|
allowChildren?: false;
|
|
233
241
|
} | {
|
|
234
242
|
allowChildren: true;
|
|
235
|
-
allowedChildBlocks?: string[];
|
|
236
243
|
});
|
|
237
244
|
type AnyBlockDefinition = BlockDefinition<Record<string, BlockProperty>, Record<string, EventDeclaration>>;
|
|
238
245
|
type RootDefinition<TProps extends Record<string, BlockProperty> = Record<string, BlockProperty>> = {
|
|
239
246
|
properties: TProps;
|
|
240
247
|
};
|
|
248
|
+
/**
|
|
249
|
+
* One PARENT's placement rule inside a collection's {@link CollectionStructure}
|
|
250
|
+
* — declares which child block types that parent (or the literal `'root'`) may
|
|
251
|
+
* contain. There are three mutually-exclusive modes, enforced by the type:
|
|
252
|
+
*
|
|
253
|
+
* - **open** — `{}` or `{ accepts: '*' }`: holds any block. (Same as having no
|
|
254
|
+
* entry at all; `'*'` is just an explicit, readable form.)
|
|
255
|
+
* - **whitelist** — `{ accepts: ['a', 'b'] }`: holds ONLY `a`/`b`. Fail-closed —
|
|
256
|
+
* a block added to the collection later is rejected until listed. `excludes`
|
|
257
|
+
* is forbidden here (a concrete `accepts` already says exactly what's allowed).
|
|
258
|
+
* - **blacklist** — `{ excludes: ['z'] }` (or `{ accepts: '*', excludes: ['z'] }`):
|
|
259
|
+
* holds anything EXCEPT `z`. Fail-open — a block added later is accepted.
|
|
260
|
+
*
|
|
261
|
+
* Whether a parent accepts children AT ALL is the separate, coarser
|
|
262
|
+
* `allowChildren` gate on the block (the root always accepts children); these
|
|
263
|
+
* rules only refine WHICH children an accepting parent may hold.
|
|
264
|
+
*/
|
|
265
|
+
type BlockStructureEntry<TBlockName extends string> = {
|
|
266
|
+
/** `'*'` = open base (optional, for readability). */
|
|
267
|
+
accepts?: '*';
|
|
268
|
+
/** Holds anything except these. */
|
|
269
|
+
excludes?: readonly TBlockName[];
|
|
270
|
+
} | {
|
|
271
|
+
/** Holds ONLY these block types. */
|
|
272
|
+
accepts: readonly TBlockName[];
|
|
273
|
+
/**
|
|
274
|
+
* Forbidden alongside a concrete `accepts` list — the list already names
|
|
275
|
+
* exactly what is allowed, so `excludes` would be ignored.
|
|
276
|
+
*/
|
|
277
|
+
excludes?: "Remove 'excludes': a concrete 'accepts' list already defines exactly which blocks are allowed. Use accepts: '*' with excludes for an all-except list.";
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Placement rules for a collection, keyed by PARENT block name (or the literal
|
|
281
|
+
* `'root'` for the top level). Open by default: a parent with no entry holds any
|
|
282
|
+
* block. The keys and the `accepts` / `excludes` block names autocomplete against
|
|
283
|
+
* the collection's block names and are checked at compile time by
|
|
284
|
+
* {@link defineCollection} (the field type alone enforces this — no extra step).
|
|
285
|
+
*
|
|
286
|
+
* This is the single source of truth that the visual editor (drop-zone gating)
|
|
287
|
+
* and the server guard (createBlock / moveBlock / duplicateBlock) both read,
|
|
288
|
+
* alongside each block's `allowChildren` flag, so they can never diverge.
|
|
289
|
+
*/
|
|
290
|
+
type CollectionStructure<TBlocks extends Record<string, AnyBlockDefinition>> = {
|
|
291
|
+
[K in keyof TBlocks | 'root']?: BlockStructureEntry<keyof TBlocks & string>;
|
|
292
|
+
};
|
|
241
293
|
type SlugConfig = {
|
|
242
294
|
enabled: false;
|
|
243
295
|
} | {
|
|
@@ -261,6 +313,15 @@ type CollectionDefinition<TProps extends Record<string, BlockProperty> = Record<
|
|
|
261
313
|
* regardless of this flag). Any collection can still be a reference target.
|
|
262
314
|
*/
|
|
263
315
|
reusableBlock?: boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Placement rules keyed by PARENT block name (or `'root'`) — which children
|
|
318
|
+
* each container may hold, via `accepts` (whitelist) / `excludes` (blacklist)
|
|
319
|
+
* (see {@link CollectionStructure}). Read by the editor and the server guard
|
|
320
|
+
* together with each block's `allowChildren` flag. Open by default; block
|
|
321
|
+
* names are checked at compile time by the field type itself, so a typo is a
|
|
322
|
+
* compile error at the `defineCollection` call site.
|
|
323
|
+
*/
|
|
324
|
+
structure?: CollectionStructure<TBlocks>;
|
|
264
325
|
};
|
|
265
326
|
type AnyCollectionDefinition = CollectionDefinition<Record<string, BlockProperty>, Record<string, AnyBlockDefinition>>;
|
|
266
327
|
type CollectionWithName = Omit<AnyCollectionDefinition, 'blocks'> & {
|
|
@@ -226,18 +226,70 @@ type BlockDefinition<TProps extends Record<string, BlockProperty> = Record<strin
|
|
|
226
226
|
label: string;
|
|
227
227
|
description?: string;
|
|
228
228
|
previewImageUrl?: string;
|
|
229
|
+
/**
|
|
230
|
+
* Editor hint: the block-picker category this block is shown under (e.g.
|
|
231
|
+
* `'Forms'`, `'Layout'`). Purely presentational — the editor groups blocks by
|
|
232
|
+
* this label; the package never acts on it. Free-form by design; for
|
|
233
|
+
* consistent, autocompleted group names across blocks, reference a shared
|
|
234
|
+
* `as const` object (e.g. `group: BLOCK_GROUPS.forms`).
|
|
235
|
+
*/
|
|
236
|
+
group?: string;
|
|
229
237
|
/** Events this (functional) block can emit — see {@link EventDeclaration}. */
|
|
230
238
|
events?: TEvents;
|
|
231
239
|
} & ({
|
|
232
240
|
allowChildren?: false;
|
|
233
241
|
} | {
|
|
234
242
|
allowChildren: true;
|
|
235
|
-
allowedChildBlocks?: string[];
|
|
236
243
|
});
|
|
237
244
|
type AnyBlockDefinition = BlockDefinition<Record<string, BlockProperty>, Record<string, EventDeclaration>>;
|
|
238
245
|
type RootDefinition<TProps extends Record<string, BlockProperty> = Record<string, BlockProperty>> = {
|
|
239
246
|
properties: TProps;
|
|
240
247
|
};
|
|
248
|
+
/**
|
|
249
|
+
* One PARENT's placement rule inside a collection's {@link CollectionStructure}
|
|
250
|
+
* — declares which child block types that parent (or the literal `'root'`) may
|
|
251
|
+
* contain. There are three mutually-exclusive modes, enforced by the type:
|
|
252
|
+
*
|
|
253
|
+
* - **open** — `{}` or `{ accepts: '*' }`: holds any block. (Same as having no
|
|
254
|
+
* entry at all; `'*'` is just an explicit, readable form.)
|
|
255
|
+
* - **whitelist** — `{ accepts: ['a', 'b'] }`: holds ONLY `a`/`b`. Fail-closed —
|
|
256
|
+
* a block added to the collection later is rejected until listed. `excludes`
|
|
257
|
+
* is forbidden here (a concrete `accepts` already says exactly what's allowed).
|
|
258
|
+
* - **blacklist** — `{ excludes: ['z'] }` (or `{ accepts: '*', excludes: ['z'] }`):
|
|
259
|
+
* holds anything EXCEPT `z`. Fail-open — a block added later is accepted.
|
|
260
|
+
*
|
|
261
|
+
* Whether a parent accepts children AT ALL is the separate, coarser
|
|
262
|
+
* `allowChildren` gate on the block (the root always accepts children); these
|
|
263
|
+
* rules only refine WHICH children an accepting parent may hold.
|
|
264
|
+
*/
|
|
265
|
+
type BlockStructureEntry<TBlockName extends string> = {
|
|
266
|
+
/** `'*'` = open base (optional, for readability). */
|
|
267
|
+
accepts?: '*';
|
|
268
|
+
/** Holds anything except these. */
|
|
269
|
+
excludes?: readonly TBlockName[];
|
|
270
|
+
} | {
|
|
271
|
+
/** Holds ONLY these block types. */
|
|
272
|
+
accepts: readonly TBlockName[];
|
|
273
|
+
/**
|
|
274
|
+
* Forbidden alongside a concrete `accepts` list — the list already names
|
|
275
|
+
* exactly what is allowed, so `excludes` would be ignored.
|
|
276
|
+
*/
|
|
277
|
+
excludes?: "Remove 'excludes': a concrete 'accepts' list already defines exactly which blocks are allowed. Use accepts: '*' with excludes for an all-except list.";
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Placement rules for a collection, keyed by PARENT block name (or the literal
|
|
281
|
+
* `'root'` for the top level). Open by default: a parent with no entry holds any
|
|
282
|
+
* block. The keys and the `accepts` / `excludes` block names autocomplete against
|
|
283
|
+
* the collection's block names and are checked at compile time by
|
|
284
|
+
* {@link defineCollection} (the field type alone enforces this — no extra step).
|
|
285
|
+
*
|
|
286
|
+
* This is the single source of truth that the visual editor (drop-zone gating)
|
|
287
|
+
* and the server guard (createBlock / moveBlock / duplicateBlock) both read,
|
|
288
|
+
* alongside each block's `allowChildren` flag, so they can never diverge.
|
|
289
|
+
*/
|
|
290
|
+
type CollectionStructure<TBlocks extends Record<string, AnyBlockDefinition>> = {
|
|
291
|
+
[K in keyof TBlocks | 'root']?: BlockStructureEntry<keyof TBlocks & string>;
|
|
292
|
+
};
|
|
241
293
|
type SlugConfig = {
|
|
242
294
|
enabled: false;
|
|
243
295
|
} | {
|
|
@@ -261,6 +313,15 @@ type CollectionDefinition<TProps extends Record<string, BlockProperty> = Record<
|
|
|
261
313
|
* regardless of this flag). Any collection can still be a reference target.
|
|
262
314
|
*/
|
|
263
315
|
reusableBlock?: boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Placement rules keyed by PARENT block name (or `'root'`) — which children
|
|
318
|
+
* each container may hold, via `accepts` (whitelist) / `excludes` (blacklist)
|
|
319
|
+
* (see {@link CollectionStructure}). Read by the editor and the server guard
|
|
320
|
+
* together with each block's `allowChildren` flag. Open by default; block
|
|
321
|
+
* names are checked at compile time by the field type itself, so a typo is a
|
|
322
|
+
* compile error at the `defineCollection` call site.
|
|
323
|
+
*/
|
|
324
|
+
structure?: CollectionStructure<TBlocks>;
|
|
264
325
|
};
|
|
265
326
|
type AnyCollectionDefinition = CollectionDefinition<Record<string, BlockProperty>, Record<string, AnyBlockDefinition>>;
|
|
266
327
|
type CollectionWithName = Omit<AnyCollectionDefinition, 'blocks'> & {
|
|
@@ -950,6 +950,10 @@ const CMS_ERRORS = {
|
|
|
950
950
|
status: 404,
|
|
951
951
|
message: 'Parent block not found'
|
|
952
952
|
},
|
|
953
|
+
BLOCK_NOT_ALLOWED_IN_PARENT: {
|
|
954
|
+
status: 400,
|
|
955
|
+
message: 'This block type is not allowed inside the target parent'
|
|
956
|
+
},
|
|
953
957
|
ROOT_NOT_FOUND: {
|
|
954
958
|
status: 404,
|
|
955
959
|
message: 'Root block not found in snapshot'
|
|
@@ -227,18 +227,70 @@ type BlockDefinition<TProps extends Record<string, BlockProperty> = Record<strin
|
|
|
227
227
|
label: string;
|
|
228
228
|
description?: string;
|
|
229
229
|
previewImageUrl?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Editor hint: the block-picker category this block is shown under (e.g.
|
|
232
|
+
* `'Forms'`, `'Layout'`). Purely presentational — the editor groups blocks by
|
|
233
|
+
* this label; the package never acts on it. Free-form by design; for
|
|
234
|
+
* consistent, autocompleted group names across blocks, reference a shared
|
|
235
|
+
* `as const` object (e.g. `group: BLOCK_GROUPS.forms`).
|
|
236
|
+
*/
|
|
237
|
+
group?: string;
|
|
230
238
|
/** Events this (functional) block can emit — see {@link EventDeclaration}. */
|
|
231
239
|
events?: TEvents;
|
|
232
240
|
} & ({
|
|
233
241
|
allowChildren?: false;
|
|
234
242
|
} | {
|
|
235
243
|
allowChildren: true;
|
|
236
|
-
allowedChildBlocks?: string[];
|
|
237
244
|
});
|
|
238
245
|
type AnyBlockDefinition = BlockDefinition<Record<string, BlockProperty>, Record<string, EventDeclaration>>;
|
|
239
246
|
type RootDefinition<TProps extends Record<string, BlockProperty> = Record<string, BlockProperty>> = {
|
|
240
247
|
properties: TProps;
|
|
241
248
|
};
|
|
249
|
+
/**
|
|
250
|
+
* One PARENT's placement rule inside a collection's {@link CollectionStructure}
|
|
251
|
+
* — declares which child block types that parent (or the literal `'root'`) may
|
|
252
|
+
* contain. There are three mutually-exclusive modes, enforced by the type:
|
|
253
|
+
*
|
|
254
|
+
* - **open** — `{}` or `{ accepts: '*' }`: holds any block. (Same as having no
|
|
255
|
+
* entry at all; `'*'` is just an explicit, readable form.)
|
|
256
|
+
* - **whitelist** — `{ accepts: ['a', 'b'] }`: holds ONLY `a`/`b`. Fail-closed —
|
|
257
|
+
* a block added to the collection later is rejected until listed. `excludes`
|
|
258
|
+
* is forbidden here (a concrete `accepts` already says exactly what's allowed).
|
|
259
|
+
* - **blacklist** — `{ excludes: ['z'] }` (or `{ accepts: '*', excludes: ['z'] }`):
|
|
260
|
+
* holds anything EXCEPT `z`. Fail-open — a block added later is accepted.
|
|
261
|
+
*
|
|
262
|
+
* Whether a parent accepts children AT ALL is the separate, coarser
|
|
263
|
+
* `allowChildren` gate on the block (the root always accepts children); these
|
|
264
|
+
* rules only refine WHICH children an accepting parent may hold.
|
|
265
|
+
*/
|
|
266
|
+
type BlockStructureEntry<TBlockName extends string> = {
|
|
267
|
+
/** `'*'` = open base (optional, for readability). */
|
|
268
|
+
accepts?: '*';
|
|
269
|
+
/** Holds anything except these. */
|
|
270
|
+
excludes?: readonly TBlockName[];
|
|
271
|
+
} | {
|
|
272
|
+
/** Holds ONLY these block types. */
|
|
273
|
+
accepts: readonly TBlockName[];
|
|
274
|
+
/**
|
|
275
|
+
* Forbidden alongside a concrete `accepts` list — the list already names
|
|
276
|
+
* exactly what is allowed, so `excludes` would be ignored.
|
|
277
|
+
*/
|
|
278
|
+
excludes?: "Remove 'excludes': a concrete 'accepts' list already defines exactly which blocks are allowed. Use accepts: '*' with excludes for an all-except list.";
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* Placement rules for a collection, keyed by PARENT block name (or the literal
|
|
282
|
+
* `'root'` for the top level). Open by default: a parent with no entry holds any
|
|
283
|
+
* block. The keys and the `accepts` / `excludes` block names autocomplete against
|
|
284
|
+
* the collection's block names and are checked at compile time by
|
|
285
|
+
* {@link defineCollection} (the field type alone enforces this — no extra step).
|
|
286
|
+
*
|
|
287
|
+
* This is the single source of truth that the visual editor (drop-zone gating)
|
|
288
|
+
* and the server guard (createBlock / moveBlock / duplicateBlock) both read,
|
|
289
|
+
* alongside each block's `allowChildren` flag, so they can never diverge.
|
|
290
|
+
*/
|
|
291
|
+
type CollectionStructure<TBlocks extends Record<string, AnyBlockDefinition>> = {
|
|
292
|
+
[K in keyof TBlocks | 'root']?: BlockStructureEntry<keyof TBlocks & string>;
|
|
293
|
+
};
|
|
242
294
|
type SlugConfig = {
|
|
243
295
|
enabled: false;
|
|
244
296
|
} | {
|
|
@@ -262,6 +314,15 @@ type CollectionDefinition<TProps extends Record<string, BlockProperty> = Record<
|
|
|
262
314
|
* regardless of this flag). Any collection can still be a reference target.
|
|
263
315
|
*/
|
|
264
316
|
reusableBlock?: boolean;
|
|
317
|
+
/**
|
|
318
|
+
* Placement rules keyed by PARENT block name (or `'root'`) — which children
|
|
319
|
+
* each container may hold, via `accepts` (whitelist) / `excludes` (blacklist)
|
|
320
|
+
* (see {@link CollectionStructure}). Read by the editor and the server guard
|
|
321
|
+
* together with each block's `allowChildren` flag. Open by default; block
|
|
322
|
+
* names are checked at compile time by the field type itself, so a typo is a
|
|
323
|
+
* compile error at the `defineCollection` call site.
|
|
324
|
+
*/
|
|
325
|
+
structure?: CollectionStructure<TBlocks>;
|
|
265
326
|
};
|
|
266
327
|
type AnyCollectionDefinition = CollectionDefinition<Record<string, BlockProperty>, Record<string, AnyBlockDefinition>>;
|
|
267
328
|
type CollectionWithName = Omit<AnyCollectionDefinition, 'blocks'> & {
|