@actuate-media/cms-core 0.26.0 → 0.27.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.
Files changed (40) hide show
  1. package/dist/__tests__/api/collections-discovery.test.js +47 -0
  2. package/dist/__tests__/api/collections-discovery.test.js.map +1 -1
  3. package/dist/__tests__/api/page-sections-routes.test.d.ts +2 -0
  4. package/dist/__tests__/api/page-sections-routes.test.d.ts.map +1 -0
  5. package/dist/__tests__/api/page-sections-routes.test.js +271 -0
  6. package/dist/__tests__/api/page-sections-routes.test.js.map +1 -0
  7. package/dist/__tests__/api/stats-collection-filter.test.d.ts +2 -0
  8. package/dist/__tests__/api/stats-collection-filter.test.d.ts.map +1 -0
  9. package/dist/__tests__/api/stats-collection-filter.test.js +190 -0
  10. package/dist/__tests__/api/stats-collection-filter.test.js.map +1 -0
  11. package/dist/api/handlers.d.ts.map +1 -1
  12. package/dist/api/handlers.js +415 -5
  13. package/dist/api/handlers.js.map +1 -1
  14. package/dist/config/types.d.ts +8 -0
  15. package/dist/config/types.d.ts.map +1 -1
  16. package/dist/sections/__tests__/sections.test.d.ts +2 -0
  17. package/dist/sections/__tests__/sections.test.d.ts.map +1 -0
  18. package/dist/sections/__tests__/sections.test.js +215 -0
  19. package/dist/sections/__tests__/sections.test.js.map +1 -0
  20. package/dist/sections/helpers.d.ts +62 -0
  21. package/dist/sections/helpers.d.ts.map +1 -0
  22. package/dist/sections/helpers.js +202 -0
  23. package/dist/sections/helpers.js.map +1 -0
  24. package/dist/sections/index.d.ts +13 -0
  25. package/dist/sections/index.d.ts.map +1 -0
  26. package/dist/sections/index.js +12 -0
  27. package/dist/sections/index.js.map +1 -0
  28. package/dist/sections/registry.d.ts +27 -0
  29. package/dist/sections/registry.d.ts.map +1 -0
  30. package/dist/sections/registry.js +349 -0
  31. package/dist/sections/registry.js.map +1 -0
  32. package/dist/sections/types.d.ts +127 -0
  33. package/dist/sections/types.d.ts.map +1 -0
  34. package/dist/sections/types.js +21 -0
  35. package/dist/sections/types.js.map +1 -0
  36. package/dist/sections/validate.d.ts +10 -0
  37. package/dist/sections/validate.d.ts.map +1 -0
  38. package/dist/sections/validate.js +92 -0
  39. package/dist/sections/validate.js.map +1 -0
  40. package/package.json +6 -1
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Flat, section-based Page Editor model — shared across the admin editor,
3
+ * the REST API, and the MCP server.
4
+ *
5
+ * Exposed as the `@actuate-media/cms-core/page-sections` subpath (NOT the
6
+ * package root) to avoid colliding with the page-builder *tree* model,
7
+ * which already exports `SectionSettings` / `createSection` from the root.
8
+ */
9
+ export { SECTION_TYPES, SECTION_TYPE_LIST, getSectionType, getSectionTypesForScope, sectionTypeLabel, isKnownSectionType, } from './registry.js';
10
+ export { generateSectionId, createSection, buildSection, addSection, removeSection, duplicateSection, toggleSectionVisibility, setSectionVisibility, moveSection, reorderSections, updateSectionContent, updateSectionSettings, updateSectionMeta, coerceSections, defaultPostHeader, coercePostHeader, createPostTemplate, coercePostTemplate, } from './helpers.js';
11
+ export { validateSectionContent } from './validate.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sections/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Section-type registry — the single source of truth for the flat Page
3
+ * Editor model. The admin editor re-exports this; the REST API and MCP
4
+ * server read it for discovery + validation.
5
+ *
6
+ * Only types listed here can be added/created, so neither the Add Section
7
+ * gallery nor an AI agent can produce a section without a working renderer
8
+ * + inspector + schema ("no dead sections").
9
+ */
10
+ import type { SectionScope, SectionTypeDef, SectionTypeId } from './types.js';
11
+ export declare const SECTION_TYPES: Record<SectionTypeId, SectionTypeDef>;
12
+ /** Ordered list for the Add Section gallery + discovery endpoints. */
13
+ export declare const SECTION_TYPE_LIST: SectionTypeDef[];
14
+ export declare function getSectionType(id: string): SectionTypeDef | undefined;
15
+ /**
16
+ * Section types available in a given editor context, in registry order.
17
+ *
18
+ * The Page editor passes `'page'`, the Post editor + Post Template editor
19
+ * pass `'post'`, so each Add Section gallery shows only the types that make
20
+ * sense (and have a working renderer) for that surface.
21
+ */
22
+ export declare function getSectionTypesForScope(scope: SectionScope): SectionTypeDef[];
23
+ /** Human label for a section type id, with a graceful fallback. */
24
+ export declare function sectionTypeLabel(id: string): string;
25
+ /** True when `id` is a registered, renderable section type. */
26
+ export declare function isKnownSectionType(id: string): id is SectionTypeId;
27
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/sections/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAmB,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAI9F,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,cAAc,CA0T/D,CAAA;AAED,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,EAAE,cAAc,EAW7C,CAAA;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAErE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,cAAc,EAAE,CAE7E;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,aAAa,CAElE"}
@@ -0,0 +1,349 @@
1
+ const BASE_SETTINGS = { backgroundType: 'none', paddingY: 'lg' };
2
+ export const SECTION_TYPES = {
3
+ hero: {
4
+ id: 'hero',
5
+ name: 'Hero Banner',
6
+ icon: 'layout-template',
7
+ description: 'Full-width banner with headline, body, and a primary call to action.',
8
+ category: 'layout',
9
+ accent: 'purple',
10
+ scope: ['page', 'post'],
11
+ defaultContent: {
12
+ eyebrow: '',
13
+ heading: 'Your headline goes here',
14
+ body: 'A short supporting sentence that sets up the value of the page.',
15
+ primaryButtonLabel: 'Get Started',
16
+ primaryButtonUrl: '/contact',
17
+ secondaryButtonLabel: '',
18
+ secondaryButtonUrl: '',
19
+ },
20
+ defaultSettings: { backgroundType: 'solid', backgroundColor: 'purple', paddingY: 'xl' },
21
+ fields: [
22
+ { key: 'eyebrow', label: 'Eyebrow', type: 'text', placeholder: 'Optional small label' },
23
+ { key: 'heading', label: 'Heading', type: 'textarea', required: true },
24
+ { key: 'body', label: 'Body', type: 'textarea' },
25
+ { key: 'primaryButtonLabel', label: 'Primary button', type: 'text' },
26
+ { key: 'primaryButtonUrl', label: 'Primary button URL', type: 'url' },
27
+ { key: 'secondaryButtonLabel', label: 'Secondary button', type: 'text' },
28
+ { key: 'secondaryButtonUrl', label: 'Secondary button URL', type: 'url' },
29
+ ],
30
+ },
31
+ text: {
32
+ id: 'text',
33
+ name: 'Text Block',
34
+ icon: 'align-left',
35
+ description: 'A heading and paragraph, useful for mission statements and prose.',
36
+ category: 'content',
37
+ accent: 'blue',
38
+ scope: ['page', 'post'],
39
+ defaultContent: {
40
+ heading: 'A short, clear heading',
41
+ body: 'Write the supporting copy for this section here.',
42
+ alignment: 'center',
43
+ },
44
+ defaultSettings: { ...BASE_SETTINGS, paddingY: 'xl' },
45
+ fields: [
46
+ { key: 'heading', label: 'Heading', type: 'textarea', required: true },
47
+ { key: 'body', label: 'Body', type: 'textarea' },
48
+ {
49
+ key: 'alignment',
50
+ label: 'Alignment',
51
+ type: 'select',
52
+ options: [
53
+ { label: 'Left', value: 'left' },
54
+ { label: 'Center', value: 'center' },
55
+ ],
56
+ },
57
+ ],
58
+ },
59
+ feature: {
60
+ id: 'feature',
61
+ name: 'Image + Text',
62
+ icon: 'panels-top-left',
63
+ description: 'Two-column feature highlight with copy on one side and media on the other.',
64
+ category: 'media',
65
+ accent: 'green',
66
+ scope: ['page', 'post'],
67
+ defaultContent: {
68
+ label: 'Feature Highlight',
69
+ heading: 'A standout capability',
70
+ body: 'Describe the feature and why it matters to your audience.',
71
+ imageUrl: '',
72
+ imageAlt: '',
73
+ imagePosition: 'right',
74
+ buttonLabel: '',
75
+ buttonUrl: '',
76
+ },
77
+ defaultSettings: { ...BASE_SETTINGS },
78
+ fields: [
79
+ {
80
+ key: 'label',
81
+ label: 'Section label',
82
+ type: 'text',
83
+ help: 'Small eyebrow above the heading',
84
+ },
85
+ { key: 'heading', label: 'Heading', type: 'textarea', required: true },
86
+ { key: 'body', label: 'Body', type: 'textarea' },
87
+ { key: 'imageUrl', label: 'Image', type: 'media' },
88
+ {
89
+ key: 'imageAlt',
90
+ label: 'Image alt text',
91
+ type: 'text',
92
+ help: 'Required when an image is set',
93
+ },
94
+ {
95
+ key: 'imagePosition',
96
+ label: 'Image position',
97
+ type: 'select',
98
+ options: [
99
+ { label: 'Right', value: 'right' },
100
+ { label: 'Left', value: 'left' },
101
+ ],
102
+ },
103
+ { key: 'buttonLabel', label: 'Button', type: 'text' },
104
+ { key: 'buttonUrl', label: 'Button URL', type: 'url' },
105
+ ],
106
+ },
107
+ stats: {
108
+ id: 'stats',
109
+ name: 'By the Numbers',
110
+ icon: 'bar-chart-3',
111
+ description: 'A row of key metrics with values and labels.',
112
+ category: 'content',
113
+ accent: 'orange',
114
+ scope: ['page', 'post'],
115
+ defaultContent: {
116
+ heading: 'By the numbers',
117
+ body: '',
118
+ stats: [
119
+ { value: '99.99%', label: 'Uptime', description: '' },
120
+ { value: '124ms', label: 'Avg response time', description: '' },
121
+ { value: '3M+', label: 'API requests served', description: '' },
122
+ ],
123
+ },
124
+ defaultSettings: { ...BASE_SETTINGS },
125
+ fields: [
126
+ { key: 'heading', label: 'Heading', type: 'textarea' },
127
+ { key: 'body', label: 'Body', type: 'textarea' },
128
+ { key: 'stats', label: 'Stats', type: 'stats' },
129
+ ],
130
+ },
131
+ cta: {
132
+ id: 'cta',
133
+ name: 'CTA Banner',
134
+ icon: 'megaphone',
135
+ description: 'A focused call-to-action band with heading, body, and a button.',
136
+ category: 'conversion',
137
+ accent: 'pink',
138
+ scope: ['page', 'post'],
139
+ defaultContent: {
140
+ heading: 'Ready to get started?',
141
+ body: 'A short nudge that motivates the next step.',
142
+ buttonLabel: 'Start Building',
143
+ buttonUrl: '/contact',
144
+ },
145
+ defaultSettings: { backgroundType: 'solid', backgroundColor: 'purple', paddingY: 'xl' },
146
+ fields: [
147
+ { key: 'heading', label: 'Heading', type: 'textarea', required: true },
148
+ { key: 'body', label: 'Body', type: 'textarea' },
149
+ { key: 'buttonLabel', label: 'Button', type: 'text' },
150
+ { key: 'buttonUrl', label: 'Button URL', type: 'url' },
151
+ ],
152
+ },
153
+ // ─── Post-oriented section types (scope: post) ─────────────────────
154
+ 'article-body': {
155
+ id: 'article-body',
156
+ name: 'Article Body',
157
+ icon: 'text',
158
+ description: "Renders the post's main body content with optional reading aids.",
159
+ category: 'content',
160
+ accent: 'blue',
161
+ scope: ['post'],
162
+ defaultContent: {
163
+ // `source: 'field'` binds the rendered body to the post's own `body`
164
+ // field (single source of truth). `override` lets the author type
165
+ // body copy directly into the section instead.
166
+ source: 'field',
167
+ body: '',
168
+ width: 'normal',
169
+ showToc: false,
170
+ },
171
+ defaultSettings: { ...BASE_SETTINGS, paddingY: 'lg' },
172
+ fields: [
173
+ {
174
+ key: 'source',
175
+ label: 'Body source',
176
+ type: 'select',
177
+ help: "Use the post's Body field, or write copy here in this section.",
178
+ options: [
179
+ { label: "Post's Body field", value: 'field' },
180
+ { label: 'Custom copy', value: 'override' },
181
+ ],
182
+ },
183
+ {
184
+ key: 'body',
185
+ label: 'Custom body',
186
+ type: 'richText',
187
+ help: 'Used only when Body source is "Custom copy".',
188
+ },
189
+ {
190
+ key: 'width',
191
+ label: 'Content width',
192
+ type: 'select',
193
+ options: [
194
+ { label: 'Normal', value: 'normal' },
195
+ { label: 'Wide', value: 'wide' },
196
+ ],
197
+ },
198
+ { key: 'showToc', label: 'Show table of contents', type: 'boolean' },
199
+ ],
200
+ },
201
+ quote: {
202
+ id: 'quote',
203
+ name: 'Pull Quote',
204
+ icon: 'quote',
205
+ description: 'A highlighted quotation with optional attribution.',
206
+ category: 'content',
207
+ accent: 'purple',
208
+ scope: ['post'],
209
+ defaultContent: {
210
+ quote: 'A memorable line worth pulling out of the body copy.',
211
+ attribution: '',
212
+ role: '',
213
+ },
214
+ defaultSettings: { ...BASE_SETTINGS, paddingY: 'lg' },
215
+ fields: [
216
+ { key: 'quote', label: 'Quote', type: 'textarea', required: true },
217
+ { key: 'attribution', label: 'Attribution', type: 'text', placeholder: 'Jane Doe' },
218
+ { key: 'role', label: 'Role / source', type: 'text', placeholder: 'CEO, Acme' },
219
+ ],
220
+ },
221
+ 'author-bio': {
222
+ id: 'author-bio',
223
+ name: 'Author Bio',
224
+ icon: 'user',
225
+ description: "A short biography block for the post's author.",
226
+ category: 'content',
227
+ accent: 'green',
228
+ scope: ['post'],
229
+ defaultContent: {
230
+ heading: 'About the author',
231
+ showAvatar: true,
232
+ showSocial: true,
233
+ },
234
+ defaultSettings: { ...BASE_SETTINGS },
235
+ fields: [
236
+ { key: 'heading', label: 'Heading', type: 'text' },
237
+ { key: 'showAvatar', label: 'Show avatar', type: 'boolean' },
238
+ { key: 'showSocial', label: 'Show social links', type: 'boolean' },
239
+ ],
240
+ },
241
+ 'related-posts': {
242
+ id: 'related-posts',
243
+ name: 'Related Posts',
244
+ icon: 'layout-grid',
245
+ description: 'A grid of related posts, chosen automatically or hand-picked.',
246
+ category: 'content',
247
+ accent: 'orange',
248
+ scope: ['post'],
249
+ defaultContent: {
250
+ heading: 'Related posts',
251
+ mode: 'auto',
252
+ count: '3',
253
+ postSlugs: [],
254
+ },
255
+ defaultSettings: { ...BASE_SETTINGS },
256
+ fields: [
257
+ { key: 'heading', label: 'Heading', type: 'text' },
258
+ {
259
+ key: 'mode',
260
+ label: 'Selection',
261
+ type: 'select',
262
+ options: [
263
+ { label: 'Automatic (newest in this type)', value: 'auto' },
264
+ { label: 'Hand-picked', value: 'manual' },
265
+ ],
266
+ },
267
+ {
268
+ key: 'count',
269
+ label: 'How many',
270
+ type: 'select',
271
+ options: [
272
+ { label: '3', value: '3' },
273
+ { label: '4', value: '4' },
274
+ { label: '6', value: '6' },
275
+ ],
276
+ },
277
+ {
278
+ key: 'postSlugs',
279
+ label: 'Posts',
280
+ type: 'relationship',
281
+ help: 'Used only when Selection is "Hand-picked".',
282
+ },
283
+ ],
284
+ },
285
+ gallery: {
286
+ id: 'gallery',
287
+ name: 'Image Gallery',
288
+ icon: 'images',
289
+ description: 'A grid of images with captions.',
290
+ category: 'media',
291
+ accent: 'pink',
292
+ scope: ['post'],
293
+ defaultContent: {
294
+ heading: '',
295
+ columns: '3',
296
+ images: [],
297
+ },
298
+ defaultSettings: { ...BASE_SETTINGS },
299
+ fields: [
300
+ { key: 'heading', label: 'Heading', type: 'text' },
301
+ {
302
+ key: 'columns',
303
+ label: 'Columns',
304
+ type: 'select',
305
+ options: [
306
+ { label: '2', value: '2' },
307
+ { label: '3', value: '3' },
308
+ { label: '4', value: '4' },
309
+ ],
310
+ },
311
+ { key: 'images', label: 'Images', type: 'gallery' },
312
+ ],
313
+ },
314
+ };
315
+ /** Ordered list for the Add Section gallery + discovery endpoints. */
316
+ export const SECTION_TYPE_LIST = [
317
+ SECTION_TYPES.hero,
318
+ SECTION_TYPES.text,
319
+ SECTION_TYPES.feature,
320
+ SECTION_TYPES.stats,
321
+ SECTION_TYPES.cta,
322
+ SECTION_TYPES['article-body'],
323
+ SECTION_TYPES.quote,
324
+ SECTION_TYPES['author-bio'],
325
+ SECTION_TYPES['related-posts'],
326
+ SECTION_TYPES.gallery,
327
+ ];
328
+ export function getSectionType(id) {
329
+ return SECTION_TYPES[id];
330
+ }
331
+ /**
332
+ * Section types available in a given editor context, in registry order.
333
+ *
334
+ * The Page editor passes `'page'`, the Post editor + Post Template editor
335
+ * pass `'post'`, so each Add Section gallery shows only the types that make
336
+ * sense (and have a working renderer) for that surface.
337
+ */
338
+ export function getSectionTypesForScope(scope) {
339
+ return SECTION_TYPE_LIST.filter((def) => def.scope.includes(scope));
340
+ }
341
+ /** Human label for a section type id, with a graceful fallback. */
342
+ export function sectionTypeLabel(id) {
343
+ return getSectionType(id)?.name ?? 'Section';
344
+ }
345
+ /** True when `id` is a registered, renderable section type. */
346
+ export function isKnownSectionType(id) {
347
+ return getSectionType(id) !== undefined;
348
+ }
349
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/sections/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Shared types for the flat, section-based Page Editor model.
3
+ *
4
+ * A page is an ordered list of `PageSection`s stored in a page document's
5
+ * `data.sections` JSON field. A section's `sectionType` keys into the
6
+ * {@link SECTION_TYPES} registry, which is the single source of truth for:
7
+ * - the Add Section gallery (label / icon / description / category)
8
+ * - default content + settings when a section is created
9
+ * - the inspector field schema (which content controls to render)
10
+ * - the renderer component (dispatches on the same `sectionType` key)
11
+ * - server + MCP validation of AI-authored section content
12
+ *
13
+ * This module lives in `cms-core` (not `cms-admin`) so the admin editor,
14
+ * the REST API, and the MCP server all validate against ONE definition.
15
+ *
16
+ * NOTE: this is deliberately distinct from the page-builder *tree* model
17
+ * (`SectionNode` etc. in `../page-builder`). That model is a recursive
18
+ * node tree; this one is a flat list of named, schema-driven sections.
19
+ */
20
+ /**
21
+ * Stable ids for the built-in section types.
22
+ *
23
+ * The first group is shared (usable on both pages and posts); the second
24
+ * group is post-oriented (article body, pull quote, author bio, related
25
+ * posts, image gallery). Which types appear in a given editor is governed
26
+ * by {@link SectionTypeDef.scope}.
27
+ */
28
+ export type SectionTypeId = 'hero' | 'text' | 'feature' | 'stats' | 'cta' | 'article-body' | 'quote' | 'author-bio' | 'related-posts' | 'gallery';
29
+ /** Where a section type may be used. Drives the Add Section gallery filter. */
30
+ export type SectionScope = 'page' | 'post';
31
+ /** Field kinds the inspector + validator understand. */
32
+ export type SectionFieldType = 'text' | 'textarea' | 'richText' | 'url' | 'media' | 'select' | 'boolean' | 'color' | 'relationship' | 'stats' | 'gallery';
33
+ export interface SectionFieldDef {
34
+ /** key into `PageSection.content` */
35
+ key: string;
36
+ label: string;
37
+ type: SectionFieldType;
38
+ placeholder?: string;
39
+ /** options for `type: 'select'` */
40
+ options?: Array<{
41
+ label: string;
42
+ value: string;
43
+ }>;
44
+ /** collection slug a `relationship` field points at (defaults to the host post type) */
45
+ relationTo?: string;
46
+ /** marks the field required for publish-time validation */
47
+ required?: boolean;
48
+ help?: string;
49
+ }
50
+ export interface SectionSettings {
51
+ backgroundType?: 'none' | 'solid' | 'gradient';
52
+ backgroundColor?: string;
53
+ paddingY?: 'sm' | 'md' | 'lg' | 'xl';
54
+ anchorId?: string;
55
+ cssClass?: string;
56
+ }
57
+ export interface SectionTypeDef {
58
+ id: SectionTypeId;
59
+ /** Display name used in the Sections panel + Add gallery */
60
+ name: string;
61
+ /** lucide-react icon name (resolved by the admin panel/gallery) */
62
+ icon: string;
63
+ description: string;
64
+ category: 'layout' | 'content' | 'media' | 'conversion';
65
+ /** accent color key (maps to the shared badge palette) */
66
+ accent: 'purple' | 'green' | 'orange' | 'blue' | 'pink';
67
+ /** which editors expose this type. Defaults (when omitted) to page-only. */
68
+ scope: SectionScope[];
69
+ defaultContent: Record<string, unknown>;
70
+ defaultSettings: SectionSettings;
71
+ /** content fields shown in the inspector, in order */
72
+ fields: SectionFieldDef[];
73
+ }
74
+ /** A single section on a page. Persisted in `data.sections[]`. */
75
+ export interface PageSection {
76
+ id: string;
77
+ sectionType: SectionTypeId;
78
+ /** Editor-facing display name (defaults to the type name). */
79
+ name: string;
80
+ /** Optional internal-only label for the team. */
81
+ internalLabel?: string;
82
+ visible: boolean;
83
+ content: Record<string, unknown>;
84
+ settings: SectionSettings;
85
+ }
86
+ /** A structured validation finding for a single section. */
87
+ export interface SectionValidationIssue {
88
+ /** the section type the issue belongs to */
89
+ sectionType: string;
90
+ /** content field key when the issue is field-scoped */
91
+ field?: string;
92
+ message: string;
93
+ }
94
+ export interface SectionValidationResult {
95
+ valid: boolean;
96
+ errors: SectionValidationIssue[];
97
+ warnings: SectionValidationIssue[];
98
+ }
99
+ /**
100
+ * Design-driven header layout for a post type. These are presentation
101
+ * toggles only — the actual values (title, image, author, date) come from
102
+ * each post document's own fields, never from the template.
103
+ */
104
+ export interface PostHeaderConfig {
105
+ /** Overall header composition. */
106
+ layout: 'centered' | 'left' | 'overlay';
107
+ showFeaturedImage: boolean;
108
+ showExcerpt: boolean;
109
+ showAuthor: boolean;
110
+ showDate: boolean;
111
+ showCategory: boolean;
112
+ showReadingTime: boolean;
113
+ }
114
+ /**
115
+ * A post type's editable template: the header layout plus the ordered list
116
+ * of sections new posts of that type inherit. Stored as a single document
117
+ * per post type in the hidden `post-templates` collection
118
+ * (`data: { postType, header, sections }`).
119
+ */
120
+ export interface PostTemplate {
121
+ /** slug of the post-type collection this template belongs to */
122
+ postType: string;
123
+ header: PostHeaderConfig;
124
+ /** default body/trailing sections new posts inherit */
125
+ sections: PageSection[];
126
+ }
127
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sections/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Shared types for the flat, section-based Page Editor model.
3
+ *
4
+ * A page is an ordered list of `PageSection`s stored in a page document's
5
+ * `data.sections` JSON field. A section's `sectionType` keys into the
6
+ * {@link SECTION_TYPES} registry, which is the single source of truth for:
7
+ * - the Add Section gallery (label / icon / description / category)
8
+ * - default content + settings when a section is created
9
+ * - the inspector field schema (which content controls to render)
10
+ * - the renderer component (dispatches on the same `sectionType` key)
11
+ * - server + MCP validation of AI-authored section content
12
+ *
13
+ * This module lives in `cms-core` (not `cms-admin`) so the admin editor,
14
+ * the REST API, and the MCP server all validate against ONE definition.
15
+ *
16
+ * NOTE: this is deliberately distinct from the page-builder *tree* model
17
+ * (`SectionNode` etc. in `../page-builder`). That model is a recursive
18
+ * node tree; this one is a flat list of named, schema-driven sections.
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sections/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
@@ -0,0 +1,10 @@
1
+ import type { SectionSettings, SectionValidationResult } from './types.js';
2
+ /**
3
+ * Validate one section's content + settings against its type schema.
4
+ *
5
+ * An unknown `sectionType` is a hard error (the agent asked for a type with
6
+ * no renderer). Required fields, button URL validity, and image alt text
7
+ * are enforced; everything else is advisory.
8
+ */
9
+ export declare function validateSectionContent(sectionType: string, content: Record<string, unknown>, _settings?: SectionSettings): SectionValidationResult;
10
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/sections/validate.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAe1E;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,CAAC,EAAE,eAAe,GAC1B,uBAAuB,CAgEzB"}