@endora-commerce/mod-cms 0.0.0-stage → 0.100.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/LICENSE +21 -0
- package/README.md +65 -2
- package/dist/admin/api/cms-client.d.ts +77 -0
- package/dist/admin/api/cms-client.d.ts.map +1 -0
- package/dist/admin/api/cms-client.js +162 -0
- package/dist/admin/api/cms-client.js.map +1 -0
- package/dist/admin/components/AdminCatalogPreviewProvider.d.ts +6 -0
- package/dist/admin/components/AdminCatalogPreviewProvider.d.ts.map +1 -0
- package/dist/admin/components/AdminCatalogPreviewProvider.js +74 -0
- package/dist/admin/components/AdminCatalogPreviewProvider.js.map +1 -0
- package/dist/admin/components/AdminCmsAssetProvider.d.ts +9 -0
- package/dist/admin/components/AdminCmsAssetProvider.d.ts.map +1 -0
- package/dist/admin/components/AdminCmsAssetProvider.js +50 -0
- package/dist/admin/components/AdminCmsAssetProvider.js.map +1 -0
- package/dist/admin/components/BackgroundFields.d.ts +4 -0
- package/dist/admin/components/BackgroundFields.d.ts.map +1 -0
- package/dist/admin/components/BackgroundFields.js +40 -0
- package/dist/admin/components/BackgroundFields.js.map +1 -0
- package/dist/admin/components/ButtonLinkFields.d.ts +6 -0
- package/dist/admin/components/ButtonLinkFields.d.ts.map +1 -0
- package/dist/admin/components/ButtonLinkFields.js +127 -0
- package/dist/admin/components/ButtonLinkFields.js.map +1 -0
- package/dist/admin/components/CarouselPreviewNav.d.ts +12 -0
- package/dist/admin/components/CarouselPreviewNav.d.ts.map +1 -0
- package/dist/admin/components/CarouselPreviewNav.js +31 -0
- package/dist/admin/components/CarouselPreviewNav.js.map +1 -0
- package/dist/admin/components/CmsContentEditorLayout.d.ts +12 -0
- package/dist/admin/components/CmsContentEditorLayout.d.ts.map +1 -0
- package/dist/admin/components/CmsContentEditorLayout.js +9 -0
- package/dist/admin/components/CmsContentEditorLayout.js.map +1 -0
- package/dist/admin/components/ComponentDragHandle.d.ts +6 -0
- package/dist/admin/components/ComponentDragHandle.d.ts.map +1 -0
- package/dist/admin/components/ComponentDragHandle.js +119 -0
- package/dist/admin/components/ComponentDragHandle.js.map +1 -0
- package/dist/admin/components/ContentSliderActionBarExtras.d.ts +6 -0
- package/dist/admin/components/ContentSliderActionBarExtras.d.ts.map +1 -0
- package/dist/admin/components/ContentSliderActionBarExtras.js +109 -0
- package/dist/admin/components/ContentSliderActionBarExtras.js.map +1 -0
- package/dist/admin/components/HookBlockAttachmentsPanel.d.ts +9 -0
- package/dist/admin/components/HookBlockAttachmentsPanel.d.ts.map +1 -0
- package/dist/admin/components/HookBlockAttachmentsPanel.js +137 -0
- package/dist/admin/components/HookBlockAttachmentsPanel.js.map +1 -0
- package/dist/admin/components/PageBuilderActionBar.d.ts +10 -0
- package/dist/admin/components/PageBuilderActionBar.d.ts.map +1 -0
- package/dist/admin/components/PageBuilderActionBar.js +118 -0
- package/dist/admin/components/PageBuilderActionBar.js.map +1 -0
- package/dist/admin/components/PageBuilderDrawer.d.ts +16 -0
- package/dist/admin/components/PageBuilderDrawer.d.ts.map +1 -0
- package/dist/admin/components/PageBuilderDrawer.js +53 -0
- package/dist/admin/components/PageBuilderDrawer.js.map +1 -0
- package/dist/admin/components/PageBuilderEditor.d.ts +45 -0
- package/dist/admin/components/PageBuilderEditor.d.ts.map +1 -0
- package/dist/admin/components/PageBuilderEditor.js +632 -0
- package/dist/admin/components/PageBuilderEditor.js.map +1 -0
- package/dist/admin/components/PuckActionGuard.d.ts +12 -0
- package/dist/admin/components/PuckActionGuard.d.ts.map +1 -0
- package/dist/admin/components/PuckActionGuard.js +30 -0
- package/dist/admin/components/PuckActionGuard.js.map +1 -0
- package/dist/admin/components/RowLayoutPicker.d.ts +8 -0
- package/dist/admin/components/RowLayoutPicker.d.ts.map +1 -0
- package/dist/admin/components/RowLayoutPicker.js +17 -0
- package/dist/admin/components/RowLayoutPicker.js.map +1 -0
- package/dist/admin/components/SliderPreviewActionBarExtras.d.ts +6 -0
- package/dist/admin/components/SliderPreviewActionBarExtras.d.ts.map +1 -0
- package/dist/admin/components/SliderPreviewActionBarExtras.js +32 -0
- package/dist/admin/components/SliderPreviewActionBarExtras.js.map +1 -0
- package/dist/admin/components/admin-catalog-preview-map.d.ts +17 -0
- package/dist/admin/components/admin-catalog-preview-map.d.ts.map +1 -0
- package/dist/admin/components/admin-catalog-preview-map.js +18 -0
- package/dist/admin/components/admin-catalog-preview-map.js.map +1 -0
- package/dist/admin/components/build-viewports.d.ts +23 -0
- package/dist/admin/components/build-viewports.d.ts.map +1 -0
- package/dist/admin/components/build-viewports.js +23 -0
- package/dist/admin/components/build-viewports.js.map +1 -0
- package/dist/admin/components/cms-template-layout.d.ts +16 -0
- package/dist/admin/components/cms-template-layout.d.ts.map +1 -0
- package/dist/admin/components/cms-template-layout.js +53 -0
- package/dist/admin/components/cms-template-layout.js.map +1 -0
- package/dist/admin/components/page-builder-i18n.d.ts +27 -0
- package/dist/admin/components/page-builder-i18n.d.ts.map +1 -0
- package/dist/admin/components/page-builder-i18n.js +34 -0
- package/dist/admin/components/page-builder-i18n.js.map +1 -0
- package/dist/admin/components/puck-safe.d.ts +10 -0
- package/dist/admin/components/puck-safe.d.ts.map +1 -0
- package/dist/admin/components/puck-safe.js +22 -0
- package/dist/admin/components/puck-safe.js.map +1 -0
- package/dist/admin/components/scope-utils.d.ts +4 -0
- package/dist/admin/components/scope-utils.d.ts.map +1 -0
- package/dist/admin/components/scope-utils.js +7 -0
- package/dist/admin/components/scope-utils.js.map +1 -0
- package/dist/admin/editors/BlockEditor.d.ts +9 -0
- package/dist/admin/editors/BlockEditor.d.ts.map +1 -0
- package/dist/admin/editors/BlockEditor.js +217 -0
- package/dist/admin/editors/BlockEditor.js.map +1 -0
- package/dist/admin/editors/PageEditor.d.ts +9 -0
- package/dist/admin/editors/PageEditor.d.ts.map +1 -0
- package/dist/admin/editors/PageEditor.js +316 -0
- package/dist/admin/editors/PageEditor.js.map +1 -0
- package/dist/admin/editors/TemplateEditor.d.ts +9 -0
- package/dist/admin/editors/TemplateEditor.d.ts.map +1 -0
- package/dist/admin/editors/TemplateEditor.js +180 -0
- package/dist/admin/editors/TemplateEditor.js.map +1 -0
- package/dist/admin/index.d.ts +38 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +144 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/BlocksListPage.d.ts +9 -0
- package/dist/admin/pages/BlocksListPage.d.ts.map +1 -0
- package/dist/admin/pages/BlocksListPage.js +47 -0
- package/dist/admin/pages/BlocksListPage.js.map +1 -0
- package/dist/admin/pages/HooksPage.d.ts +9 -0
- package/dist/admin/pages/HooksPage.d.ts.map +1 -0
- package/dist/admin/pages/HooksPage.js +41 -0
- package/dist/admin/pages/HooksPage.js.map +1 -0
- package/dist/admin/pages/PagesListPage.d.ts +9 -0
- package/dist/admin/pages/PagesListPage.d.ts.map +1 -0
- package/dist/admin/pages/PagesListPage.js +51 -0
- package/dist/admin/pages/PagesListPage.js.map +1 -0
- package/dist/admin/pages/TemplatesListPage.d.ts +9 -0
- package/dist/admin/pages/TemplatesListPage.d.ts.map +1 -0
- package/dist/admin/pages/TemplatesListPage.js +47 -0
- package/dist/admin/pages/TemplatesListPage.js.map +1 -0
- package/dist/admin-ui/index.d.ts +90 -0
- package/dist/admin-ui/index.d.ts.map +1 -0
- package/dist/admin-ui/index.js +89 -0
- package/dist/admin-ui/index.js.map +1 -0
- package/dist/backend/cli/block-names.d.ts +92 -0
- package/dist/backend/cli/block-names.d.ts.map +1 -0
- package/dist/backend/cli/block-names.js +132 -0
- package/dist/backend/cli/block-names.js.map +1 -0
- package/dist/backend/entities/cms-block.entity.d.ts +20 -0
- package/dist/backend/entities/cms-block.entity.d.ts.map +1 -0
- package/dist/backend/entities/cms-block.entity.js +77 -0
- package/dist/backend/entities/cms-block.entity.js.map +1 -0
- package/dist/backend/entities/cms-hook-block-attachment.entity.d.ts +15 -0
- package/dist/backend/entities/cms-hook-block-attachment.entity.d.ts.map +1 -0
- package/dist/backend/entities/cms-hook-block-attachment.entity.js +46 -0
- package/dist/backend/entities/cms-hook-block-attachment.entity.js.map +1 -0
- package/dist/backend/entities/cms-hook.entity.d.ts +20 -0
- package/dist/backend/entities/cms-hook.entity.d.ts.map +1 -0
- package/dist/backend/entities/cms-hook.entity.js +73 -0
- package/dist/backend/entities/cms-hook.entity.js.map +1 -0
- package/dist/backend/entities/cms-page.entity.d.ts +43 -0
- package/dist/backend/entities/cms-page.entity.d.ts.map +1 -0
- package/dist/backend/entities/cms-page.entity.js +140 -0
- package/dist/backend/entities/cms-page.entity.js.map +1 -0
- package/dist/backend/entities/cms-template.entity.d.ts +20 -0
- package/dist/backend/entities/cms-template.entity.d.ts.map +1 -0
- package/dist/backend/entities/cms-template.entity.js +73 -0
- package/dist/backend/entities/cms-template.entity.js.map +1 -0
- package/dist/backend/index.d.ts +157 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +317 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/plugin.d.ts +81 -0
- package/dist/backend/plugin.d.ts.map +1 -0
- package/dist/backend/plugin.js +81 -0
- package/dist/backend/plugin.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +19 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +164 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.storefront.d.ts +6 -0
- package/dist/backend/routes.storefront.d.ts.map +1 -0
- package/dist/backend/routes.storefront.js +89 -0
- package/dist/backend/routes.storefront.js.map +1 -0
- package/dist/backend/services/asset-embed-resolver.d.ts +17 -0
- package/dist/backend/services/asset-embed-resolver.d.ts.map +1 -0
- package/dist/backend/services/asset-embed-resolver.js +40 -0
- package/dist/backend/services/asset-embed-resolver.js.map +1 -0
- package/dist/backend/services/asset-references.d.ts +4 -0
- package/dist/backend/services/asset-references.d.ts.map +1 -0
- package/dist/backend/services/asset-references.js +55 -0
- package/dist/backend/services/asset-references.js.map +1 -0
- package/dist/backend/services/cms-block-read-port.d.ts +27 -0
- package/dist/backend/services/cms-block-read-port.d.ts.map +1 -0
- package/dist/backend/services/cms-block-read-port.js +50 -0
- package/dist/backend/services/cms-block-read-port.js.map +1 -0
- package/dist/backend/services/cms-block-seed-port.d.ts +31 -0
- package/dist/backend/services/cms-block-seed-port.d.ts.map +1 -0
- package/dist/backend/services/cms-block-seed-port.js +68 -0
- package/dist/backend/services/cms-block-seed-port.js.map +1 -0
- package/dist/backend/services/cms-block-service.d.ts +38 -0
- package/dist/backend/services/cms-block-service.d.ts.map +1 -0
- package/dist/backend/services/cms-block-service.js +218 -0
- package/dist/backend/services/cms-block-service.js.map +1 -0
- package/dist/backend/services/cms-cache.d.ts +54 -0
- package/dist/backend/services/cms-cache.d.ts.map +1 -0
- package/dist/backend/services/cms-cache.js +113 -0
- package/dist/backend/services/cms-cache.js.map +1 -0
- package/dist/backend/services/cms-hook-service.d.ts +35 -0
- package/dist/backend/services/cms-hook-service.d.ts.map +1 -0
- package/dist/backend/services/cms-hook-service.js +216 -0
- package/dist/backend/services/cms-hook-service.js.map +1 -0
- package/dist/backend/services/cms-language-reference.d.ts +11 -0
- package/dist/backend/services/cms-language-reference.d.ts.map +1 -0
- package/dist/backend/services/cms-language-reference.js +26 -0
- package/dist/backend/services/cms-language-reference.js.map +1 -0
- package/dist/backend/services/cms-page-read-port.d.ts +23 -0
- package/dist/backend/services/cms-page-read-port.d.ts.map +1 -0
- package/dist/backend/services/cms-page-read-port.js +54 -0
- package/dist/backend/services/cms-page-read-port.js.map +1 -0
- package/dist/backend/services/cms-page-service.d.ts +104 -0
- package/dist/backend/services/cms-page-service.d.ts.map +1 -0
- package/dist/backend/services/cms-page-service.js +468 -0
- package/dist/backend/services/cms-page-service.js.map +1 -0
- package/dist/backend/services/cms-reference-registry.d.ts +30 -0
- package/dist/backend/services/cms-reference-registry.d.ts.map +1 -0
- package/dist/backend/services/cms-reference-registry.js +98 -0
- package/dist/backend/services/cms-reference-registry.js.map +1 -0
- package/dist/backend/services/cms-template-service.d.ts +37 -0
- package/dist/backend/services/cms-template-service.d.ts.map +1 -0
- package/dist/backend/services/cms-template-service.js +205 -0
- package/dist/backend/services/cms-template-service.js.map +1 -0
- package/dist/backend/services/content-tree-walker.d.ts +7 -0
- package/dist/backend/services/content-tree-walker.d.ts.map +1 -0
- package/dist/backend/services/content-tree-walker.js +89 -0
- package/dist/backend/services/content-tree-walker.js.map +1 -0
- package/dist/backend/services/page-builder-registry.d.ts +120 -0
- package/dist/backend/services/page-builder-registry.d.ts.map +1 -0
- package/dist/backend/services/page-builder-registry.js +220 -0
- package/dist/backend/services/page-builder-registry.js.map +1 -0
- package/dist/backend/services/seed-hooks.d.ts +22 -0
- package/dist/backend/services/seed-hooks.d.ts.map +1 -0
- package/dist/backend/services/seed-hooks.js +94 -0
- package/dist/backend/services/seed-hooks.js.map +1 -0
- package/dist/backend/services/storefront-resolver.d.ts +71 -0
- package/dist/backend/services/storefront-resolver.d.ts.map +1 -0
- package/dist/backend/services/storefront-resolver.js +329 -0
- package/dist/backend/services/storefront-resolver.js.map +1 -0
- package/dist/manifest.d.ts +225 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +695 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260425T162418_cms_pages_init.d.ts +10 -0
- package/dist/migrations/20260425T162418_cms_pages_init.d.ts.map +1 -0
- package/dist/migrations/20260425T162418_cms_pages_init.js +30 -0
- package/dist/migrations/20260425T162418_cms_pages_init.js.map +1 -0
- package/dist/migrations/20260505T130214_cms_init.d.ts +28 -0
- package/dist/migrations/20260505T130214_cms_init.d.ts.map +1 -0
- package/dist/migrations/20260505T130214_cms_init.js +332 -0
- package/dist/migrations/20260505T130214_cms_init.js.map +1 -0
- package/dist/migrations/20260903T101741_cms_namespace_block_names.d.ts +6 -0
- package/dist/migrations/20260903T101741_cms_namespace_block_names.d.ts.map +1 -0
- package/dist/migrations/20260903T101741_cms_namespace_block_names.js +60 -0
- package/dist/migrations/20260903T101741_cms_namespace_block_names.js.map +1 -0
- package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.d.ts +27 -0
- package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.d.ts.map +1 -0
- package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.js +44 -0
- package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.js.map +1 -0
- package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.d.ts +32 -0
- package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.d.ts.map +1 -0
- package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.js +36 -0
- package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.js.map +1 -0
- package/dist/migrations/index.d.ts +31 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +37 -0
- package/dist/migrations/index.js.map +1 -0
- package/docs/cms/extending-page-builder.md +256 -0
- package/docs/cms/index.md +233 -0
- package/i18n/en.json +231 -0
- package/i18n/pl.json +231 -0
- package/package.json +125 -3
- package/tailwind.css +16 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
import { ERROR_CODES, firstSlugSegment, } from '@endora-commerce/contracts';
|
|
3
|
+
import { HttpError } from '@endora-commerce/platform/http';
|
|
4
|
+
import { SalesChannel } from '@endora-commerce/platform/kernel';
|
|
5
|
+
import { walkBlockEmbeds, walkUnknownComponents } from './content-tree-walker.js';
|
|
6
|
+
const emptyContent = { languages: {} };
|
|
7
|
+
/**
|
|
8
|
+
* The reserved set as the refusal reads it, from the value an operator typed.
|
|
9
|
+
*
|
|
10
|
+
* The Setting is free-form JSON, so this is forgiving in the three ways an
|
|
11
|
+
* operator's list is likely to be wrong and in no other: `"/cart"` and
|
|
12
|
+
* `"Cart"` and `"checkout/pay"` all mean the segment `cart`, `cart` and
|
|
13
|
+
* `checkout`. A non-string entry is dropped rather than stringified — an
|
|
14
|
+
* operator who typed `["cart", 7]` reserved one segment, not two, and
|
|
15
|
+
* `"7"` reserving a path is a rule nobody wrote.
|
|
16
|
+
*/
|
|
17
|
+
export function normalizeReservedSegments(value) {
|
|
18
|
+
if (!Array.isArray(value))
|
|
19
|
+
return [];
|
|
20
|
+
const out = new Set();
|
|
21
|
+
for (const entry of value) {
|
|
22
|
+
if (typeof entry !== 'string')
|
|
23
|
+
continue;
|
|
24
|
+
const segment = firstSlugSegment(entry.trim());
|
|
25
|
+
if (segment.length > 0)
|
|
26
|
+
out.add(segment);
|
|
27
|
+
}
|
|
28
|
+
return [...out];
|
|
29
|
+
}
|
|
30
|
+
export class CmsPageService {
|
|
31
|
+
emFactory;
|
|
32
|
+
knownComponentNames;
|
|
33
|
+
cache;
|
|
34
|
+
references;
|
|
35
|
+
/**
|
|
36
|
+
* Absent until `registerModule` installs it, and absent means "nothing is
|
|
37
|
+
* reserved". That is the manifest's own default (`defaultValue: []`), so an
|
|
38
|
+
* unwired service and a deployment that reserves nothing answer alike — and
|
|
39
|
+
* a *failing* read is not this state: it propagates, see `reservedSegments`.
|
|
40
|
+
*/
|
|
41
|
+
reservedSegmentsResolver = null;
|
|
42
|
+
constructor(emFactory, knownComponentNames, cache, references) {
|
|
43
|
+
this.emFactory = emFactory;
|
|
44
|
+
this.knownComponentNames = knownComponentNames;
|
|
45
|
+
this.cache = cache;
|
|
46
|
+
this.references = references;
|
|
47
|
+
}
|
|
48
|
+
setReservedSegmentsResolver(resolver) {
|
|
49
|
+
this.reservedSegmentsResolver = resolver;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The deployment's reserved first path segments — the **one** value the
|
|
53
|
+
* save-time refusal below and the editor's inline warning both read
|
|
54
|
+
* (FR-033). Two lists would be two answers waiting to disagree, and a warning
|
|
55
|
+
* that disagrees with a refusal is worse than no warning.
|
|
56
|
+
*/
|
|
57
|
+
async reservedSegments() {
|
|
58
|
+
if (!this.reservedSegmentsResolver)
|
|
59
|
+
return [];
|
|
60
|
+
return normalizeReservedSegments(await this.reservedSegmentsResolver());
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* FR-031 — refuse a slug whose first segment the deployment reserves.
|
|
64
|
+
*
|
|
65
|
+
* Nothing here creates precedence and nothing may (`contracts/cms-page-url.md`
|
|
66
|
+
* §5.0): the storefront's route already wins, measured, with no mechanism.
|
|
67
|
+
* What this removes is the **silence** — a page that saves, publishes and is
|
|
68
|
+
* never served while the operator is told nothing, which is a defect
|
|
69
|
+
* indistinguishable from a legitimate state because the URL answers 200 with
|
|
70
|
+
* somebody else's content.
|
|
71
|
+
*
|
|
72
|
+
* The offending segment travels in `details` so the envelope can fill the
|
|
73
|
+
* `{segment}` placeholder in the operator's own language (§5.4): the code for
|
|
74
|
+
* a consumer to branch on, the sentence for the operator to read.
|
|
75
|
+
*/
|
|
76
|
+
async assertSlugNotReserved(slug) {
|
|
77
|
+
const segment = firstSlugSegment(slug);
|
|
78
|
+
if (segment.length === 0)
|
|
79
|
+
return;
|
|
80
|
+
const reserved = await this.reservedSegments();
|
|
81
|
+
if (!reserved.includes(segment))
|
|
82
|
+
return;
|
|
83
|
+
throw new HttpError(409, ERROR_CODES.CMS_SLUG_RESERVED, `The first path segment "${segment}" is reserved by this storefront.`, { segment });
|
|
84
|
+
}
|
|
85
|
+
async invalidateForPageId(pageId) {
|
|
86
|
+
if (!this.cache)
|
|
87
|
+
return;
|
|
88
|
+
const rows = (await this.emFactory().execute(`select slug from cms_page_sales_channels where page_id = ?
|
|
89
|
+
union
|
|
90
|
+
select slug from cms_pages where id = ?`, [pageId, pageId]));
|
|
91
|
+
const slugs = new Set(rows.map((r) => r.slug).filter((s) => s && s.length > 0));
|
|
92
|
+
if (slugs.size > 0)
|
|
93
|
+
await this.cache.invalidatePagesBySlug(slugs);
|
|
94
|
+
}
|
|
95
|
+
async invalidateForSlugs(slugs) {
|
|
96
|
+
if (!this.cache)
|
|
97
|
+
return;
|
|
98
|
+
const filtered = Array.from(slugs).filter((s) => s && s.length > 0);
|
|
99
|
+
if (filtered.length > 0)
|
|
100
|
+
await this.cache.invalidatePagesBySlug(filtered);
|
|
101
|
+
}
|
|
102
|
+
async list(filters = {}) {
|
|
103
|
+
const em = this.emFactory();
|
|
104
|
+
const params = [];
|
|
105
|
+
const where = [];
|
|
106
|
+
if (filters.salesChannelId) {
|
|
107
|
+
params.push(filters.salesChannelId);
|
|
108
|
+
where.push(`exists (
|
|
109
|
+
select 1 from cms_page_sales_channels cpsc
|
|
110
|
+
where cpsc.page_id = p.id and cpsc.sales_channel_id = ?
|
|
111
|
+
)`);
|
|
112
|
+
}
|
|
113
|
+
if (filters.status) {
|
|
114
|
+
params.push(filters.status);
|
|
115
|
+
where.push('p.status = ?');
|
|
116
|
+
}
|
|
117
|
+
if (filters.q) {
|
|
118
|
+
params.push(`%${filters.q.toLowerCase()}%`);
|
|
119
|
+
where.push('(lower(p.name) like ? or lower(p.slug) like ?)');
|
|
120
|
+
params.push(`%${filters.q.toLowerCase()}%`);
|
|
121
|
+
}
|
|
122
|
+
const rows = (await em.execute(`select p.* from cms_pages p
|
|
123
|
+
${where.length > 0 ? `where ${where.join(' and ')}` : ''}
|
|
124
|
+
order by p.updated_at desc
|
|
125
|
+
limit 50`, params));
|
|
126
|
+
const data = await Promise.all(rows.map((row) => this.toSummary(row)));
|
|
127
|
+
return { data, nextCursor: null };
|
|
128
|
+
}
|
|
129
|
+
async create(input) {
|
|
130
|
+
// Before the transaction, deliberately: this is a judgement on the input
|
|
131
|
+
// against the deployment's configuration and touches no row, so opening a
|
|
132
|
+
// transaction to refuse it would hold a connection for the length of a
|
|
133
|
+
// settings read.
|
|
134
|
+
await this.assertSlugNotReserved(input.slug);
|
|
135
|
+
const em = this.emFactory();
|
|
136
|
+
const id = randomUUID();
|
|
137
|
+
const now = new Date();
|
|
138
|
+
const meta = this.splitMeta(input.meta ?? null);
|
|
139
|
+
const title = Object.fromEntries(input.languages.map((language) => [
|
|
140
|
+
language,
|
|
141
|
+
input.meta?.[language]?.title?.trim() || input.name,
|
|
142
|
+
]));
|
|
143
|
+
const body = Object.fromEntries(input.languages.map((language) => [language, '']));
|
|
144
|
+
await em.transactional(async (tx) => {
|
|
145
|
+
await this.assertLanguagesInChannelScope(tx, input.languages, input.salesChannelIds);
|
|
146
|
+
await this.assertSlugAvailable(tx, input.slug, input.salesChannelIds);
|
|
147
|
+
await tx.execute(`insert into cms_pages
|
|
148
|
+
(id, path, status, title, body, published_at, archived_at, created_at, updated_at,
|
|
149
|
+
name, slug, active, description, meta_title, meta_description, meta_keywords,
|
|
150
|
+
content, languages, version)
|
|
151
|
+
values (?, ?, 'draft', ?::jsonb, ?::jsonb, null, null, ?, ?,
|
|
152
|
+
?, ?, ?, ?, ?::jsonb, ?::jsonb, ?::jsonb, ?::jsonb, ?::jsonb, 1)`, [
|
|
153
|
+
id,
|
|
154
|
+
this.legacyPath(input.slug, id),
|
|
155
|
+
JSON.stringify(title),
|
|
156
|
+
JSON.stringify(body),
|
|
157
|
+
now,
|
|
158
|
+
now,
|
|
159
|
+
input.name,
|
|
160
|
+
input.slug,
|
|
161
|
+
input.active ?? true,
|
|
162
|
+
input.description ?? null,
|
|
163
|
+
JSON.stringify(meta.metaTitle),
|
|
164
|
+
JSON.stringify(meta.metaDescription),
|
|
165
|
+
JSON.stringify(meta.metaKeywords),
|
|
166
|
+
JSON.stringify(emptyContent),
|
|
167
|
+
JSON.stringify(input.languages),
|
|
168
|
+
]);
|
|
169
|
+
await this.replaceChannelScope(tx, id, input.salesChannelIds, input.slug);
|
|
170
|
+
});
|
|
171
|
+
await this.invalidateForSlugs([input.slug]);
|
|
172
|
+
return this.get(id);
|
|
173
|
+
}
|
|
174
|
+
async get(id) {
|
|
175
|
+
const row = await this.findRow(id);
|
|
176
|
+
if (!row)
|
|
177
|
+
throw new HttpError(404, ERROR_CODES.CMS_PAGE_NOT_FOUND, 'CMS Page not found.');
|
|
178
|
+
return this.toDetail(row);
|
|
179
|
+
}
|
|
180
|
+
async patch(id, input) {
|
|
181
|
+
// Only when the request **writes** a slug. A patch that renames a page or
|
|
182
|
+
// edits its meta description is not choosing an address, and refusing it
|
|
183
|
+
// would make every page whose slug predates the deployment's reserved set
|
|
184
|
+
// uneditable — a rule that punishes the operator for a decision somebody
|
|
185
|
+
// else made later.
|
|
186
|
+
if (input.slug !== undefined)
|
|
187
|
+
await this.assertSlugNotReserved(input.slug);
|
|
188
|
+
const em = this.emFactory();
|
|
189
|
+
const slugsToInvalidate = new Set();
|
|
190
|
+
await em.transactional(async (tx) => {
|
|
191
|
+
const row = await this.findRow(id, tx);
|
|
192
|
+
if (!row)
|
|
193
|
+
throw new HttpError(404, ERROR_CODES.CMS_PAGE_NOT_FOUND, 'CMS Page not found.');
|
|
194
|
+
this.assertVersion(row, input.version);
|
|
195
|
+
slugsToInvalidate.add(row.slug);
|
|
196
|
+
const nextSlug = input.slug ?? row.slug;
|
|
197
|
+
const nextChannels = input.salesChannelIds ?? (await this.channelIdsFor(id, tx));
|
|
198
|
+
const nextLanguages = input.languages ?? row.languages;
|
|
199
|
+
await this.assertLanguagesInChannelScope(tx, nextLanguages, nextChannels);
|
|
200
|
+
if (input.slug || input.salesChannelIds) {
|
|
201
|
+
await this.assertSlugAvailable(tx, nextSlug, nextChannels, id);
|
|
202
|
+
}
|
|
203
|
+
const meta = input.meta !== undefined ? this.splitMeta(input.meta ?? null) : null;
|
|
204
|
+
const sets = [];
|
|
205
|
+
const params = [];
|
|
206
|
+
const set = (sql, value) => {
|
|
207
|
+
sets.push(sql);
|
|
208
|
+
params.push(value);
|
|
209
|
+
};
|
|
210
|
+
if (input.name !== undefined)
|
|
211
|
+
set('name = ?', input.name);
|
|
212
|
+
if (input.slug !== undefined)
|
|
213
|
+
set('slug = ?', input.slug);
|
|
214
|
+
if (input.active !== undefined)
|
|
215
|
+
set('active = ?', input.active);
|
|
216
|
+
if (input.description !== undefined)
|
|
217
|
+
set('description = ?', input.description);
|
|
218
|
+
if (input.languages !== undefined)
|
|
219
|
+
set('languages = ?::jsonb', JSON.stringify(input.languages));
|
|
220
|
+
if (meta) {
|
|
221
|
+
set('meta_title = ?::jsonb', JSON.stringify(meta.metaTitle));
|
|
222
|
+
set('meta_description = ?::jsonb', JSON.stringify(meta.metaDescription));
|
|
223
|
+
set('meta_keywords = ?::jsonb', JSON.stringify(meta.metaKeywords));
|
|
224
|
+
}
|
|
225
|
+
if (sets.length > 0) {
|
|
226
|
+
params.push(id);
|
|
227
|
+
await tx.execute(`update cms_pages
|
|
228
|
+
set ${sets.join(', ')}, version = version + 1, updated_at = now()
|
|
229
|
+
where id = ?`, params);
|
|
230
|
+
}
|
|
231
|
+
if (input.salesChannelIds || input.slug) {
|
|
232
|
+
await this.replaceChannelScope(tx, id, nextChannels, nextSlug);
|
|
233
|
+
}
|
|
234
|
+
slugsToInvalidate.add(nextSlug);
|
|
235
|
+
});
|
|
236
|
+
await this.invalidateForSlugs(slugsToInvalidate);
|
|
237
|
+
return this.get(id);
|
|
238
|
+
}
|
|
239
|
+
async setContent(id, language, data, version) {
|
|
240
|
+
const em = this.emFactory();
|
|
241
|
+
await em.transactional(async (tx) => {
|
|
242
|
+
const row = await this.findRow(id, tx);
|
|
243
|
+
if (!row)
|
|
244
|
+
throw new HttpError(404, ERROR_CODES.CMS_PAGE_NOT_FOUND, 'CMS Page not found.');
|
|
245
|
+
this.assertVersion(row, version);
|
|
246
|
+
const unknown = walkUnknownComponents(data, new Set(this.knownComponentNames()));
|
|
247
|
+
if (unknown.size > 0) {
|
|
248
|
+
console.warn(`CMS page ${id} saved with unknown components: ${Array.from(unknown).join(', ')}`);
|
|
249
|
+
}
|
|
250
|
+
await this.assertBlockEmbedsExist(tx, data, await this.channelIdsFor(id, tx));
|
|
251
|
+
const content = {
|
|
252
|
+
languages: {
|
|
253
|
+
...(row.content.languages ?? {}),
|
|
254
|
+
[language]: data,
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
if (!row.languages.includes(language)) {
|
|
258
|
+
throw new HttpError(400, ERROR_CODES.CMS_LANGUAGE_NOT_IN_CHANNEL_SCOPE, `CMS Page language "${language}" is not assigned to this page.`);
|
|
259
|
+
}
|
|
260
|
+
await tx.execute(`update cms_pages
|
|
261
|
+
set content = ?::jsonb, version = version + 1, updated_at = now()
|
|
262
|
+
where id = ?`, [JSON.stringify(content), id]);
|
|
263
|
+
});
|
|
264
|
+
await this.invalidateForPageId(id);
|
|
265
|
+
return this.get(id);
|
|
266
|
+
}
|
|
267
|
+
async publish(id) {
|
|
268
|
+
return this.transition(id, 'published');
|
|
269
|
+
}
|
|
270
|
+
async archive(id) {
|
|
271
|
+
return this.transition(id, 'archived');
|
|
272
|
+
}
|
|
273
|
+
async unarchive(id) {
|
|
274
|
+
return this.transition(id, 'draft');
|
|
275
|
+
}
|
|
276
|
+
async delete(id) {
|
|
277
|
+
if (this.references) {
|
|
278
|
+
const refs = await this.references.findPageReferences(id);
|
|
279
|
+
if (refs.length > 0) {
|
|
280
|
+
throw new HttpError(409, ERROR_CODES.CMS_REFERENCED, 'CMS Page is referenced.');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
await this.invalidateForPageId(id);
|
|
284
|
+
await this.emFactory().execute('delete from cms_pages where id = ?', [id]);
|
|
285
|
+
}
|
|
286
|
+
async transition(id, status) {
|
|
287
|
+
const em = this.emFactory();
|
|
288
|
+
const row = await this.findRow(id, em);
|
|
289
|
+
if (!row)
|
|
290
|
+
throw new HttpError(404, ERROR_CODES.CMS_PAGE_NOT_FOUND, 'CMS Page not found.');
|
|
291
|
+
await em.execute(`update cms_pages
|
|
292
|
+
set status = ?,
|
|
293
|
+
published_at = case when ? = 'published' then now() else published_at end,
|
|
294
|
+
archived_at = case when ? = 'archived' then now() else null end,
|
|
295
|
+
version = version + 1,
|
|
296
|
+
updated_at = now()
|
|
297
|
+
where id = ?`, [status, status, status, id]);
|
|
298
|
+
await this.invalidateForPageId(id);
|
|
299
|
+
return this.get(id);
|
|
300
|
+
}
|
|
301
|
+
async findRow(id, em = this.emFactory()) {
|
|
302
|
+
const rows = (await em.execute('select * from cms_pages where id = ?', [
|
|
303
|
+
id,
|
|
304
|
+
]));
|
|
305
|
+
return rows[0] ?? null;
|
|
306
|
+
}
|
|
307
|
+
async assertSlugAvailable(em, slug, salesChannelIds, exceptPageId) {
|
|
308
|
+
if (salesChannelIds.length === 0)
|
|
309
|
+
return;
|
|
310
|
+
const placeholders = salesChannelIds.map(() => '?').join(', ');
|
|
311
|
+
const rows = (await em.execute(`select page_id from cms_page_sales_channels
|
|
312
|
+
where slug = ? and sales_channel_id in (${placeholders})
|
|
313
|
+
${exceptPageId ? 'and page_id <> ?' : ''}
|
|
314
|
+
limit 1`, exceptPageId ? [slug, ...salesChannelIds, exceptPageId] : [slug, ...salesChannelIds]));
|
|
315
|
+
if (rows.length > 0) {
|
|
316
|
+
throw new HttpError(409, ERROR_CODES.CMS_SLUG_CONFLICT, 'CMS Page slug already exists.');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
channelLanguageCodes(value) {
|
|
320
|
+
if (Array.isArray(value)) {
|
|
321
|
+
return value.filter((item) => typeof item === 'string');
|
|
322
|
+
}
|
|
323
|
+
if (typeof value === 'string') {
|
|
324
|
+
try {
|
|
325
|
+
const parsed = JSON.parse(value);
|
|
326
|
+
if (Array.isArray(parsed)) {
|
|
327
|
+
return parsed.filter((item) => typeof item === 'string');
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return [];
|
|
335
|
+
}
|
|
336
|
+
resolvedChannelLanguageCodes(languages, defaultLanguage) {
|
|
337
|
+
const codes = this.channelLanguageCodes(languages);
|
|
338
|
+
if (codes.length > 0)
|
|
339
|
+
return codes;
|
|
340
|
+
if (typeof defaultLanguage === 'string' && defaultLanguage.length > 0) {
|
|
341
|
+
return [defaultLanguage];
|
|
342
|
+
}
|
|
343
|
+
return [];
|
|
344
|
+
}
|
|
345
|
+
async assertLanguagesInChannelScope(em, languages, salesChannelIds) {
|
|
346
|
+
if (languages.length === 0 || salesChannelIds.length === 0)
|
|
347
|
+
return;
|
|
348
|
+
/**
|
|
349
|
+
* The kernel's own entity, not `select languages, default_language from
|
|
350
|
+
* sales_channels` (feature 075, D-87). `sales_channels` is the kernel's
|
|
351
|
+
* table since feature 072 moved the resolution machinery there, and a
|
|
352
|
+
* module relating into the kernel by ORM is the sanctioned access. The read
|
|
353
|
+
* stays on the caller's `em` so it still sees the transaction the write is
|
|
354
|
+
* being validated inside.
|
|
355
|
+
*/
|
|
356
|
+
const channels = await em.find(SalesChannel, { id: { $in: salesChannelIds } });
|
|
357
|
+
const allowed = new Set(channels.flatMap((channel) => this.resolvedChannelLanguageCodes(channel.languages, channel.defaultLanguage)));
|
|
358
|
+
const unsupported = languages.find((language) => !allowed.has(language));
|
|
359
|
+
if (unsupported) {
|
|
360
|
+
throw new HttpError(400, ERROR_CODES.CMS_LANGUAGE_NOT_IN_CHANNEL_SCOPE, `CMS Page language "${unsupported}" is not configured for the assigned sales channels.`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async replaceChannelScope(em, pageId, salesChannelIds, slug) {
|
|
364
|
+
await em.execute('delete from cms_page_sales_channels where page_id = ?', [
|
|
365
|
+
pageId,
|
|
366
|
+
]);
|
|
367
|
+
for (const salesChannelId of salesChannelIds) {
|
|
368
|
+
await em.execute(`insert into cms_page_sales_channels (page_id, sales_channel_id, slug)
|
|
369
|
+
values (?, ?, ?)`, [pageId, salesChannelId, slug]);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
async assertBlockEmbedsExist(em, data, salesChannelIds) {
|
|
373
|
+
const codes = Array.from(walkBlockEmbeds(data));
|
|
374
|
+
if (codes.length === 0 || salesChannelIds.length === 0)
|
|
375
|
+
return;
|
|
376
|
+
const codePlaceholders = codes.map(() => '?').join(', ');
|
|
377
|
+
const channelPlaceholders = salesChannelIds.map(() => '?').join(', ');
|
|
378
|
+
const rows = (await em.execute(`select distinct code
|
|
379
|
+
from cms_block_sales_channels
|
|
380
|
+
where code in (${codePlaceholders})
|
|
381
|
+
and sales_channel_id in (${channelPlaceholders})`, [...codes, ...salesChannelIds]));
|
|
382
|
+
const found = new Set(rows.map((row) => row.code));
|
|
383
|
+
const missing = codes.find((code) => !found.has(code));
|
|
384
|
+
if (missing) {
|
|
385
|
+
throw new HttpError(404, ERROR_CODES.CMS_BLOCK_NOT_FOUND, `CMS Block "${missing}" not found.`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
async channelIdsFor(pageId, em = this.emFactory()) {
|
|
389
|
+
const rows = (await em.execute('select sales_channel_id::text as id from cms_page_sales_channels where page_id = ?', [pageId]));
|
|
390
|
+
return rows.map((row) => row.id);
|
|
391
|
+
}
|
|
392
|
+
assertVersion(row, version) {
|
|
393
|
+
if (version !== undefined && version !== row.version) {
|
|
394
|
+
throw new HttpError(409, ERROR_CODES.VERSION_CONFLICT, 'CMS Page was updated concurrently.');
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
splitMeta(meta) {
|
|
398
|
+
const metaTitle = {};
|
|
399
|
+
const metaDescription = {};
|
|
400
|
+
const metaKeywords = {};
|
|
401
|
+
const entries = Object.entries(meta ?? {});
|
|
402
|
+
for (const [language, value] of entries) {
|
|
403
|
+
if (value.title !== undefined)
|
|
404
|
+
metaTitle[language] = value.title;
|
|
405
|
+
if (value.description !== undefined)
|
|
406
|
+
metaDescription[language] = value.description;
|
|
407
|
+
if (value.keywords !== undefined)
|
|
408
|
+
metaKeywords[language] = value.keywords;
|
|
409
|
+
}
|
|
410
|
+
return { metaTitle, metaDescription, metaKeywords };
|
|
411
|
+
}
|
|
412
|
+
async toSummary(row) {
|
|
413
|
+
return {
|
|
414
|
+
id: row.id,
|
|
415
|
+
name: row.name,
|
|
416
|
+
slug: row.slug,
|
|
417
|
+
status: row.status,
|
|
418
|
+
active: row.active,
|
|
419
|
+
description: row.description,
|
|
420
|
+
salesChannelIds: await this.channelIdsFor(row.id),
|
|
421
|
+
languages: row.languages,
|
|
422
|
+
version: row.version,
|
|
423
|
+
createdAt: this.iso(row.created_at),
|
|
424
|
+
updatedAt: this.iso(row.updated_at),
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
async toDetail(row) {
|
|
428
|
+
return {
|
|
429
|
+
...(await this.toSummary(row)),
|
|
430
|
+
meta: this.combineMeta(row),
|
|
431
|
+
content: {
|
|
432
|
+
languages: row.content.languages ?? {},
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
combineMeta(row) {
|
|
437
|
+
const languages = new Set([
|
|
438
|
+
...Object.keys(row.meta_title ?? {}),
|
|
439
|
+
...Object.keys(row.meta_description ?? {}),
|
|
440
|
+
...Object.keys(row.meta_keywords ?? {}),
|
|
441
|
+
]);
|
|
442
|
+
if (languages.size === 0)
|
|
443
|
+
return null;
|
|
444
|
+
const meta = {};
|
|
445
|
+
for (const language of languages) {
|
|
446
|
+
meta[language] = {
|
|
447
|
+
...(row.meta_title?.[language] !== undefined
|
|
448
|
+
? { title: row.meta_title[language] }
|
|
449
|
+
: {}),
|
|
450
|
+
...(row.meta_description?.[language] !== undefined
|
|
451
|
+
? { description: row.meta_description[language] }
|
|
452
|
+
: {}),
|
|
453
|
+
...(row.meta_keywords?.[language] !== undefined
|
|
454
|
+
? { keywords: row.meta_keywords[language] }
|
|
455
|
+
: {}),
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
return meta;
|
|
459
|
+
}
|
|
460
|
+
iso(value) {
|
|
461
|
+
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
|
|
462
|
+
}
|
|
463
|
+
legacyPath(slug, id) {
|
|
464
|
+
const suffix = id.slice(0, 8);
|
|
465
|
+
return `${slug}-${suffix}`.slice(0, 180);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
//# sourceMappingURL=cms-page-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cms-page-service.js","sourceRoot":"","sources":["../../../src/backend/services/cms-page-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CmsReference, CmsExternalReferenceScanner } from '@endora-commerce/contracts';
|
|
2
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
3
|
+
/**
|
|
4
|
+
* Both shapes moved to `@endora-commerce/contracts` in feature 075's Phase P — `megamenu`
|
|
5
|
+
* contributes a scanner, which makes the descriptor a boundary shape rather
|
|
6
|
+
* than an internal. Re-exported here for the length of Phase P, which cuts no
|
|
7
|
+
* consumer.
|
|
8
|
+
*/
|
|
9
|
+
export type { CmsReference, CmsExternalReferenceScanner };
|
|
10
|
+
export declare class CmsReferenceRegistry {
|
|
11
|
+
private readonly emFactory;
|
|
12
|
+
private readonly externalScanners;
|
|
13
|
+
constructor(emFactory: () => EntityManager);
|
|
14
|
+
/**
|
|
15
|
+
* Register an external scanner. Another module calls this from its own
|
|
16
|
+
* `ctx.onBoot`, so the contribution passes through the lifecycle seams rather
|
|
17
|
+
* than a composition root's back door. Idempotent across registrations of the
|
|
18
|
+
* same scanner instance.
|
|
19
|
+
*/
|
|
20
|
+
register(scanner: CmsExternalReferenceScanner): void;
|
|
21
|
+
/** The contributing module of every registered scanner, in registration order. */
|
|
22
|
+
externalOwners(): readonly string[];
|
|
23
|
+
/** Pages and modules that point at the Page with this id. */
|
|
24
|
+
findPageReferences(pageId: string): Promise<CmsReference[]>;
|
|
25
|
+
/** Pages, Templates, Hooks, and external modules that reference the Block. */
|
|
26
|
+
findBlockReferences(blockIdOrCode: string, blockCode?: string): Promise<CmsReference[]>;
|
|
27
|
+
/** Pages and Blocks that point at the Template with this code. */
|
|
28
|
+
findTemplateReferences(templateIdOrCode: string, templateCode?: string): Promise<CmsReference[]>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=cms-reference-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cms-reference-registry.d.ts","sourceRoot":"","sources":["../../../src/backend/services/cms-reference-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D;;;;;GAKG;AACH,YAAY,EAAE,YAAY,EAAE,2BAA2B,EAAE,CAAC;AAE1D,qBAAa,oBAAoB;IAGnB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqC;gBAEzC,SAAS,EAAE,MAAM,aAAa;IAE3D;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,IAAI;IAMpD,kFAAkF;IAClF,cAAc,IAAI,SAAS,MAAM,EAAE;IAInC,6DAA6D;IACvD,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAUjE,8EAA8E;IACxE,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAiD7F,kEAAkE;IAC5D,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAkCvG"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { walkBlockEmbeds, walkTemplateEmbeds } from './content-tree-walker.js';
|
|
2
|
+
export class CmsReferenceRegistry {
|
|
3
|
+
emFactory;
|
|
4
|
+
externalScanners = [];
|
|
5
|
+
constructor(emFactory) {
|
|
6
|
+
this.emFactory = emFactory;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Register an external scanner. Another module calls this from its own
|
|
10
|
+
* `ctx.onBoot`, so the contribution passes through the lifecycle seams rather
|
|
11
|
+
* than a composition root's back door. Idempotent across registrations of the
|
|
12
|
+
* same scanner instance.
|
|
13
|
+
*/
|
|
14
|
+
register(scanner) {
|
|
15
|
+
if (!this.externalScanners.includes(scanner)) {
|
|
16
|
+
this.externalScanners.push(scanner);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** The contributing module of every registered scanner, in registration order. */
|
|
20
|
+
externalOwners() {
|
|
21
|
+
return this.externalScanners.map((scanner) => scanner.ownerModuleId);
|
|
22
|
+
}
|
|
23
|
+
/** Pages and modules that point at the Page with this id. */
|
|
24
|
+
async findPageReferences(pageId) {
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const scanner of this.externalScanners) {
|
|
27
|
+
if (scanner.findPageReferences) {
|
|
28
|
+
out.push(...(await scanner.findPageReferences(pageId)));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
/** Pages, Templates, Hooks, and external modules that reference the Block. */
|
|
34
|
+
async findBlockReferences(blockIdOrCode, blockCode) {
|
|
35
|
+
// Backwards-compat: callers that supply only the code (the historical
|
|
36
|
+
// shape) skip the external scanners that need an id.
|
|
37
|
+
const code = blockCode ?? blockIdOrCode;
|
|
38
|
+
const blockId = blockCode === undefined ? null : blockIdOrCode;
|
|
39
|
+
const out = [];
|
|
40
|
+
const em = this.emFactory();
|
|
41
|
+
const pages = (await em.execute(`select id::text, name, content from cms_pages`));
|
|
42
|
+
for (const row of pages) {
|
|
43
|
+
if (walkBlockEmbeds(row.content).has(code)) {
|
|
44
|
+
out.push({ kind: 'cms_page', entityId: row.id, label: row.name });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const templates = (await em.execute(`select id::text, name, content from cms_templates`));
|
|
48
|
+
for (const row of templates) {
|
|
49
|
+
if (walkBlockEmbeds(row.content).has(code)) {
|
|
50
|
+
out.push({ kind: 'cms_template', entityId: row.id, label: row.name });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const hooks = (await em.execute(`select h.id::text, h.name
|
|
54
|
+
from cms_hook_block_attachments a
|
|
55
|
+
join cms_hooks h on h.id = a.hook_id
|
|
56
|
+
join cms_blocks b on b.id = a.block_id
|
|
57
|
+
where b.code = ?`, [code]));
|
|
58
|
+
for (const row of hooks) {
|
|
59
|
+
out.push({ kind: 'cms_hook', entityId: row.id, label: row.name });
|
|
60
|
+
}
|
|
61
|
+
if (blockId) {
|
|
62
|
+
for (const scanner of this.externalScanners) {
|
|
63
|
+
if (scanner.findBlockReferences) {
|
|
64
|
+
out.push(...(await scanner.findBlockReferences(blockId, code)));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/** Pages and Blocks that point at the Template with this code. */
|
|
71
|
+
async findTemplateReferences(templateIdOrCode, templateCode) {
|
|
72
|
+
const code = templateCode ?? templateIdOrCode;
|
|
73
|
+
const templateId = templateCode === undefined ? null : templateIdOrCode;
|
|
74
|
+
const out = [];
|
|
75
|
+
const em = this.emFactory();
|
|
76
|
+
const pages = (await em.execute(`select id::text, name, content from cms_pages`));
|
|
77
|
+
for (const row of pages) {
|
|
78
|
+
if (walkTemplateEmbeds(row.content).has(code)) {
|
|
79
|
+
out.push({ kind: 'cms_page', entityId: row.id, label: row.name });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const blocks = (await em.execute(`select id::text, name, content from cms_blocks`));
|
|
83
|
+
for (const row of blocks) {
|
|
84
|
+
if (walkTemplateEmbeds(row.content).has(code)) {
|
|
85
|
+
out.push({ kind: 'cms_block', entityId: row.id, label: row.name });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (templateId) {
|
|
89
|
+
for (const scanner of this.externalScanners) {
|
|
90
|
+
if (scanner.findTemplateReferences) {
|
|
91
|
+
out.push(...(await scanner.findTemplateReferences(templateId, code)));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=cms-reference-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cms-reference-registry.js","sourceRoot":"","sources":["../../../src/backend/services/cms-reference-registry.ts"],"names":[],"mappings":"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"}
|