@actuate-media/cms-core 0.49.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/api/resolve-layout-bridge.test.d.ts +2 -0
- package/dist/__tests__/api/resolve-layout-bridge.test.d.ts.map +1 -0
- package/dist/__tests__/api/resolve-layout-bridge.test.js +165 -0
- package/dist/__tests__/api/resolve-layout-bridge.test.js.map +1 -0
- package/dist/api/handlers.d.ts.map +1 -1
- package/dist/api/handlers.js +15 -2
- package/dist/api/handlers.js.map +1 -1
- package/dist/sections/__tests__/bridge.test.d.ts +2 -0
- package/dist/sections/__tests__/bridge.test.d.ts.map +1 -0
- package/dist/sections/__tests__/bridge.test.js +171 -0
- package/dist/sections/__tests__/bridge.test.js.map +1 -0
- package/dist/sections/bridge.d.ts +8 -0
- package/dist/sections/bridge.d.ts.map +1 -0
- package/dist/sections/bridge.js +211 -0
- package/dist/sections/bridge.js.map +1 -0
- package/dist/sections/index.d.ts +1 -0
- package/dist/sections/index.d.ts.map +1 -1
- package/dist/sections/index.js +1 -0
- package/dist/sections/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-layout-bridge.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/api/resolve-layout-bridge.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { handleActuateAPI } from '../../api/index.js';
|
|
3
|
+
import { initDB } from '../../db.js';
|
|
4
|
+
function createMockDB(docs) {
|
|
5
|
+
const rows = docs.map((d) => ({ ...d, deletedAt: d.deletedAt ?? null }));
|
|
6
|
+
const matches = (d, where) => {
|
|
7
|
+
if (!where)
|
|
8
|
+
return true;
|
|
9
|
+
if (where.id && d.id !== where.id)
|
|
10
|
+
return false;
|
|
11
|
+
if (where.collection && d.collection !== where.collection)
|
|
12
|
+
return false;
|
|
13
|
+
if (where.status && d.status !== where.status)
|
|
14
|
+
return false;
|
|
15
|
+
if (where.deletedAt === null && d.deletedAt)
|
|
16
|
+
return false;
|
|
17
|
+
if (where.OR && Array.isArray(where.OR)) {
|
|
18
|
+
return where.OR.some((clause) => {
|
|
19
|
+
if (clause.slug !== undefined)
|
|
20
|
+
return d.slug === clause.slug;
|
|
21
|
+
if (clause.data?.path && clause.data?.equals !== undefined) {
|
|
22
|
+
return d.data?.[clause.data.path[0]] === clause.data.equals;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
apiKey: { findMany: async () => [], findUnique: async () => null },
|
|
31
|
+
document: {
|
|
32
|
+
findMany: async ({ where } = {}) => rows.filter((d) => matches(d, where)),
|
|
33
|
+
findFirst: async ({ where }) => rows.find((d) => matches(d, where ?? {})) ?? null,
|
|
34
|
+
count: async () => rows.length,
|
|
35
|
+
},
|
|
36
|
+
version: { create: async () => ({}), findMany: async () => [], count: async () => 0 },
|
|
37
|
+
auditLog: { create: async () => ({}) },
|
|
38
|
+
webhook: { findMany: async () => [] },
|
|
39
|
+
webhookDelivery: { create: async () => ({}) },
|
|
40
|
+
user: {},
|
|
41
|
+
session: {},
|
|
42
|
+
media: {},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const pagesCollection = {
|
|
46
|
+
slug: 'pages',
|
|
47
|
+
labels: { singular: 'Page', plural: 'Pages' },
|
|
48
|
+
type: 'page',
|
|
49
|
+
urlPrefix: '',
|
|
50
|
+
fields: {
|
|
51
|
+
title: { type: 'text', label: 'Title', required: true },
|
|
52
|
+
slug: { type: 'slug', label: 'Slug', required: true },
|
|
53
|
+
sections: { type: 'json', label: 'Sections' },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
const cmsConfig = { collections: { pages: pagesCollection } };
|
|
57
|
+
// A page-builder tree (page → section → row → column → hero block) with no
|
|
58
|
+
// flat `sections` array of its own.
|
|
59
|
+
const layoutTree = {
|
|
60
|
+
id: 'page',
|
|
61
|
+
type: 'page',
|
|
62
|
+
children: [
|
|
63
|
+
{
|
|
64
|
+
id: 'sec',
|
|
65
|
+
type: 'section',
|
|
66
|
+
settings: { htmlId: 'top' },
|
|
67
|
+
children: [
|
|
68
|
+
{
|
|
69
|
+
id: 'row',
|
|
70
|
+
type: 'row',
|
|
71
|
+
settings: {},
|
|
72
|
+
children: [
|
|
73
|
+
{
|
|
74
|
+
id: 'col',
|
|
75
|
+
type: 'column',
|
|
76
|
+
settings: { width: 12 },
|
|
77
|
+
children: [
|
|
78
|
+
{
|
|
79
|
+
id: 'blk',
|
|
80
|
+
type: 'block',
|
|
81
|
+
settings: { blockType: 'hero' },
|
|
82
|
+
data: { title: 'Welcome home', subtitle: 'Built in the page builder' },
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
beforeEach(() => {
|
|
93
|
+
delete globalThis.__actuateConfig;
|
|
94
|
+
process.env.CMS_SECRET = 'a'.repeat(48);
|
|
95
|
+
});
|
|
96
|
+
describe('GET /resolve — page-builder (_layout) → sections bridge', () => {
|
|
97
|
+
it('derives data.sections from _layout when the page has no flat sections', async () => {
|
|
98
|
+
const docs = [
|
|
99
|
+
{
|
|
100
|
+
id: 'doc-1',
|
|
101
|
+
collection: 'pages',
|
|
102
|
+
slug: 'home',
|
|
103
|
+
status: 'PUBLISHED',
|
|
104
|
+
data: { title: 'Home', slug: 'home', _layout: layoutTree },
|
|
105
|
+
publishedAt: new Date('2026-01-01T00:00:00Z'),
|
|
106
|
+
updatedAt: new Date('2026-01-01T00:00:00Z'),
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
const db = createMockDB(docs);
|
|
110
|
+
initDB(db);
|
|
111
|
+
const handler = handleActuateAPI({ prismaClient: db, config: cmsConfig });
|
|
112
|
+
const res = await handler(new Request('https://example.com/api/cms/resolve?path=/home'));
|
|
113
|
+
expect(res.status).toBe(200);
|
|
114
|
+
const body = await res.json();
|
|
115
|
+
const sections = body.data.data.sections;
|
|
116
|
+
expect(Array.isArray(sections)).toBe(true);
|
|
117
|
+
expect(sections).toHaveLength(1);
|
|
118
|
+
expect(sections[0].sectionType).toBe('hero');
|
|
119
|
+
expect(sections[0].content).toMatchObject({
|
|
120
|
+
heading: 'Welcome home',
|
|
121
|
+
body: 'Built in the page builder',
|
|
122
|
+
});
|
|
123
|
+
expect(sections[0].settings.anchorId).toBe('top');
|
|
124
|
+
// The raw tree is never exposed to the client.
|
|
125
|
+
expect(body.data.data._layout).toBeUndefined();
|
|
126
|
+
});
|
|
127
|
+
it('does not overwrite an existing flat sections array', async () => {
|
|
128
|
+
const docs = [
|
|
129
|
+
{
|
|
130
|
+
id: 'doc-2',
|
|
131
|
+
collection: 'pages',
|
|
132
|
+
slug: 'about',
|
|
133
|
+
status: 'PUBLISHED',
|
|
134
|
+
data: {
|
|
135
|
+
title: 'About',
|
|
136
|
+
slug: 'about',
|
|
137
|
+
_layout: layoutTree,
|
|
138
|
+
sections: [
|
|
139
|
+
{
|
|
140
|
+
id: 's1',
|
|
141
|
+
sectionType: 'text',
|
|
142
|
+
name: 'Text Block',
|
|
143
|
+
visible: true,
|
|
144
|
+
content: { heading: 'Hand-authored', body: 'wins' },
|
|
145
|
+
settings: {},
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
publishedAt: new Date('2026-01-01T00:00:00Z'),
|
|
150
|
+
updatedAt: new Date('2026-01-01T00:00:00Z'),
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
const db = createMockDB(docs);
|
|
154
|
+
initDB(db);
|
|
155
|
+
const handler = handleActuateAPI({ prismaClient: db, config: cmsConfig });
|
|
156
|
+
const res = await handler(new Request('https://example.com/api/cms/resolve?path=/about'));
|
|
157
|
+
expect(res.status).toBe(200);
|
|
158
|
+
const body = await res.json();
|
|
159
|
+
const sections = body.data.data.sections;
|
|
160
|
+
expect(sections).toHaveLength(1);
|
|
161
|
+
expect(sections[0].sectionType).toBe('text');
|
|
162
|
+
expect(sections[0].content.heading).toBe('Hand-authored');
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
//# sourceMappingURL=resolve-layout-bridge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-layout-bridge.test.js","sourceRoot":"","sources":["../../../src/__tests__/api/resolve-layout-bridge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/api/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/api/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAgmC5C,iFAAiF;AACjF,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AA8JD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS9E;AAiVD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqwYzD"}
|
package/dist/api/handlers.js
CHANGED
|
@@ -45,7 +45,7 @@ import { createSSEPresenceAdapter } from '../presence/index.js';
|
|
|
45
45
|
import { BUILT_IN_TEMPLATES } from '../page-builder/templates.js';
|
|
46
46
|
import { validateTree } from '../page-builder/validate.js';
|
|
47
47
|
import { auditAccessibility, fixAccessibility } from '../page-builder/a11y-fix.js';
|
|
48
|
-
import { SECTION_TYPE_LIST, getSectionType, getSectionTypesForScope, buildSection, coerceSections, coercePostHeader, defaultPostHeader, createPostTemplate, addSection as addSectionToList, removeSection as removeSectionFromList, reorderSections as reorderSectionList, setSectionVisibility, updateSectionContent as updateSectionContentInList, updateSectionSettings as updateSectionSettingsInList, updateSectionMeta as updateSectionMetaInList, validateSectionContent, } from '../sections/index.js';
|
|
48
|
+
import { SECTION_TYPE_LIST, getSectionType, getSectionTypesForScope, buildSection, coerceSections, coercePostHeader, layoutTreeToSections, defaultPostHeader, createPostTemplate, addSection as addSectionToList, removeSection as removeSectionFromList, reorderSections as reorderSectionList, setSectionVisibility, updateSectionContent as updateSectionContentInList, updateSectionSettings as updateSectionSettingsInList, updateSectionMeta as updateSectionMetaInList, validateSectionContent, } from '../sections/index.js';
|
|
49
49
|
import { buildPostsOrderBy, buildPostsWhere, extractSeoScore as extractPostSeoScore, resolveQueryCollections, } from '../posts/query.js';
|
|
50
50
|
import { getClientIp, isResolvedIp } from '../security/client-ip.js';
|
|
51
51
|
import { safeFetch, SsrfBlockedError } from '../security/safe-fetch.js';
|
|
@@ -8771,7 +8771,20 @@ export function registerCMSRoutes(router) {
|
|
|
8771
8771
|
}
|
|
8772
8772
|
}
|
|
8773
8773
|
const layout = await resolveLayout(pathParam, docData, matchedCollection);
|
|
8774
|
-
const { _layout:
|
|
8774
|
+
const { _layout: layoutTree, ...cleanData } = docData;
|
|
8775
|
+
// WS-A5 compat bridge (ADR 0001): a document authored only in the
|
|
8776
|
+
// page-builder tree (`_layout`, Model B) still renders through the
|
|
8777
|
+
// canonical sections path. When it has no flat `sections` of its own,
|
|
8778
|
+
// derive a best-effort PageSection[] from the tree at read time so
|
|
8779
|
+
// page-builder content is never stranded. Non-destructive — the stored
|
|
8780
|
+
// document is untouched; only the response is enriched.
|
|
8781
|
+
if ((!Array.isArray(cleanData.sections) || cleanData.sections.length === 0) &&
|
|
8782
|
+
layoutTree &&
|
|
8783
|
+
typeof layoutTree === 'object') {
|
|
8784
|
+
const bridged = layoutTreeToSections(layoutTree);
|
|
8785
|
+
if (bridged.length > 0)
|
|
8786
|
+
cleanData.sections = bridged;
|
|
8787
|
+
}
|
|
8775
8788
|
// Compose page meta + JSON-LD up front so client renderers (Next.js
|
|
8776
8789
|
// generateMetadata, plain SSR, MCP agents) don't have to re-derive
|
|
8777
8790
|
// schema, OG tags, and canonical URLs from raw doc data. Reads the
|