@actuate-media/cms-core 0.52.0 → 0.53.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__/actions/document-crud.test.js +48 -0
- package/dist/__tests__/actions/document-crud.test.js.map +1 -1
- package/dist/__tests__/api/page-sections-routes.test.js +23 -0
- package/dist/__tests__/api/page-sections-routes.test.js.map +1 -1
- package/dist/__tests__/sections/sections-migrate.test.d.ts +2 -0
- package/dist/__tests__/sections/sections-migrate.test.d.ts.map +1 -0
- package/dist/__tests__/sections/sections-migrate.test.js +145 -0
- package/dist/__tests__/sections/sections-migrate.test.js.map +1 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +11 -1
- package/dist/actions.js.map +1 -1
- package/dist/api/handlers.d.ts.map +1 -1
- package/dist/api/handlers.js +24 -11
- package/dist/api/handlers.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/sections/migrate.d.ts +42 -0
- package/dist/sections/migrate.d.ts.map +1 -0
- package/dist/sections/migrate.js +66 -0
- package/dist/sections/migrate.js.map +1 -0
- package/package.json +1 -1
package/dist/api/handlers.js
CHANGED
|
@@ -2511,13 +2511,25 @@ export function registerCMSRoutes(router) {
|
|
|
2511
2511
|
}
|
|
2512
2512
|
});
|
|
2513
2513
|
// Shared: load a page document's sections, or a Response on error.
|
|
2514
|
-
|
|
2514
|
+
//
|
|
2515
|
+
// ADR 0002 ownership guard: a document authored in the visual page builder
|
|
2516
|
+
// carries a `_layout` tree and its `sections` are *compiled* from that tree on
|
|
2517
|
+
// every save. Editing those sections directly would be silently overwritten by
|
|
2518
|
+
// the next builder save, so for WRITE callers we refuse a builder-owned doc
|
|
2519
|
+
// with 409 instead. Read callers are unaffected.
|
|
2520
|
+
const loadPageSections = async (collection, id, ctx, opts) => {
|
|
2515
2521
|
if (!collectionSupportsSections(collection)) {
|
|
2516
2522
|
return errorResponse(`Collection "${collection}" does not declare a "sections" JSON field, so it cannot store page sections.`, 400);
|
|
2517
2523
|
}
|
|
2518
2524
|
const doc = await getDocument(collection, id, ctx);
|
|
2519
2525
|
if (!doc)
|
|
2520
2526
|
return errorResponse('Page not found', 404);
|
|
2527
|
+
// `getDocument` lifts the stored `_layout` out of `data` onto the wire
|
|
2528
|
+
// envelope (`doc.layout`), so the builder-ownership signal lives there.
|
|
2529
|
+
const layout = doc.layout;
|
|
2530
|
+
if (opts?.forWrite && layout && typeof layout === 'object') {
|
|
2531
|
+
return errorResponse(`Page "${id}" is owned by the visual page builder: its sections are compiled from the builder layout and would be overwritten on the next save. Edit it in the Page Builder instead (or clear its layout to convert it to a section-authored page).`, 409);
|
|
2532
|
+
}
|
|
2521
2533
|
const data = doc.data ?? {};
|
|
2522
2534
|
return { sections: coerceSections(data.sections) };
|
|
2523
2535
|
};
|
|
@@ -2572,7 +2584,7 @@ export function registerCMSRoutes(router) {
|
|
|
2572
2584
|
return errorResponse(`Unknown section type "${sectionType}". Call GET /page-sections/types for valid ids.`, 400);
|
|
2573
2585
|
}
|
|
2574
2586
|
const ctx = buildActionContext(auth.session, db());
|
|
2575
|
-
const loaded = await loadPageSections(params.collection, params.id, ctx);
|
|
2587
|
+
const loaded = await loadPageSections(params.collection, params.id, ctx, { forWrite: true });
|
|
2576
2588
|
if (loaded instanceof Response)
|
|
2577
2589
|
return loaded;
|
|
2578
2590
|
const section = buildSection(sectionType, {
|
|
@@ -2614,7 +2626,7 @@ export function registerCMSRoutes(router) {
|
|
|
2614
2626
|
if (!orderedIds)
|
|
2615
2627
|
return errorResponse('orderedIds (string[]) is required', 400);
|
|
2616
2628
|
const ctx = buildActionContext(auth.session, db());
|
|
2617
|
-
const loaded = await loadPageSections(params.collection, params.id, ctx);
|
|
2629
|
+
const loaded = await loadPageSections(params.collection, params.id, ctx, { forWrite: true });
|
|
2618
2630
|
if (loaded instanceof Response)
|
|
2619
2631
|
return loaded;
|
|
2620
2632
|
const next = reorderSectionList(loaded.sections, orderedIds);
|
|
@@ -2637,7 +2649,7 @@ export function registerCMSRoutes(router) {
|
|
|
2637
2649
|
return scopeErr;
|
|
2638
2650
|
const body = (await request.json().catch(() => null));
|
|
2639
2651
|
const ctx = buildActionContext(auth.session, db());
|
|
2640
|
-
const loaded = await loadPageSections(params.collection, params.id, ctx);
|
|
2652
|
+
const loaded = await loadPageSections(params.collection, params.id, ctx, { forWrite: true });
|
|
2641
2653
|
if (loaded instanceof Response)
|
|
2642
2654
|
return loaded;
|
|
2643
2655
|
const sectionId = params.sectionId;
|
|
@@ -2682,7 +2694,7 @@ export function registerCMSRoutes(router) {
|
|
|
2682
2694
|
if (scopeErr)
|
|
2683
2695
|
return scopeErr;
|
|
2684
2696
|
const ctx = buildActionContext(auth.session, db());
|
|
2685
|
-
const loaded = await loadPageSections(params.collection, params.id, ctx);
|
|
2697
|
+
const loaded = await loadPageSections(params.collection, params.id, ctx, { forWrite: true });
|
|
2686
2698
|
if (loaded instanceof Response)
|
|
2687
2699
|
return loaded;
|
|
2688
2700
|
const sectionId = params.sectionId;
|
|
@@ -8837,12 +8849,13 @@ export function registerCMSRoutes(router) {
|
|
|
8837
8849
|
}
|
|
8838
8850
|
const layout = await resolveLayout(pathParam, docData, matchedCollection);
|
|
8839
8851
|
const { _layout: layoutTree, ...cleanData } = docData;
|
|
8840
|
-
//
|
|
8841
|
-
//
|
|
8842
|
-
//
|
|
8843
|
-
//
|
|
8844
|
-
//
|
|
8845
|
-
//
|
|
8852
|
+
// LEGACY fallback (ADR 0002): builder pages now compile `_layout` to
|
|
8853
|
+
// canonical `data.sections` on save, so this branch is a no-op for any
|
|
8854
|
+
// document written after that change. It still fires for LEGACY pages
|
|
8855
|
+
// authored in the tree before compile-on-save (and not yet migrated via
|
|
8856
|
+
// `migratePageBuilderSections`): when such a doc has no flat `sections`,
|
|
8857
|
+
// derive a best-effort PageSection[] at read time so page-builder content
|
|
8858
|
+
// is never stranded. Non-destructive — only the response is enriched.
|
|
8846
8859
|
if ((!Array.isArray(cleanData.sections) || cleanData.sections.length === 0) &&
|
|
8847
8860
|
layoutTree &&
|
|
8848
8861
|
typeof layoutTree === 'object') {
|