@paroicms/site-generator-plugin 0.1.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 (59) hide show
  1. package/README.md +9 -0
  2. package/gen-backend/dist/context.js +2 -0
  3. package/gen-backend/dist/data-format.js +37 -0
  4. package/gen-backend/dist/generator/actions.js +35 -0
  5. package/gen-backend/dist/generator/fake-content-generator.ts/create-database-with-fake-content.js +227 -0
  6. package/gen-backend/dist/generator/fake-content-generator.ts/create-node-contents.js +156 -0
  7. package/gen-backend/dist/generator/fake-content-generator.ts/fake-content-types.js +1 -0
  8. package/gen-backend/dist/generator/fake-content-generator.ts/generate-fake-content.js +127 -0
  9. package/gen-backend/dist/generator/fake-content-generator.ts/invoke-generate-fake-content.js +49 -0
  10. package/gen-backend/dist/generator/generator-types.js +1 -0
  11. package/gen-backend/dist/generator/helpers/esm-module.helper.js +6 -0
  12. package/gen-backend/dist/generator/helpers/js-utils.js +14 -0
  13. package/gen-backend/dist/generator/lib/common-types.js +1 -0
  14. package/gen-backend/dist/generator/lib/create-prompt.js +44 -0
  15. package/gen-backend/dist/generator/lib/debug-utils.js +118 -0
  16. package/gen-backend/dist/generator/lib/images-lib.js +16 -0
  17. package/gen-backend/dist/generator/lib/llm-invoke-types.js +1 -0
  18. package/gen-backend/dist/generator/lib/llm-tokens.js +10 -0
  19. package/gen-backend/dist/generator/lib/markdown-bulleted-list-parser.js +147 -0
  20. package/gen-backend/dist/generator/lib/parse-llm-response.js +160 -0
  21. package/gen-backend/dist/generator/lib/tasks.js +112 -0
  22. package/gen-backend/dist/generator/lib/utils.js +13 -0
  23. package/gen-backend/dist/generator/llm-queries/invoke-message-guard.js +86 -0
  24. package/gen-backend/dist/generator/llm-queries/invoke-new-site-analysis.js +169 -0
  25. package/gen-backend/dist/generator/llm-queries/invoke-update-site-schema.js +94 -0
  26. package/gen-backend/dist/generator/site-generator/common-template-creator.js +108 -0
  27. package/gen-backend/dist/generator/site-generator/document-template-creator.js +329 -0
  28. package/gen-backend/dist/generator/site-generator/id-key-provider.js +14 -0
  29. package/gen-backend/dist/generator/site-generator/jt-site-schema-helpers.js +55 -0
  30. package/gen-backend/dist/generator/site-generator/site-generator.js +75 -0
  31. package/gen-backend/dist/generator/site-generator/template-creator-types.js +1 -0
  32. package/gen-backend/dist/generator/site-generator/template-helpers.js +26 -0
  33. package/gen-backend/dist/generator/site-generator/theme-creator.js +180 -0
  34. package/gen-backend/dist/generator/site-generator/theme-css.js +323 -0
  35. package/gen-backend/dist/generator/site-schema-generator/analysis-types.js +1 -0
  36. package/gen-backend/dist/generator/site-schema-generator/create-l10n.js +42 -0
  37. package/gen-backend/dist/generator/site-schema-generator/create-site-schema.js +240 -0
  38. package/gen-backend/dist/generator/site-schema-generator/default-pages.js +38 -0
  39. package/gen-backend/dist/plugin.js +86 -0
  40. package/gen-backend/prompts/0-context.md +9 -0
  41. package/gen-backend/prompts/generate-fake-content-multiple.md +22 -0
  42. package/gen-backend/prompts/generate-fake-content-single.md +16 -0
  43. package/gen-backend/prompts/message-guard.md +89 -0
  44. package/gen-backend/prompts/new-site-1-analysis.md +214 -0
  45. package/gen-backend/prompts/new-site-2-fields.md +50 -0
  46. package/gen-backend/prompts/predefined-fields.json +110 -0
  47. package/gen-backend/prompts/test-message1.txt +1 -0
  48. package/gen-backend/prompts/update-site-schema-1-write-details.md +57 -0
  49. package/gen-backend/prompts/update-site-schema-2-execute.md +77 -0
  50. package/gen-front/dist/gen-front.css +1 -0
  51. package/gen-front/dist/gen-front.eot +0 -0
  52. package/gen-front/dist/gen-front.mjs +998 -0
  53. package/gen-front/dist/gen-front.svg +345 -0
  54. package/gen-front/dist/gen-front.ttf +0 -0
  55. package/gen-front/dist/gen-front.woff +0 -0
  56. package/gen-front/dist/gen-front.woff2 +0 -0
  57. package/gen-front/dist/gen-front2.woff2 +0 -0
  58. package/gen-front/dist/gen-front3.woff2 +0 -0
  59. package/package.json +79 -0
