@actuate-media/cms-core 0.28.1 → 0.30.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 (141) hide show
  1. package/dist/__tests__/actions/seo-fields-update.test.d.ts +2 -0
  2. package/dist/__tests__/actions/seo-fields-update.test.d.ts.map +1 -0
  3. package/dist/__tests__/actions/seo-fields-update.test.js +93 -0
  4. package/dist/__tests__/actions/seo-fields-update.test.js.map +1 -0
  5. package/dist/__tests__/api/llms-txt.test.d.ts +2 -0
  6. package/dist/__tests__/api/llms-txt.test.d.ts.map +1 -0
  7. package/dist/__tests__/api/llms-txt.test.js +77 -0
  8. package/dist/__tests__/api/llms-txt.test.js.map +1 -0
  9. package/dist/__tests__/api/seo-read-access.test.d.ts +2 -0
  10. package/dist/__tests__/api/seo-read-access.test.d.ts.map +1 -0
  11. package/dist/__tests__/api/seo-read-access.test.js +101 -0
  12. package/dist/__tests__/api/seo-read-access.test.js.map +1 -0
  13. package/dist/__tests__/api/seo-summary-ssrf.test.d.ts +2 -0
  14. package/dist/__tests__/api/seo-summary-ssrf.test.d.ts.map +1 -0
  15. package/dist/__tests__/api/seo-summary-ssrf.test.js +80 -0
  16. package/dist/__tests__/api/seo-summary-ssrf.test.js.map +1 -0
  17. package/dist/__tests__/api/sitemap-pagination.test.d.ts +2 -0
  18. package/dist/__tests__/api/sitemap-pagination.test.d.ts.map +1 -0
  19. package/dist/__tests__/api/sitemap-pagination.test.js +100 -0
  20. package/dist/__tests__/api/sitemap-pagination.test.js.map +1 -0
  21. package/dist/__tests__/media/seo.test.d.ts +2 -0
  22. package/dist/__tests__/media/seo.test.d.ts.map +1 -0
  23. package/dist/__tests__/media/seo.test.js +186 -0
  24. package/dist/__tests__/media/seo.test.js.map +1 -0
  25. package/dist/__tests__/middleware.test.d.ts +2 -0
  26. package/dist/__tests__/middleware.test.d.ts.map +1 -0
  27. package/dist/__tests__/middleware.test.js +50 -0
  28. package/dist/__tests__/middleware.test.js.map +1 -0
  29. package/dist/__tests__/redirects/graph.test.d.ts +2 -0
  30. package/dist/__tests__/redirects/graph.test.d.ts.map +1 -0
  31. package/dist/__tests__/redirects/graph.test.js +104 -0
  32. package/dist/__tests__/redirects/graph.test.js.map +1 -0
  33. package/dist/__tests__/redirects/suggest.test.d.ts +2 -0
  34. package/dist/__tests__/redirects/suggest.test.d.ts.map +1 -0
  35. package/dist/__tests__/redirects/suggest.test.js +28 -0
  36. package/dist/__tests__/redirects/suggest.test.js.map +1 -0
  37. package/dist/__tests__/seo/analysis-markdown.test.d.ts +2 -0
  38. package/dist/__tests__/seo/analysis-markdown.test.d.ts.map +1 -0
  39. package/dist/__tests__/seo/analysis-markdown.test.js +57 -0
  40. package/dist/__tests__/seo/analysis-markdown.test.js.map +1 -0
  41. package/dist/__tests__/seo/audit-engine.test.d.ts +2 -0
  42. package/dist/__tests__/seo/audit-engine.test.d.ts.map +1 -0
  43. package/dist/__tests__/seo/audit-engine.test.js +152 -0
  44. package/dist/__tests__/seo/audit-engine.test.js.map +1 -0
  45. package/dist/__tests__/seo/audit-runner.test.d.ts +2 -0
  46. package/dist/__tests__/seo/audit-runner.test.d.ts.map +1 -0
  47. package/dist/__tests__/seo/audit-runner.test.js +82 -0
  48. package/dist/__tests__/seo/audit-runner.test.js.map +1 -0
  49. package/dist/__tests__/seo/config-store.test.js +24 -160
  50. package/dist/__tests__/seo/config-store.test.js.map +1 -1
  51. package/dist/__tests__/seo/internal-collections.test.d.ts +2 -0
  52. package/dist/__tests__/seo/internal-collections.test.d.ts.map +1 -0
  53. package/dist/__tests__/seo/internal-collections.test.js +27 -0
  54. package/dist/__tests__/seo/internal-collections.test.js.map +1 -0
  55. package/dist/__tests__/seo/page-meta.test.js +34 -2
  56. package/dist/__tests__/seo/page-meta.test.js.map +1 -1
  57. package/dist/__tests__/seo/robots.test.js +23 -2
  58. package/dist/__tests__/seo/robots.test.js.map +1 -1
  59. package/dist/__tests__/seo/score.test.d.ts +2 -0
  60. package/dist/__tests__/seo/score.test.d.ts.map +1 -0
  61. package/dist/__tests__/seo/score.test.js +152 -0
  62. package/dist/__tests__/seo/score.test.js.map +1 -0
  63. package/dist/__tests__/setup/index.test.d.ts +2 -0
  64. package/dist/__tests__/setup/index.test.d.ts.map +1 -0
  65. package/dist/__tests__/setup/index.test.js +82 -0
  66. package/dist/__tests__/setup/index.test.js.map +1 -0
  67. package/dist/actions.d.ts +24 -0
  68. package/dist/actions.d.ts.map +1 -1
  69. package/dist/actions.js +63 -0
  70. package/dist/actions.js.map +1 -1
  71. package/dist/api/handlers.d.ts.map +1 -1
  72. package/dist/api/handlers.js +2339 -274
  73. package/dist/api/handlers.js.map +1 -1
  74. package/dist/config/types.d.ts +7 -0
  75. package/dist/config/types.d.ts.map +1 -1
  76. package/dist/index.d.ts +4 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +4 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/media/index.d.ts +2 -0
  81. package/dist/media/index.d.ts.map +1 -1
  82. package/dist/media/index.js +1 -0
  83. package/dist/media/index.js.map +1 -1
  84. package/dist/media/seo.d.ts +88 -0
  85. package/dist/media/seo.d.ts.map +1 -0
  86. package/dist/media/seo.js +215 -0
  87. package/dist/media/seo.js.map +1 -0
  88. package/dist/middleware.js +12 -2
  89. package/dist/middleware.js.map +1 -1
  90. package/dist/redirects/graph.d.ts +68 -0
  91. package/dist/redirects/graph.d.ts.map +1 -0
  92. package/dist/redirects/graph.js +136 -0
  93. package/dist/redirects/graph.js.map +1 -0
  94. package/dist/redirects/index.d.ts +5 -0
  95. package/dist/redirects/index.d.ts.map +1 -0
  96. package/dist/redirects/index.js +3 -0
  97. package/dist/redirects/index.js.map +1 -0
  98. package/dist/redirects/suggest.d.ts +21 -0
  99. package/dist/redirects/suggest.d.ts.map +1 -0
  100. package/dist/redirects/suggest.js +55 -0
  101. package/dist/redirects/suggest.js.map +1 -0
  102. package/dist/seo/analysis.d.ts +9 -0
  103. package/dist/seo/analysis.d.ts.map +1 -1
  104. package/dist/seo/analysis.js +45 -6
  105. package/dist/seo/analysis.js.map +1 -1
  106. package/dist/seo/audit-engine.d.ts +119 -0
  107. package/dist/seo/audit-engine.d.ts.map +1 -0
  108. package/dist/seo/audit-engine.js +402 -0
  109. package/dist/seo/audit-engine.js.map +1 -0
  110. package/dist/seo/audit-runner.d.ts +47 -0
  111. package/dist/seo/audit-runner.d.ts.map +1 -0
  112. package/dist/seo/audit-runner.js +252 -0
  113. package/dist/seo/audit-runner.js.map +1 -0
  114. package/dist/seo/config-store.d.ts +28 -0
  115. package/dist/seo/config-store.d.ts.map +1 -1
  116. package/dist/seo/config-store.js +22 -0
  117. package/dist/seo/config-store.js.map +1 -1
  118. package/dist/seo/index.d.ts +8 -3
  119. package/dist/seo/index.d.ts.map +1 -1
  120. package/dist/seo/index.js +5 -2
  121. package/dist/seo/index.js.map +1 -1
  122. package/dist/seo/page-meta.d.ts +6 -0
  123. package/dist/seo/page-meta.d.ts.map +1 -1
  124. package/dist/seo/page-meta.js +22 -5
  125. package/dist/seo/page-meta.js.map +1 -1
  126. package/dist/seo/robots.d.ts +7 -0
  127. package/dist/seo/robots.d.ts.map +1 -1
  128. package/dist/seo/robots.js +10 -1
  129. package/dist/seo/robots.js.map +1 -1
  130. package/dist/seo/score.d.ts +132 -0
  131. package/dist/seo/score.d.ts.map +1 -0
  132. package/dist/seo/score.js +216 -0
  133. package/dist/seo/score.js.map +1 -0
  134. package/dist/setup/index.d.ts +16 -1
  135. package/dist/setup/index.d.ts.map +1 -1
  136. package/dist/setup/index.js +52 -2
  137. package/dist/setup/index.js.map +1 -1
  138. package/package.json +1 -1
  139. package/prisma/migrations/0008_media_center/migration.sql +47 -0
  140. package/prisma/migrations/0009_seo/migration.sql +143 -0
  141. package/prisma/schema.prisma +183 -8
