@actuate-media/cms-core 0.19.0 → 0.20.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.
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Editable SEO config — DB-backed overrides for the static `actuate.config.ts`
3
+ * `seo` block + per-collection `CollectionSEOConfig`.
4
+ *
5
+ * Static config in `actuate.config.ts` is the source of truth at code level,
6
+ * but admins need to be able to change site name, default OG image, robots
7
+ * policy, default Schema.org types per collection, etc. without redeploying.
8
+ *
9
+ * Storage: a single Document row with `collection = '__seo_config__'` and
10
+ * `data.{site, collections}`. The leading double underscore makes the slug
11
+ * un-spellable as a normal collection (slugs are lowercased + dashed in the
12
+ * config validator), so it can never collide with a user collection.
13
+ *
14
+ * Merge semantics: DB values take precedence over static config, field by
15
+ * field. Removing a value in the UI (setting it to undefined / empty string)
16
+ * falls back to the static default — so the admin panel is purely additive,
17
+ * never destructive of code-level config.
18
+ */
19
+ import type { ActuateCMSConfig, CollectionSEOConfig, SiteSEOConfig } from '../config/types.js';
20
+ export declare const SEO_CONFIG_COLLECTION = "__seo_config__";
21
+ /**
22
+ * Shape of the overrides document stored in the DB. Every field is optional —
23
+ * a freshly-installed CMS has no row at all and the UI lazily creates one on
24
+ * first save.
25
+ */
26
+ export interface SeoConfigOverrides {
27
+ /** Site-wide overrides. Merged shallow-then-deep over static `config.seo`. */
28
+ site?: Partial<SiteSEOConfig>;
29
+ /** Per-collection overrides keyed by collection slug. */
30
+ collections?: Record<string, Partial<CollectionSEOConfig>>;
31
+ /** Last update timestamp (set by the writer). */
32
+ updatedAt?: string;
33
+ /** User id of the last editor (set by the writer). */
34
+ updatedBy?: string;
35
+ }
36
+ /** Read the SEO overrides document. Returns null when no row exists yet. */
37
+ export declare function getSeoOverrides(db: unknown): Promise<SeoConfigOverrides | null>;
38
+ /**
39
+ * Upsert the SEO overrides document. The caller is responsible for auth/role
40
+ * checks — this function only handles storage.
41
+ */
42
+ export declare function putSeoOverrides(db: unknown, overrides: SeoConfigOverrides, userId: string): Promise<SeoConfigOverrides>;
43
+ /**
44
+ * Merge static site-wide SEO config with the DB overrides. Nested objects
45
+ * (`robots`, `sitemap`, `ogImage`, `organization`) merge field-by-field;
46
+ * primitive values use override-wins-if-set.
47
+ */
48
+ export declare function mergeSiteSeoConfig(base: SiteSEOConfig | undefined, over: Partial<SiteSEOConfig> | undefined): SiteSEOConfig;
49
+ /** Same merge semantics as the site-wide version, applied to a single collection. */
50
+ export declare function mergeCollectionSeoConfig(base: CollectionSEOConfig | undefined, over: Partial<CollectionSEOConfig> | undefined): CollectionSEOConfig;
51
+ /**
52
+ * Return a new config object with DB-stored SEO overrides applied. The
53
+ * static config is never mutated — callers receive a shallow copy with
54
+ * `seo` and each collection's `seo` block replaced by the merged values.
55
+ *
56
+ * Routes that compose SEO output call this once per request, then thread
57
+ * the result through to `composePageMeta` / sitemap helpers exactly like
58
+ * the static config they replaced.
59
+ */
60
+ export declare function applySeoOverrides(config: ActuateCMSConfig | null | undefined, overrides: SeoConfigOverrides | null): ActuateCMSConfig | null;
61
+ //# sourceMappingURL=config-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/seo/config-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAEhB,mBAAmB,EACnB,aAAa,EACd,MAAM,oBAAoB,CAAA;AAE3B,eAAO,MAAM,qBAAqB,mBAAmB,CAAA;AAErD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAC7B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAC1D,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,4EAA4E;AAC5E,wBAAsB,eAAe,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAerF;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,CAAC,CA8B7B;AAwBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,aAAa,GAAG,SAAS,EAC/B,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,GACvC,aAAa,CA6Bf;AAED,qFAAqF;AACrF,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,mBAAmB,GAAG,SAAS,EACrC,IAAI,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,SAAS,GAC7C,mBAAmB,CAiBrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,EAC3C,SAAS,EAAE,kBAAkB,GAAG,IAAI,GACnC,gBAAgB,GAAG,IAAI,CAkBzB"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Editable SEO config — DB-backed overrides for the static `actuate.config.ts`
3
+ * `seo` block + per-collection `CollectionSEOConfig`.
4
+ *
5
+ * Static config in `actuate.config.ts` is the source of truth at code level,
6
+ * but admins need to be able to change site name, default OG image, robots
7
+ * policy, default Schema.org types per collection, etc. without redeploying.
8
+ *
9
+ * Storage: a single Document row with `collection = '__seo_config__'` and
10
+ * `data.{site, collections}`. The leading double underscore makes the slug
11
+ * un-spellable as a normal collection (slugs are lowercased + dashed in the
12
+ * config validator), so it can never collide with a user collection.
13
+ *
14
+ * Merge semantics: DB values take precedence over static config, field by
15
+ * field. Removing a value in the UI (setting it to undefined / empty string)
16
+ * falls back to the static default — so the admin panel is purely additive,
17
+ * never destructive of code-level config.
18
+ */
19
+ export const SEO_CONFIG_COLLECTION = '__seo_config__';
20
+ /** Read the SEO overrides document. Returns null when no row exists yet. */
21
+ export async function getSeoOverrides(db) {
22
+ const d = db;
23
+ if (!d?.document?.findFirst)
24
+ return null;
25
+ try {
26
+ const doc = await d.document.findFirst({
27
+ where: { collection: SEO_CONFIG_COLLECTION, deletedAt: null },
28
+ select: { data: true },
29
+ });
30
+ if (!doc)
31
+ return null;
32
+ const data = doc.data;
33
+ if (!data || typeof data !== 'object')
34
+ return null;
35
+ return data;
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Upsert the SEO overrides document. The caller is responsible for auth/role
43
+ * checks — this function only handles storage.
44
+ */
45
+ export async function putSeoOverrides(db, overrides, userId) {
46
+ const d = db;
47
+ const data = {
48
+ ...overrides,
49
+ updatedAt: new Date().toISOString(),
50
+ updatedBy: userId,
51
+ };
52
+ const existing = await d.document.findFirst({
53
+ where: { collection: SEO_CONFIG_COLLECTION, deletedAt: null },
54
+ select: { id: true },
55
+ });
56
+ if (existing) {
57
+ await d.document.update({
58
+ where: { id: existing.id },
59
+ data: { data, updatedById: userId },
60
+ });
61
+ }
62
+ else {
63
+ await d.document.create({
64
+ data: {
65
+ collection: SEO_CONFIG_COLLECTION,
66
+ data,
67
+ status: 'PUBLISHED',
68
+ title: 'SEO defaults',
69
+ slug: 'seo-config',
70
+ createdById: userId,
71
+ updatedById: userId,
72
+ },
73
+ });
74
+ }
75
+ return data;
76
+ }
77
+ /**
78
+ * Shallow-merge that drops undefined / empty-string values on the override
79
+ * side so the UI can "unset" a field by submitting an empty string.
80
+ */
81
+ function mergeFields(base, over) {
82
+ const out = { ...(base ?? {}) };
83
+ if (!over)
84
+ return out;
85
+ for (const [k, v] of Object.entries(over)) {
86
+ if (v === undefined)
87
+ continue;
88
+ if (typeof v === 'string' && v.trim() === '')
89
+ continue;
90
+ if (v === null) {
91
+ delete out[k];
92
+ continue;
93
+ }
94
+ out[k] = v;
95
+ }
96
+ return out;
97
+ }
98
+ /**
99
+ * Merge static site-wide SEO config with the DB overrides. Nested objects
100
+ * (`robots`, `sitemap`, `ogImage`, `organization`) merge field-by-field;
101
+ * primitive values use override-wins-if-set.
102
+ */
103
+ export function mergeSiteSeoConfig(base, over) {
104
+ if (!over)
105
+ return { ...(base ?? {}) };
106
+ // The SEO config interfaces are declared with explicit named fields and no
107
+ // index signature, so we cast through Record<string, unknown> when calling
108
+ // the generic merge helper. Behaviour is unchanged; this is purely a
109
+ // structural-typing escape hatch.
110
+ const merged = mergeFields(base, over);
111
+ return {
112
+ ...merged,
113
+ robots: mergeFields(base?.robots, over.robots),
114
+ sitemap: mergeFields(base?.sitemap, over.sitemap),
115
+ ogImage: mergeFields(base?.ogImage, over.ogImage),
116
+ organization: mergeFields(base?.organization, over.organization),
117
+ };
118
+ }
119
+ /** Same merge semantics as the site-wide version, applied to a single collection. */
120
+ export function mergeCollectionSeoConfig(base, over) {
121
+ if (!over)
122
+ return { ...(base ?? {}) };
123
+ const merged = mergeFields(base, over);
124
+ return {
125
+ ...merged,
126
+ defaultRobots: mergeFields(base?.defaultRobots, over.defaultRobots),
127
+ defaultOgImage: mergeFields(base?.defaultOgImage, over.defaultOgImage),
128
+ };
129
+ }
130
+ /**
131
+ * Return a new config object with DB-stored SEO overrides applied. The
132
+ * static config is never mutated — callers receive a shallow copy with
133
+ * `seo` and each collection's `seo` block replaced by the merged values.
134
+ *
135
+ * Routes that compose SEO output call this once per request, then thread
136
+ * the result through to `composePageMeta` / sitemap helpers exactly like
137
+ * the static config they replaced.
138
+ */
139
+ export function applySeoOverrides(config, overrides) {
140
+ if (!config)
141
+ return null;
142
+ if (!overrides)
143
+ return config;
144
+ const mergedSite = mergeSiteSeoConfig(config.seo, overrides.site);
145
+ const mergedCollections = {};
146
+ for (const [slug, col] of Object.entries(config.collections ?? {})) {
147
+ const colOver = overrides.collections?.[slug];
148
+ mergedCollections[slug] = colOver
149
+ ? { ...col, seo: mergeCollectionSeoConfig(col.seo, colOver) }
150
+ : col;
151
+ }
152
+ return {
153
+ ...config,
154
+ seo: mergedSite,
155
+ collections: mergedCollections,
156
+ };
157
+ }
158
+ //# sourceMappingURL=config-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store.js","sourceRoot":"","sources":["../../src/seo/config-store.ts"],"names":[],"mappings":"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"}
@@ -10,4 +10,6 @@ export { generateLlmsTxt } from './llms-txt.js';
10
10
  export type { LlmsTxtConfig, LlmsTxtPage } from './llms-txt.js';
11
11
  export { composePageMeta, detectSchemaType } from './page-meta.js';
12
12
  export type { ComposePageMetaInput, ComposedPageMeta, ComposeDocumentInput } from './page-meta.js';
13
+ export { SEO_CONFIG_COLLECTION, getSeoOverrides, putSeoOverrides, applySeoOverrides, mergeSiteSeoConfig, mergeCollectionSeoConfig, } from './config-store.js';
14
+ export type { SeoConfigOverrides } from './config-store.js';
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAEtB,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAElG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAE3F,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE1F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAErE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAE9E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAElE,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAEtB,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAElG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAE3F,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE1F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAErE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAE9E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/C,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAElE,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAElG,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAA;AAE1B,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
package/dist/seo/index.js CHANGED
@@ -4,4 +4,5 @@ export { resolveRobotsDirectives } from './robots.js';
4
4
  export { resolveTitle, getDocumentTitle } from './title-templates.js';
5
5
  export { generateLlmsTxt } from './llms-txt.js';
6
6
  export { composePageMeta, detectSchemaType } from './page-meta.js';
7
+ export { SEO_CONFIG_COLLECTION, getSeoOverrides, putSeoOverrides, applySeoOverrides, mergeSiteSeoConfig, mergeCollectionSeoConfig, } from './config-store.js';
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAItB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAI3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAIrD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAIrE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAI/C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAItB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAI3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAIrD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAIrE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAI/C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAIlE,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actuate-media/cms-core",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/actuate-media/actuatecms.git",