@@ -0,0 +1,323 @@
1
+ export function getThemeCssContent() {
2
+ return `/* Reset */
3
+ * {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ a,
8
+ a:visited {
9
+ color: inherit;
10
+ text-decoration: none;
11
+ }
12
+
13
+ /* Elements */
14
+
15
+ body {
16
+ background-color: #aaa;
17
+ margin: 0;
18
+ padding: 0;
19
+ }
20
+
21
+ img {
22
+ display: block;
23
+ max-width: 100%;
24
+ }
25
+
26
+ picture {
27
+ display: block;
28
+ }
29
+
30
+ header {
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: space-between;
34
+ padding-bottom: 15px;
35
+ padding-top: 15px;
36
+ color: #fff;
37
+ }
38
+
39
+ @media (max-width: 768px) {
40
+ header {
41
+ flex-wrap: wrap;
42
+ padding: 15px 0 5px;
43
+ }
44
+ }
45
+
46
+ footer {
47
+ margin-top: 30px;
48
+ padding: 20px;
49
+ text-align: center;
50
+ }
51
+
52
+ /* Tile */
53
+
54
+ a > article {
55
+ background-color: #fff;
56
+ border-radius: 6px;
57
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
58
+ display: flex;
59
+ max-width: 340px;
60
+ overflow: hidden;
61
+ }
62
+ a > article div:first-child {
63
+ flex: 0 0 120px;
64
+ max-width: 120px;
65
+ }
66
+ a > article img {
67
+ height: 100%;
68
+ object-fit: cover;
69
+ width: 100%;
70
+ }
71
+ a > article div:last-child {
72
+ display: flex;
73
+ flex: 1;
74
+ flex-direction: column;
75
+ padding: 15px;
76
+ }
77
+ a > article h3 {
78
+ margin: 0 0 8px;
79
+ font-size: 16px;
80
+ font-weight: bold;
81
+ color: #333;
82
+ }
83
+ a > article p {
84
+ color: #666;
85
+ font-size: 14px;
86
+ line-height: 1.4;
87
+ margin: 0;
88
+ }
89
+ a:hover > article {
90
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.4);
91
+ }
92
+
93
+ /* Navbar */
94
+
95
+ nav {
96
+ align-items: center;
97
+ display: flex;
98
+ flex-grow: 1;
99
+ justify-content: center;
100
+ margin: 0 15px;
101
+ }
102
+
103
+ @media (max-width: 768px) {
104
+ nav {
105
+ flex-basis: 100%;
106
+ order: 3;
107
+ margin: 10px 0 5px;
108
+ justify-content: flex-start;
109
+ overflow-x: auto;
110
+ padding-bottom: 5px;
111
+ }
112
+ }
113
+
114
+ nav a {
115
+ color: rgba(255, 255, 255, 0.85);
116
+ padding: 8px;
117
+ margin: 0 4px;
118
+ border-radius: 4px;
119
+ font-size: 17px;
120
+ font-weight: bold;
121
+ position: relative;
122
+ transition: all 0.2s ease;
123
+ }
124
+
125
+ nav a:hover {
126
+ color: #fff;
127
+ background-color: rgba(255, 255, 255, 0.1);
128
+ }
129
+
130
+ nav a.active {
131
+ color: #fff;
132
+ }
133
+
134
+ nav a.active::after {
135
+ content: "";
136
+ position: absolute;
137
+ bottom: 0;
138
+ left: 16px;
139
+ right: 16px;
140
+ height: 3px;
141
+ background-color: #3498db;
142
+ border-radius: 1.5px;
143
+ }
144
+
145
+ /* Classes */
146
+
147
+ ._bg2 {
148
+ background-color: #444;
149
+ color: #eee;
150
+ }
151
+
152
+ .Container {
153
+ max-width: 1200px;
154
+ margin-left: auto;
155
+ margin-right: auto;
156
+ padding-left: 20px;
157
+ padding-right: 20px;
158
+ }
159
+
160
+ .Page {
161
+ background-color: #fff;
162
+ color: #333;
163
+ padding: 5px 40px;
164
+ }
165
+
166
+ .TextWidth {
167
+ max-width: 600px;
168
+ margin: 0 auto;
169
+ }
170
+
171
+ .List {
172
+ display: flex;
173
+ gap: 20px;
174
+ flex-wrap: wrap;
175
+ }
176
+
177
+ .Pt {
178
+ padding-top: 50px;
179
+ }
180
+
181
+ .Pb {
182
+ padding-bottom: 50px;
183
+ }
184
+
185
+ .HeaderLogo {
186
+ display: flex;
187
+ align-items: center;
188
+ }
189
+
190
+ .HeaderLogo img {
191
+ margin-right: 10px;
192
+ border-radius: 50%;
193
+ }
194
+
195
+ .HeaderTitle {
196
+ font-size: 20px;
197
+ font-weight: bold;
198
+ }
199
+
200
+ .Text::after {
201
+ clear: both;
202
+ content: "";
203
+ display: block;
204
+ }
205
+
206
+ .Text .Img {
207
+ height: auto;
208
+ }
209
+
210
+ .Text .Img.left {
211
+ float: left;
212
+ margin: 5px 20px 10px 0;
213
+ }
214
+
215
+ .Text .Img.right {
216
+ float: right;
217
+ margin: 5px 0 10px 20px;
218
+ }
219
+
220
+ .Text .Img.left, .Text .Img.right {
221
+ max-width: 50%;
222
+ }
223
+
224
+ .Text .Img.center {
225
+ display: block;
226
+ margin: 20px auto;
227
+ }
228
+
229
+ .Text a,
230
+ .Text a:visited,
231
+ .TextLink,
232
+ .TextLink:visited {
233
+ color: #007bff;
234
+ cursor: pointer;
235
+ text-decoration: underline;
236
+ }
237
+
238
+ .Hero img {
239
+ height: auto;
240
+ width: 100%;
241
+ }
242
+
243
+ .InfiniteLoading-actionArea {
244
+ align-items: center;
245
+ display: flex;
246
+ justify-content: center;
247
+ }
248
+
249
+ button,
250
+ .Button,
251
+ .SearchOpenerBtn,
252
+ .InfiniteLoading-btn,
253
+ .ContactForm-btn {
254
+ background-color: #3498db;
255
+ border: 1px solid #3498db;
256
+ border-radius: 5px;
257
+ color: #fff;
258
+ cursor: pointer;
259
+ display: inline-block;
260
+ font-size: 16px;
261
+ margin: 10px 0;
262
+ padding: 10px 20px;
263
+ text-align: center;
264
+ text-decoration: none;
265
+ }
266
+ button:hover,
267
+ .Button:hover,
268
+ .SearchOpenerBtn:hover,
269
+ .InfiniteLoading-btn:hover,
270
+ .ContactForm-btn:hover {
271
+ background-color: #2980b9;
272
+ border-color: #2980b9;
273
+ }
274
+ button:disabled,
275
+ .Button:disabled,
276
+ .SearchOpenerBtn:disabled,
277
+ .InfiniteLoading-btn:disabled,
278
+ .ContactForm-btn:disabled {
279
+ background-color: #ccc;
280
+ border-color: #ccc;
281
+ }
282
+
283
+ .SearchOpenerBtn {
284
+ display: flex;
285
+ }
286
+
287
+ .Field {
288
+ margin: 20px 0;
289
+ }
290
+
291
+ .Field:has(> .Field-img) {
292
+ display: flex;
293
+ flex-wrap: wrap;
294
+ gap: 5px;
295
+ justify-content: center;
296
+ }
297
+
298
+ .Field-img {
299
+ border-radius: 10px;
300
+ }
301
+
302
+ .Indent {
303
+ border-left: 4px solid #888;
304
+ margin-left: 40px;
305
+ }
306
+
307
+ .Row {
308
+ display: flex;
309
+ gap: 20px;
310
+ }
311
+
312
+ .Row.spaceBetween {
313
+ justify-content: space-between;
314
+ }
315
+
316
+ .SearchPageResponse,
317
+ .SearchPageResponse div {
318
+ display: flex;
319
+ flex-direction: column;
320
+ align-items: center;
321
+ gap: 20px;
322
+ }`;
323
+ }
@@ -0,0 +1,42 @@
1
+ export function createL10n(analysis, siteSchema) {
2
+ const l10n = {};
3
+ const language = analysis.siteProperties.language;
4
+ const siteLocales = analysis.siteProperties.theme
5
+ ? {
6
+ siteTheme: analysis.siteProperties.theme,
7
+ nodeTypes: {},
8
+ }
9
+ : {
10
+ nodeTypes: {},
11
+ };
12
+ l10n[language] = siteLocales;
13
+ const typeLabels = l10n[language].nodeTypes;
14
+ for (const nodeType of siteSchema.nodeTypes ?? []) {
15
+ if (nodeType.kind === "site")
16
+ continue;
17
+ const saType = analysis.dictionary[nodeType.typeName];
18
+ if (!saType)
19
+ continue;
20
+ const currentEntry = {
21
+ label: saType.label,
22
+ };
23
+ if (saType.description) {
24
+ currentEntry.description = saType.description;
25
+ }
26
+ if (nodeType.kind === "document" && nodeType.lists) {
27
+ currentEntry.lists = {};
28
+ for (const list of nodeType.lists) {
29
+ const listEntry = analysis.dictionary[list.listName];
30
+ const listLocales = {
31
+ label: listEntry?.label ?? list.listName,
32
+ };
33
+ currentEntry.lists[list.listName] = listLocales;
34
+ if (listEntry?.description) {
35
+ listLocales.description = listEntry?.description;
36
+ }
37
+ }
38
+ }
39
+ typeLabels[nodeType.typeName] = currentEntry;
40
+ }
41
+ return l10n;
42
+ }
@@ -0,0 +1,240 @@
1
+ import { generateSlug } from "@paroicms/public-anywhere-lib";
2
+ export function createSiteSchemaFromAnalysis(analysis) {
3
+ const { siteProperties } = analysis;
4
+ const siteSchema = {
5
+ version: "7",
6
+ languages: [siteProperties.language],
7
+ plugins: [
8
+ "@paroicms/quill-editor-plugin",
9
+ "@paroicms/content-loading-plugin",
10
+ "@paroicms/public-menu-plugin",
11
+ "@paroicms/contact-form-plugin",
12
+ ],
13
+ nodeTypes: [
14
+ {
15
+ kind: "site",
16
+ },
17
+ ...toNodeTypes(analysis),
18
+ ],
19
+ };
20
+ return siteSchema;
21
+ }
22
+ function toNodeTypes(analysis) {
23
+ const nodeTypes = new Map(Object.entries(analysis.dictionary)
24
+ .map(([typeName, saType]) => [typeName, toNodeType(typeName, saType)])
25
+ .filter(([_, item]) => !!item));
26
+ const ctx = {
27
+ language: analysis.siteProperties.language,
28
+ analysis,
29
+ nodeTypes,
30
+ treeNodeDict: new Map(),
31
+ };
32
+ walkTree(analysis.tree.home, undefined, ctx);
33
+ const result = []; // keep the original order
34
+ for (const typeName of Object.keys(analysis.dictionary)) {
35
+ const found = nodeTypes.get(typeName);
36
+ if (!found)
37
+ continue; // it's a partList
38
+ result.push(found);
39
+ }
40
+ return result;
41
+ }
42
+ function walkTree(saNode, parentNode, ctx) {
43
+ const { typeName } = saNode;
44
+ const nodeType = ctx.nodeTypes.get(typeName);
45
+ if (!nodeType)
46
+ throw new Error(`Missing definition of node type "${typeName}"`);
47
+ const saType = ctx.analysis.dictionary[typeName];
48
+ if (!saType)
49
+ throw new Error(`Missing definition of node type "${typeName}"`);
50
+ if (ctx.treeNodeDict.has(typeName)) {
51
+ if (saNode.children)
52
+ throw new Error(`Duplicate definition of node type "${typeName}"`);
53
+ if (!parentNode)
54
+ throw new Error("Home node cannot be a reference");
55
+ if (nodeType.kind === "document") {
56
+ if (nodeType.documentKind === "routing") {
57
+ throw new Error(`A routing document cannot be a reference: "${typeName}"`);
58
+ }
59
+ if (nodeType.documentKind === "regular") {
60
+ if (saNode.kind !== "regularDocument") {
61
+ throw new Error(`Inconsistant kind for document "${typeName}"`);
62
+ }
63
+ appendAsChildRegularDocument({
64
+ nodeType,
65
+ typeName,
66
+ parentNode,
67
+ children: undefined,
68
+ }, ctx);
69
+ }
70
+ else {
71
+ throw new Error(`Unexpected document kind: "${nodeType.documentKind}"`);
72
+ }
73
+ }
74
+ else if (nodeType.kind === "part") {
75
+ if (saNode.kind !== "part") {
76
+ throw new Error(`Inconsistant kind for part "${typeName}"`);
77
+ }
78
+ appendAsChildPart({
79
+ nodeType,
80
+ typeName,
81
+ parentNode,
82
+ children: undefined,
83
+ listName: saNode.listName,
84
+ }, ctx);
85
+ }
86
+ else {
87
+ throw new Error(`Unexpected kind: "${nodeType.kind}"`);
88
+ }
89
+ return;
90
+ }
91
+ ctx.treeNodeDict.set(typeName, saNode);
92
+ if (saNode.kind === "routingDocument") {
93
+ if (nodeType.kind !== "document" || nodeType.documentKind !== "routing") {
94
+ throw new Error(`In the tree, "${typeName}" is used as a routing document but it is a "${nodeType.kind}"`);
95
+ }
96
+ if (parentNode) {
97
+ appendAsRoutingChild({
98
+ nodeType,
99
+ typeName,
100
+ parentNode,
101
+ });
102
+ }
103
+ }
104
+ else {
105
+ if (!parentNode)
106
+ throw new Error("Home node should be a routing document");
107
+ if (saNode.kind === "regularDocument") {
108
+ if (nodeType.kind !== "document" || nodeType.documentKind !== "regular") {
109
+ throw new Error(`In the tree, "${typeName}" is used as a regular document but it is a "${nodeType.kind}"`);
110
+ }
111
+ appendAsChildRegularDocument({
112
+ nodeType,
113
+ typeName,
114
+ parentNode,
115
+ children: saNode.children,
116
+ }, ctx);
117
+ }
118
+ else if (saNode.kind === "part") {
119
+ if (!parentNode)
120
+ throw new Error("Home node cannot be a list");
121
+ if (nodeType.kind !== "part") {
122
+ throw new Error(`In the tree, "${typeName}" is used as a part but it is a "${nodeType.kind}"`);
123
+ }
124
+ appendAsChildPart({
125
+ nodeType,
126
+ typeName,
127
+ parentNode,
128
+ children: saNode.children,
129
+ listName: saNode.listName,
130
+ }, ctx);
131
+ }
132
+ else {
133
+ throw new Error(`Unexpected node kind: "${saNode.kind}"`);
134
+ }
135
+ }
136
+ saNode.children?.forEach((child) => walkTree(child, nodeType, ctx));
137
+ }
138
+ function appendAsRoutingChild(options) {
139
+ const { nodeType, typeName, parentNode } = options;
140
+ if (nodeType.kind !== "document") {
141
+ throw new Error(`In the tree, "${typeName}" is used as a routing document but it is a "${nodeType.kind}"`);
142
+ }
143
+ if (nodeType.documentKind !== "routing") {
144
+ throw new Error(`In the tree, "${typeName}" is used as a routing document but it is a "${nodeType.documentKind}"`);
145
+ }
146
+ if (parentNode.kind !== "document") {
147
+ throw new Error(`In the tree, "${typeName}" is used as a routing document but its parent is a "${parentNode.kind}"`);
148
+ }
149
+ if (parentNode.documentKind !== "routing") {
150
+ throw new Error(`Due to a technical limitation, routing document "${typeName}" can't be used as child of "${parentNode.documentKind}"`);
151
+ }
152
+ parentNode.routingChildren ??= [];
153
+ parentNode.routingChildren.push(typeName);
154
+ }
155
+ function appendAsChildRegularDocument(options, ctx) {
156
+ const { nodeType, typeName, parentNode, children } = options;
157
+ const saType = ctx.analysis.dictionary[typeName];
158
+ if (nodeType.kind !== "document") {
159
+ throw new Error(`In the tree, "${typeName}" is used as a regular document but it is a "${nodeType.kind}"`);
160
+ }
161
+ if (nodeType.documentKind !== "regular") {
162
+ throw new Error(`In the tree, "${typeName}" is used as a regular document but it is a "${nodeType.documentKind}"`);
163
+ }
164
+ if (parentNode.kind !== "document") {
165
+ throw new Error(`In the tree, "${typeName}" is used as a regular document but its parent is a "${parentNode.kind}"`);
166
+ }
167
+ if (!parentNode.regularChildren) {
168
+ parentNode.regularChildren = [];
169
+ parentNode.regularChildrenSorting = saType.temporal ? "publishDate desc" : "title asc";
170
+ }
171
+ parentNode.regularChildren.push(typeName);
172
+ children?.forEach((child) => walkTree(child, nodeType, ctx));
173
+ }
174
+ function appendAsChildPart(options, ctx) {
175
+ const { nodeType, typeName, parentNode, children, listName } = options;
176
+ const saType = ctx.analysis.dictionary[typeName];
177
+ if (nodeType.kind !== "part") {
178
+ throw new Error(`In the tree, "${typeName}" is used as a part but it is a "${nodeType.kind}"`);
179
+ }
180
+ if (parentNode.kind === "document") {
181
+ parentNode.lists ??= [];
182
+ parentNode.lists.push({
183
+ listName,
184
+ parts: [typeName],
185
+ sorting: saType.temporal ? "publishDate desc" : "manual",
186
+ });
187
+ }
188
+ else if (parentNode.kind === "part") {
189
+ if (parentNode.list) {
190
+ parentNode.list.parts.push(typeName);
191
+ }
192
+ else {
193
+ parentNode.list = {
194
+ parts: [typeName],
195
+ sorting: saType.temporal ? "publishDate desc" : "manual",
196
+ };
197
+ }
198
+ }
199
+ else {
200
+ throw new Error(`Unexpected kind: "${parentNode.kind}"`);
201
+ }
202
+ children?.forEach((child) => walkTree(child, nodeType, ctx));
203
+ }
204
+ export function toNodeType(typeName, saType) {
205
+ if (saType.kind === "part")
206
+ return toPartNodeType(typeName);
207
+ if (saType.kind === "regularDocument")
208
+ return toRegularDocumentNodeType(typeName, saType);
209
+ if (saType.kind === "routingDocument")
210
+ return toRoutingDocumentNodeType(typeName, saType);
211
+ if (saType.kind === "partList")
212
+ return;
213
+ throw new Error(`Unexpected kind: "${saType.kind}" for node type "${typeName}"`);
214
+ }
215
+ function toPartNodeType(typeName) {
216
+ return {
217
+ typeName,
218
+ kind: "part",
219
+ };
220
+ }
221
+ function toRoutingDocumentNodeType(typeName, saType) {
222
+ return {
223
+ typeName,
224
+ kind: "document",
225
+ documentKind: "routing",
226
+ ogType: saType.ogType,
227
+ route: generateSlug(saType.label),
228
+ withFeaturedImage: typeName !== "home" && !!saType.entryPage,
229
+ };
230
+ }
231
+ function toRegularDocumentNodeType(typeName, saType) {
232
+ return {
233
+ typeName,
234
+ kind: "document",
235
+ documentKind: "regular",
236
+ ogType: saType.ogType,
237
+ route: saType.temporal ? ":yyyy/:mm/:dd/:relativeId-:slug" : ":relativeId-:slug",
238
+ withFeaturedImage: true,
239
+ };
240
+ }
@@ -0,0 +1,38 @@
1
+ import { getJtHomeType } from "../site-generator/jt-site-schema-helpers.js";
2
+ export function appendDefaultPages(siteSchema, l10n) {
3
+ if (!siteSchema.nodeTypes)
4
+ return;
5
+ const homeType = getJtHomeType(siteSchema);
6
+ homeType.routingChildren ??= [];
7
+ homeType.routingChildren.push("searchPage", "contactPage");
8
+ siteSchema.nodeTypes.push({
9
+ typeName: "searchPage",
10
+ kind: "document",
11
+ documentKind: "routing",
12
+ route: {
13
+ en: "search",
14
+ fr: "recherche",
15
+ },
16
+ withFeaturedImage: false,
17
+ }, {
18
+ typeName: "contactPage",
19
+ kind: "document",
20
+ documentKind: "routing",
21
+ route: {
22
+ en: "contact-us",
23
+ fr: "contactez-nous",
24
+ },
25
+ withFeaturedImage: false,
26
+ });
27
+ for (const [language, l10nData] of Object.entries(l10n)) {
28
+ l10nData.nodeTypes ??= {};
29
+ if (typeof l10nData.nodeTypes !== "object")
30
+ throw new Error("Invalid l10n data");
31
+ l10nData.nodeTypes.searchPage = {
32
+ label: language === "fr" ? "Page de recherche" : "Search Page",
33
+ };
34
+ l10nData.nodeTypes.contactPage = {
35
+ label: language === "fr" ? "Page de contact" : "Contact Page",
36
+ };
37
+ }
38
+ }