@@ -0,0 +1,152 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { runSeoAuditAnalysis, buildQuickWins, issueKeyFor, } from '../../seo/audit-engine.js';
3
+ const goodPage = {
4
+ entityType: 'page',
5
+ entityId: 'p1',
6
+ title: 'Home',
7
+ url: '/',
8
+ content: '<h1>Home</h1>' + 'word '.repeat(400),
9
+ metaTitle: 'Home — Acme, the modern CMS for teams',
10
+ metaDescription: 'Acme is the modern content platform that helps marketing and engineering teams ship reliable, fast, search-optimised websites together without friction every week.',
11
+ focusKeyword: 'modern cms',
12
+ canonicalUrl: 'https://acme.com/',
13
+ ogTitle: 'Home',
14
+ ogDescription: 'Welcome',
15
+ ogImage: 'https://acme.com/og.png',
16
+ structuredDataType: 'WebPage',
17
+ noindex: false,
18
+ };
19
+ function findIssues(issues, type) {
20
+ return issues.filter((i) => i.type === type);
21
+ }
22
+ describe('runSeoAuditAnalysis', () => {
23
+ it('produces no content issues for a fully-optimised page', () => {
24
+ const result = runSeoAuditAnalysis([goodPage]);
25
+ expect(result.pages).toHaveLength(1);
26
+ expect(result.pages[0].score).toBeGreaterThanOrEqual(95);
27
+ expect(result.counts.total).toBe(0);
28
+ });
29
+ it('detects missing meta description', () => {
30
+ const result = runSeoAuditAnalysis([{ ...goodPage, metaDescription: '' }]);
31
+ const found = findIssues(result.issues, 'missing-meta-description');
32
+ expect(found).toHaveLength(1);
33
+ expect(found[0].severity).toBe('warning');
34
+ expect(found[0].fixActionType).toBe('edit-metadata');
35
+ });
36
+ it('detects duplicate meta titles across pages', () => {
37
+ const a = { ...goodPage, entityId: 'a', url: '/about', metaTitle: 'Same Title Here For Both' };
38
+ const b = {
39
+ ...goodPage,
40
+ entityId: 'b',
41
+ url: '/services',
42
+ metaTitle: 'Same Title Here For Both',
43
+ };
44
+ const result = runSeoAuditAnalysis([a, b]);
45
+ const dup = findIssues(result.issues, 'duplicate-meta-title');
46
+ expect(dup).toHaveLength(1);
47
+ expect(dup[0].severity).toBe('critical');
48
+ expect(dup[0].relatedEntityIds.sort()).toEqual(['a', 'b']);
49
+ });
50
+ it('does not flag duplicate when titles differ', () => {
51
+ const a = { ...goodPage, entityId: 'a', metaTitle: 'Title A unique enough here' };
52
+ const b = { ...goodPage, entityId: 'b', metaTitle: 'Title B unique enough here' };
53
+ const result = runSeoAuditAnalysis([a, b]);
54
+ expect(findIssues(result.issues, 'duplicate-meta-title')).toHaveLength(0);
55
+ });
56
+ it('detects broken internal links from signals', () => {
57
+ const result = runSeoAuditAnalysis([goodPage], {
58
+ brokenLinks: [
59
+ { url: '/services/enterprise', fromEntityId: 'p1', fromTitle: 'Home', fromUrl: '/' },
60
+ ],
61
+ });
62
+ const broken = findIssues(result.issues, 'broken-internal-link');
63
+ expect(broken).toHaveLength(1);
64
+ expect(broken[0].severity).toBe('critical');
65
+ expect(broken[0].category).toBe('technical');
66
+ });
67
+ it('detects missing H1 only in non-empty content', () => {
68
+ const noH1 = { ...goodPage, content: '<p>no heading here</p>' };
69
+ const result = runSeoAuditAnalysis([noH1]);
70
+ expect(findIssues(result.issues, 'missing-h1')).toHaveLength(1);
71
+ });
72
+ it('detects thin content', () => {
73
+ const thin = { ...goodPage, content: '<h1>x</h1> short body', wordCount: 20 };
74
+ const result = runSeoAuditAnalysis([thin]);
75
+ expect(findIssues(result.issues, 'thin-content')).toHaveLength(1);
76
+ });
77
+ it('detects missing alt text on images', () => {
78
+ const withImg = { ...goodPage, content: '<h1>x</h1>' + 'w '.repeat(400) + '<img src="a.png">' };
79
+ const result = runSeoAuditAnalysis([withImg]);
80
+ expect(findIssues(result.issues, 'missing-alt-text')).toHaveLength(1);
81
+ });
82
+ it('counts issues by severity', () => {
83
+ const bad = {
84
+ entityType: 'page',
85
+ entityId: 'bad',
86
+ title: 'Bad',
87
+ url: '/bad',
88
+ content: '<p>thin</p>',
89
+ metaTitle: '',
90
+ metaDescription: '',
91
+ };
92
+ const result = runSeoAuditAnalysis([bad]);
93
+ expect(result.counts.total).toBeGreaterThan(0);
94
+ expect(result.counts.warning).toBeGreaterThanOrEqual(2); // missing title + desc
95
+ });
96
+ it('computes a site score that drops with missing metadata', () => {
97
+ const great = runSeoAuditAnalysis([goodPage]).siteScore.score;
98
+ const poor = runSeoAuditAnalysis([
99
+ {
100
+ ...goodPage,
101
+ metaTitle: '',
102
+ metaDescription: '',
103
+ structuredDataType: '',
104
+ ogImage: '',
105
+ canonicalUrl: '',
106
+ },
107
+ ]).siteScore.score;
108
+ expect(great).toBeGreaterThan(poor);
109
+ });
110
+ });
111
+ describe('issueKeyFor', () => {
112
+ it('builds a stable key', () => {
113
+ expect(issueKeyFor('missing-meta-title', 'p1')).toBe('missing-meta-title:p1');
114
+ });
115
+ });
116
+ describe('buildQuickWins', () => {
117
+ const mk = (type, impact, id) => ({
118
+ issueKey: `${type}:${id}`,
119
+ entityType: 'page',
120
+ entityId: id,
121
+ entityTitle: id,
122
+ url: `/${id}`,
123
+ severity: 'warning',
124
+ category: 'content',
125
+ type,
126
+ title: type,
127
+ description: '',
128
+ impact,
129
+ recommendation: '',
130
+ fixable: true,
131
+ fixActionType: 'edit-metadata',
132
+ relatedEntityIds: [],
133
+ });
134
+ it('ranks higher-impact wins first', () => {
135
+ const wins = buildQuickWins([
136
+ mk('missing-canonical', 'Low', '1'),
137
+ mk('missing-meta-description', 'High', '2'),
138
+ mk('missing-meta-description', 'High', '3'),
139
+ ]);
140
+ expect(wins[0].issueType).toBe('missing-meta-description');
141
+ expect(wins[0].count).toBe(2);
142
+ });
143
+ it('excludes non-fixable issues', () => {
144
+ const issue = { ...mk('thin-content', 'Low', '1'), fixable: false };
145
+ expect(buildQuickWins([issue])).toHaveLength(0);
146
+ });
147
+ it('caps at 5 wins', () => {
148
+ const issues = Array.from({ length: 10 }, (_, i) => mk(`type-${i}`, 'Medium', String(i)));
149
+ expect(buildQuickWins(issues).length).toBeLessThanOrEqual(5);
150
+ });
151
+ });
152
+ //# sourceMappingURL=audit-engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-engine.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/audit-engine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=audit-runner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-runner.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/seo/audit-runner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,82 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { gatherAuditEntities, runAndPersistAudit } from '../../seo/audit-runner.js';
3
+ /**
4
+ * Regression coverage for the SEO audit reliability fixes:
5
+ * - a new audit refuses to start while another is RUNNING (parallel runs can
6
+ * otherwise duplicate SeoIssue rows for the same issueKey), and
7
+ * - `gatherAuditEntities` bounds its document query so a large instance can't
8
+ * OOM the audit pass.
9
+ */
10
+ function baseDb(overrides = {}) {
11
+ return {
12
+ document: {
13
+ findMany: vi.fn(async () => []),
14
+ },
15
+ seoAuditRun: {
16
+ create: vi.fn(async () => ({ id: 'run-1' })),
17
+ update: vi.fn(async () => ({})),
18
+ findFirst: vi.fn(async () => null),
19
+ },
20
+ seoIssue: {
21
+ findMany: vi.fn(async () => []),
22
+ create: vi.fn(async () => ({})),
23
+ update: vi.fn(async () => ({})),
24
+ },
25
+ ...overrides,
26
+ };
27
+ }
28
+ describe('runAndPersistAudit concurrency guard', () => {
29
+ it('throws when another audit started within the stale window', async () => {
30
+ const db = baseDb();
31
+ // First findFirst call is the RUNNING check; return a fresh running run.
32
+ db.seoAuditRun.findFirst = vi.fn(async ({ where }) => {
33
+ if (where?.status === 'RUNNING')
34
+ return { startedAt: new Date() };
35
+ return null;
36
+ });
37
+ await expect(runAndPersistAudit(db)).rejects.toThrow(/already running/i);
38
+ expect(db.seoAuditRun.create).not.toHaveBeenCalled();
39
+ });
40
+ it('proceeds when the only RUNNING run is stale (crashed)', async () => {
41
+ const db = baseDb();
42
+ const stale = new Date(Date.now() - 60 * 60 * 1000); // 1h ago
43
+ db.seoAuditRun.findFirst = vi.fn(async ({ where }) => {
44
+ if (where?.status === 'RUNNING')
45
+ return { startedAt: stale };
46
+ if (where?.status === 'COMPLETED')
47
+ return { siteScoreAfter: 80 };
48
+ return null;
49
+ });
50
+ const result = await runAndPersistAudit(db);
51
+ expect(db.seoAuditRun.create).toHaveBeenCalledTimes(1);
52
+ expect(result.status).toBe('COMPLETED');
53
+ });
54
+ it('proceeds when no audit is running', async () => {
55
+ const db = baseDb();
56
+ const result = await runAndPersistAudit(db);
57
+ expect(db.seoAuditRun.create).toHaveBeenCalledTimes(1);
58
+ expect(result.status).toBe('COMPLETED');
59
+ });
60
+ });
61
+ describe('gatherAuditEntities query bounds', () => {
62
+ it('caps the document query with a take limit', async () => {
63
+ const findMany = vi.fn(async (_args) => []);
64
+ const db = { document: { findMany } };
65
+ await gatherAuditEntities(db);
66
+ expect(findMany).toHaveBeenCalledTimes(1);
67
+ const arg = (findMany.mock.calls[0]?.[0] ?? {});
68
+ expect(typeof arg.take).toBe('number');
69
+ expect(arg.take).toBeGreaterThan(0);
70
+ });
71
+ it('excludes internal/system collections from the audit set', async () => {
72
+ const findMany = vi.fn(async () => [
73
+ { id: 'a', collection: 'pages', data: { title: 'A', slug: 'a' } },
74
+ { id: 'b', collection: '__seo_config__', data: { title: 'B', slug: 'b' } },
75
+ ]);
76
+ const db = { document: { findMany } };
77
+ const entities = await gatherAuditEntities(db);
78
+ expect(entities).toHaveLength(1);
79
+ expect(entities[0].entityId).toBe('a');
80
+ });
81
+ });
82
+ //# sourceMappingURL=audit-runner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-runner.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/audit-runner.test.ts"],"names":[],"mappings":"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"}
@@ -1,167 +1,31 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { SEO_CONFIG_COLLECTION, applySeoOverrides, getSeoOverrides, mergeCollectionSeoConfig, mergeSiteSeoConfig, putSeoOverrides, } from '../../seo/config-store.js';
3
- // In-memory mock that mirrors the parts of the Prisma `document` model the
4
- // config-store touches. Using a single-row store keeps the slug-uniqueness
5
- // contract honest — putSeoOverrides should upsert, not duplicate.
6
- function makeDb() {
7
- let row = null;
8
- return {
9
- document: {
10
- findFirst: async ({ where, select: _select, }) => {
11
- if (!row)
12
- return null;
13
- if (row.collection !== where.collection)
14
- return null;
15
- if (row.deletedAt !== null)
16
- return null;
17
- return row;
18
- },
19
- create: async ({ data }) => {
20
- row = {
21
- id: 'row-1',
22
- collection: data.collection,
23
- data: data.data,
24
- deletedAt: null,
25
- };
26
- return row;
27
- },
28
- update: async ({ where, data }) => {
29
- if (!row || row.id !== where.id)
30
- throw new Error('Row not found');
31
- row = { ...row, data: data.data ?? row.data };
32
- return row;
33
- },
34
- },
35
- };
36
- }
37
- describe('config-store: mergeSiteSeoConfig', () => {
38
- it('returns base verbatim when no override is supplied', () => {
39
- const result = mergeSiteSeoConfig({ siteUrl: 'https://a.com', siteName: 'A' }, undefined);
40
- expect(result).toEqual({ siteUrl: 'https://a.com', siteName: 'A' });
41
- });
42
- it('lets override fields win and ignores empty strings', () => {
43
- const result = mergeSiteSeoConfig({ siteUrl: 'https://a.com', siteName: 'A', twitterHandle: '@a' }, { siteUrl: 'https://b.com', siteName: '', twitterHandle: undefined });
44
- // siteUrl flips; empty-string siteName is treated as "unset" (keeps base);
45
- // undefined twitterHandle keeps base too.
46
- expect(result.siteUrl).toBe('https://b.com');
47
- expect(result.siteName).toBe('A');
48
- expect(result.twitterHandle).toBe('@a');
49
- });
50
- it('deep-merges nested robots/sitemap/ogImage blocks', () => {
51
- const result = mergeSiteSeoConfig({
52
- siteUrl: 'https://a.com',
53
- robots: { blockAIBots: false, disabled: false },
54
- sitemap: { defaultChangeFreq: 'weekly', defaultPriority: 0.6 },
55
- ogImage: { theme: 'light' },
56
- }, {
57
- robots: { blockAIBots: true }, // disabled untouched
58
- sitemap: { defaultPriority: 0.9 }, // defaultChangeFreq untouched
59
- ogImage: { theme: 'dark' },
1
+ import { describe, it, expect } from 'vitest';
2
+ import { DEFAULT_SEO_MODULE_SETTINGS, resolveSeoModuleSettings } from '../../seo/config-store.js';
3
+ describe('resolveSeoModuleSettings', () => {
4
+ it('returns defaults when no overrides exist', () => {
5
+ expect(resolveSeoModuleSettings(null)).toEqual(DEFAULT_SEO_MODULE_SETTINGS);
6
+ expect(resolveSeoModuleSettings({})).toEqual(DEFAULT_SEO_MODULE_SETTINGS);
7
+ });
8
+ it('merges stored module settings over defaults', () => {
9
+ const result = resolveSeoModuleSettings({
10
+ module: { indexEntireSite: false, noindexTagPages: true },
60
11
  });
61
- expect(result.robots).toEqual({ blockAIBots: true, disabled: false });
62
- expect(result.sitemap).toEqual({ defaultChangeFreq: 'weekly', defaultPriority: 0.9 });
63
- expect(result.ogImage).toEqual({ theme: 'dark' });
64
- });
65
- });
66
- describe('config-store: mergeCollectionSeoConfig', () => {
67
- it('overrides scalar fields and merges defaultRobots field-by-field', () => {
68
- const result = mergeCollectionSeoConfig({
69
- defaultSchemaType: 'WebPage',
70
- archivePath: '/blog',
71
- defaultRobots: { noIndex: false, noFollow: false },
72
- }, { defaultSchemaType: 'BlogPosting', defaultRobots: { noIndex: true } });
73
- expect(result.defaultSchemaType).toBe('BlogPosting');
74
- expect(result.archivePath).toBe('/blog');
75
- expect(result.defaultRobots).toEqual({ noIndex: true, noFollow: false });
76
- });
77
- });
78
- describe('config-store: applySeoOverrides', () => {
79
- const baseConfig = {
80
- collections: {
81
- posts: {
82
- slug: 'posts',
83
- labels: { singular: 'Post', plural: 'Posts' },
84
- fields: {},
85
- type: 'post',
86
- seo: { defaultSchemaType: 'BlogPosting', sitemapPriority: 0.6 },
87
- },
88
- pages: {
89
- slug: 'pages',
90
- labels: { singular: 'Page', plural: 'Pages' },
91
- fields: {},
92
- type: 'page',
93
- },
94
- },
95
- seo: { siteUrl: 'https://example.com', siteName: 'Example' },
96
- };
97
- it('returns base when overrides are null', () => {
98
- const merged = applySeoOverrides(baseConfig, null);
99
- expect(merged).toBe(baseConfig);
100
- });
101
- it('applies site-wide and per-collection overrides without mutating the base', () => {
102
- const merged = applySeoOverrides(baseConfig, {
103
- site: { siteName: 'New Brand', twitterHandle: '@new' },
104
- collections: {
105
- posts: { defaultSchemaType: 'NewsArticle', defaultRobots: { noIndex: true } },
106
- pages: { archivePath: '/archive' },
107
- },
12
+ expect(result.indexEntireSite).toBe(false);
13
+ expect(result.noindexTagPages).toBe(true);
14
+ // untouched fields keep defaults
15
+ expect(result.sitemapEnabled).toBe(true);
16
+ expect(result.searchConsoleConnected).toBe(false);
17
+ });
18
+ it('ignores undefined/null stored values', () => {
19
+ const result = resolveSeoModuleSettings({
20
+ module: { robotsTxt: undefined },
108
21
  });
109
- expect(merged?.seo?.siteName).toBe('New Brand');
110
- expect(merged?.seo?.siteUrl).toBe('https://example.com'); // untouched
111
- expect(merged?.seo?.twitterHandle).toBe('@new');
112
- expect(merged?.collections?.posts?.seo?.defaultSchemaType).toBe('NewsArticle');
113
- expect(merged?.collections?.posts?.seo?.sitemapPriority).toBe(0.6); // untouched
114
- expect(merged?.collections?.posts?.seo?.defaultRobots).toEqual({ noIndex: true });
115
- expect(merged?.collections?.pages?.seo?.archivePath).toBe('/archive');
116
- // Base config is untouched.
117
- expect(baseConfig.seo?.siteName).toBe('Example');
118
- expect(baseConfig.collections.posts?.seo?.defaultSchemaType).toBe('BlogPosting');
22
+ expect(result.robotsTxt).toBe('');
119
23
  });
120
- it('passes through unknown collection slugs in overrides without crashing', () => {
121
- const merged = applySeoOverrides(baseConfig, {
122
- collections: { 'not-a-real-collection': { defaultSchemaType: 'Service' } },
24
+ it('preserves an explicit custom robots body', () => {
25
+ const result = resolveSeoModuleSettings({
26
+ module: { robotsTxt: 'User-agent: *\nDisallow: /private/' },
123
27
  });
124
- // The unknown slug is silently ignored because we iterate over base.collections.
125
- expect(Object.keys(merged?.collections ?? {})).toEqual(['posts', 'pages']);
126
- });
127
- });
128
- describe('config-store: getSeoOverrides / putSeoOverrides', () => {
129
- let db;
130
- beforeEach(() => {
131
- db = makeDb();
132
- });
133
- it('returns null when no row exists yet', async () => {
134
- const result = await getSeoOverrides(db);
135
- expect(result).toBeNull();
136
- });
137
- it('persists overrides and roundtrips through getSeoOverrides', async () => {
138
- await putSeoOverrides(db, { site: { siteName: 'X' }, collections: { posts: { defaultSchemaType: 'BlogPosting' } } }, 'user-1');
139
- const result = await getSeoOverrides(db);
140
- expect(result?.site?.siteName).toBe('X');
141
- expect(result?.collections?.posts?.defaultSchemaType).toBe('BlogPosting');
142
- expect(result?.updatedBy).toBe('user-1');
143
- expect(typeof result?.updatedAt).toBe('string');
144
- });
145
- it('upserts (does not duplicate) on a second write', async () => {
146
- await putSeoOverrides(db, { site: { siteName: 'X' } }, 'user-1');
147
- await putSeoOverrides(db, { site: { siteName: 'Y' } }, 'user-2');
148
- const result = await getSeoOverrides(db);
149
- expect(result?.site?.siteName).toBe('Y');
150
- expect(result?.updatedBy).toBe('user-2');
151
- });
152
- it('exports the reserved collection slug so it can never collide with a user collection', () => {
153
- expect(SEO_CONFIG_COLLECTION).toMatch(/^__/);
154
- });
155
- it('returns null instead of throwing when db is unusable', async () => {
156
- const broken = {
157
- document: {
158
- findFirst: async () => {
159
- throw new Error('boom');
160
- },
161
- },
162
- };
163
- const result = await getSeoOverrides(broken);
164
- expect(result).toBeNull();
28
+ expect(result.robotsTxt).toContain('Disallow: /private/');
165
29
  });
166
30
  });
167
31
  //# sourceMappingURL=config-store.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-store.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/config-store.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config-store.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/config-store.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAEjG,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;QAC3E,MAAM,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAG,wBAAwB,CAAC;YACtC,MAAM,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE;SAC1D,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC1C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzC,iCAAiC;QACjC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAG,wBAAwB,CAAC;YACtC,MAAM,EAAE,EAAE,SAAS,EAAE,SAA8B,EAAE;SACtD,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,wBAAwB,CAAC;YACtC,MAAM,EAAE,EAAE,SAAS,EAAE,oCAAoC,EAAE;SAC5D,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=internal-collections.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-collections.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/seo/internal-collections.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { isInternalCollection } from '../../seo/audit-runner.js';
3
+ import { SEO_CONFIG_COLLECTION } from '../../seo/config-store.js';
4
+ /**
5
+ * Regression guard for the `/llms.txt` leak (production review blocker): the
6
+ * public surface must never list internal/system collections. `isInternalCollection`
7
+ * is the single source of truth shared by the audit runner and `/llms.txt`.
8
+ */
9
+ describe('isInternalCollection', () => {
10
+ it('flags the explicit internal/system collections', () => {
11
+ expect(isInternalCollection(SEO_CONFIG_COLLECTION)).toBe(true);
12
+ expect(isInternalCollection('__seo_config__')).toBe(true);
13
+ expect(isInternalCollection('page-tags')).toBe(true);
14
+ expect(isInternalCollection('redirects')).toBe(true);
15
+ });
16
+ it('flags any `__`-prefixed convention collection (e.g. demo perf rows)', () => {
17
+ expect(isInternalCollection('__seo_perf__')).toBe(true);
18
+ expect(isInternalCollection('__anything__')).toBe(true);
19
+ });
20
+ it('allows real, public content collections', () => {
21
+ expect(isInternalCollection('pages')).toBe(false);
22
+ expect(isInternalCollection('posts')).toBe(false);
23
+ expect(isInternalCollection('blog')).toBe(false);
24
+ expect(isInternalCollection('case-studies')).toBe(false);
25
+ });
26
+ });
27
+ //# sourceMappingURL=internal-collections.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-collections.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/internal-collections.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAEjE;;;;GAIG;AACH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,oBAAoB,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9D,MAAM,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzD,MAAM,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpD,MAAM,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACvD,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjD,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjD,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChD,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -140,6 +140,38 @@ describe('composePageMeta', () => {
140
140
  });
141
141
  expect(result.meta['robots']).toContain('noindex');
142
142
  });
143
+ it('honors the robotsPolicy select field (regression: was ignored)', () => {
144
+ const result = composePageMeta({
145
+ doc: {
146
+ id: '1',
147
+ collection: 'pages',
148
+ slug: 'secret',
149
+ data: { title: 'Secret', robotsPolicy: 'noindex-nofollow' },
150
+ },
151
+ collection: makeCollection(),
152
+ config: makeConfig(),
153
+ });
154
+ expect(result.meta['robots']).toContain('noindex');
155
+ expect(result.meta['robots']).toContain('nofollow');
156
+ });
157
+ it('forces noindex outside production when seo.robots.noIndexNonProduction is set', () => {
158
+ const result = composePageMeta({
159
+ doc: { id: '1', collection: 'pages', slug: 'home', data: { title: 'Home' } },
160
+ collection: makeCollection(),
161
+ config: makeConfig({ robots: { noIndexNonProduction: true } }),
162
+ environment: 'preview',
163
+ });
164
+ expect(result.meta['robots']).toContain('noindex');
165
+ });
166
+ it('does NOT force noindex in production even with noIndexNonProduction set', () => {
167
+ const result = composePageMeta({
168
+ doc: { id: '1', collection: 'pages', slug: 'home', data: { title: 'Home' } },
169
+ collection: makeCollection(),
170
+ config: makeConfig({ robots: { noIndexNonProduction: true } }),
171
+ environment: 'production',
172
+ });
173
+ expect(result.meta['robots'] ?? '').not.toContain('noindex');
174
+ });
143
175
  it('emits og:image, og:url, og:title, twitter:card', () => {
144
176
  const result = composePageMeta({
145
177
  doc: {
@@ -157,13 +189,13 @@ describe('composePageMeta', () => {
157
189
  expect(result.meta['twitter:card']).toBe('summary_large_image');
158
190
  expect(result.meta['twitter:site']).toBe('@example');
159
191
  });
160
- it('auto-builds og:image URL pointing at /og.png when none configured', () => {
192
+ it('auto-builds og:image URL pointing at the CMS /api/cms/og.png endpoint when none configured', () => {
161
193
  const result = composePageMeta({
162
194
  doc: { id: '1', collection: 'pages', slug: 'about', data: { title: 'About Us' } },
163
195
  collection: makeCollection(),
164
196
  config: makeConfig(),
165
197
  });
166
- expect(result.meta['og:image']).toBe('https://example.com/og.png?title=' + encodeURIComponent('About Us'));
198
+ expect(result.meta['og:image']).toBe('https://example.com/api/cms/og.png?title=' + encodeURIComponent('About Us'));
167
199
  });
168
200
  it('escapes < in JSON-LD HTML so it cannot break out of <script>', () => {
169
201
  const result = composePageMeta({
@@ -1 +1 @@
1
- {"version":3,"file":"page-meta.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/page-meta.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"page-meta.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/page-meta.test.ts"],"names":[],"mappings":"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"}