meno-core 1.0.40 → 1.0.41
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/bin/cli.ts +33 -0
- package/build-astro.ts +3 -27
- package/dist/bin/cli.js +30 -2
- package/dist/bin/cli.js.map +2 -2
- package/dist/build-static.js +7 -7
- package/dist/chunks/{chunk-3NOZVNM4.js → chunk-EQOSDQS2.js} +4 -4
- package/dist/chunks/{chunk-V4SVSX3X.js → chunk-IBR2F4IL.js} +4 -5
- package/dist/chunks/{chunk-V4SVSX3X.js.map → chunk-IBR2F4IL.js.map} +2 -2
- package/dist/chunks/{chunk-OJ5SROQN.js → chunk-IGVQF5GY.js} +8 -6
- package/dist/chunks/chunk-IGVQF5GY.js.map +7 -0
- package/dist/chunks/{chunk-Z7SAOCDG.js → chunk-LBWIHPN7.js} +5 -2
- package/dist/chunks/{chunk-Z7SAOCDG.js.map → chunk-LBWIHPN7.js.map} +2 -2
- package/dist/chunks/{chunk-A6KWUEA6.js → chunk-MKB2J6AD.js} +9 -1
- package/dist/chunks/chunk-MKB2J6AD.js.map +7 -0
- package/dist/chunks/{chunk-LOJLO2EY.js → chunk-S2HXJTAF.js} +1 -1
- package/dist/chunks/chunk-S2HXJTAF.js.map +7 -0
- package/dist/chunks/{chunk-GKICS7CF.js → chunk-SK3TLNUP.js} +120 -107
- package/dist/chunks/chunk-SK3TLNUP.js.map +7 -0
- package/dist/chunks/{chunk-MOCRENNU.js → chunk-SNUROC7E.js} +6 -6
- package/dist/chunks/{configService-TXBNUBBL.js → configService-MICL4S2L.js} +2 -2
- package/dist/chunks/{constants-L75FR445.js → constants-ZEU4TZCA.js} +2 -2
- package/dist/entries/server-router.js +7 -7
- package/dist/lib/client/index.js +9 -4
- package/dist/lib/client/index.js.map +2 -2
- package/dist/lib/server/index.js +76 -2966
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +3 -3
- package/dist/lib/test-utils/index.js +1 -1
- package/lib/client/core/ComponentBuilder.ts +1 -1
- package/lib/client/routing/Router.tsx +6 -0
- package/lib/client/templateEngine.test.ts +178 -0
- package/lib/client/templateEngine.ts +1 -2
- package/lib/server/astro/cmsPageEmitter.ts +3 -0
- package/lib/server/astro/componentEmitter.ts +60 -12
- package/lib/server/astro/nodeToAstro.test.ts +1101 -0
- package/lib/server/astro/nodeToAstro.ts +43 -4
- package/lib/server/astro/pageEmitter.ts +4 -0
- package/lib/server/index.ts +18 -4
- package/lib/server/services/configService.ts +12 -0
- package/lib/server/ssr/htmlGenerator.ts +0 -5
- package/lib/server/ssr/imageMetadata.ts +3 -3
- package/lib/server/ssr/ssrRenderer.ts +48 -19
- package/lib/shared/constants.ts +2 -0
- package/lib/shared/types/components.ts +8 -4
- package/lib/shared/validation/propValidator.ts +2 -1
- package/lib/shared/validation/schemas.ts +3 -1
- package/package.json +1 -1
- package/templates/index-router.html +0 -5
- package/dist/chunks/chunk-A6KWUEA6.js.map +0 -7
- package/dist/chunks/chunk-GKICS7CF.js.map +0 -7
- package/dist/chunks/chunk-LOJLO2EY.js.map +0 -7
- package/dist/chunks/chunk-OJ5SROQN.js.map +0 -7
- /package/dist/chunks/{chunk-3NOZVNM4.js.map → chunk-EQOSDQS2.js.map} +0 -0
- /package/dist/chunks/{chunk-MOCRENNU.js.map → chunk-SNUROC7E.js.map} +0 -0
- /package/dist/chunks/{configService-TXBNUBBL.js.map → configService-MICL4S2L.js.map} +0 -0
- /package/dist/chunks/{constants-L75FR445.js.map → constants-ZEU4TZCA.js.map} +0 -0
package/dist/lib/server/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "../../chunks/chunk-4OFZP5NQ.js";
|
|
4
4
|
import {
|
|
5
5
|
buildStaticPages
|
|
6
|
-
} from "../../chunks/chunk-
|
|
6
|
+
} from "../../chunks/chunk-EQOSDQS2.js";
|
|
7
7
|
import {
|
|
8
8
|
ComponentService,
|
|
9
9
|
EnumService,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
logResponseTime,
|
|
33
33
|
withErrorHandling,
|
|
34
34
|
withLogging
|
|
35
|
-
} from "../../chunks/chunk-
|
|
35
|
+
} from "../../chunks/chunk-SNUROC7E.js";
|
|
36
36
|
import {
|
|
37
37
|
CMSService,
|
|
38
38
|
ColorService,
|
|
@@ -43,19 +43,15 @@ import {
|
|
|
43
43
|
buildAttributes,
|
|
44
44
|
buildComponentHTML,
|
|
45
45
|
buildImageMetadataMap,
|
|
46
|
-
buildSlugIndex,
|
|
47
46
|
clearJSValidationCache,
|
|
48
47
|
collectComponentCSS,
|
|
49
48
|
collectComponentJavaScript,
|
|
50
|
-
collectComponentLibraries,
|
|
51
49
|
colorService,
|
|
52
50
|
createI18nResolver,
|
|
53
51
|
escapeHtml,
|
|
54
52
|
extractPageMeta,
|
|
55
|
-
filterLibrariesByContext,
|
|
56
53
|
generateFontCSS,
|
|
57
54
|
generateFontPreloadTags,
|
|
58
|
-
generateLibraryTags,
|
|
59
55
|
generateMetaTags,
|
|
60
56
|
generateSSRHTML,
|
|
61
57
|
generateThemeColorVariablesCSS,
|
|
@@ -68,7 +64,6 @@ import {
|
|
|
68
64
|
loadProjectConfig,
|
|
69
65
|
loadResponsiveScalesConfig,
|
|
70
66
|
mapPageNameToPath,
|
|
71
|
-
mergeLibraries,
|
|
72
67
|
migrateTemplatesDirectory,
|
|
73
68
|
parseJSON,
|
|
74
69
|
processCMSPropsTemplate,
|
|
@@ -76,13 +71,12 @@ import {
|
|
|
76
71
|
renderPageSSR,
|
|
77
72
|
resetFontConfig,
|
|
78
73
|
styleToString,
|
|
79
|
-
translatePath,
|
|
80
74
|
variableService
|
|
81
|
-
} from "../../chunks/chunk-
|
|
75
|
+
} from "../../chunks/chunk-SK3TLNUP.js";
|
|
82
76
|
import {
|
|
83
77
|
ConfigService,
|
|
84
78
|
configService
|
|
85
|
-
} from "../../chunks/chunk-
|
|
79
|
+
} from "../../chunks/chunk-MKB2J6AD.js";
|
|
86
80
|
import {
|
|
87
81
|
bundleFile,
|
|
88
82
|
createRuntimeServer,
|
|
@@ -112,23 +106,14 @@ import {
|
|
|
112
106
|
writeFile
|
|
113
107
|
} from "../../chunks/chunk-WQFG7PAH.js";
|
|
114
108
|
import "../../chunks/chunk-LIHJ6OUH.js";
|
|
115
|
-
import "../../chunks/chunk-
|
|
116
|
-
import "../../chunks/chunk-
|
|
109
|
+
import "../../chunks/chunk-S2HXJTAF.js";
|
|
110
|
+
import "../../chunks/chunk-IBR2F4IL.js";
|
|
117
111
|
import {
|
|
118
|
-
extractInteractiveStyleMappings,
|
|
119
|
-
extractUtilityClassesFromHTML,
|
|
120
|
-
generateAllInteractiveCSS,
|
|
121
112
|
generateElementClassName,
|
|
122
|
-
generateUtilityCSS,
|
|
123
|
-
hasInteractiveStyleMappings,
|
|
124
113
|
isItemDraftForLocale,
|
|
125
|
-
isVoidElement
|
|
126
|
-
|
|
127
|
-
} from "../../chunks/chunk-OJ5SROQN.js";
|
|
114
|
+
isVoidElement
|
|
115
|
+
} from "../../chunks/chunk-IGVQF5GY.js";
|
|
128
116
|
import {
|
|
129
|
-
DEFAULT_BREAKPOINTS,
|
|
130
|
-
DEFAULT_I18N_CONFIG,
|
|
131
|
-
buildLocalizedPath,
|
|
132
117
|
isI18nValue,
|
|
133
118
|
resolveI18nValue
|
|
134
119
|
} from "../../chunks/chunk-PGH3ATYI.js";
|
|
@@ -137,2900 +122,15 @@ import {
|
|
|
137
122
|
HMR_ROUTE,
|
|
138
123
|
MAX_PORT_ATTEMPTS,
|
|
139
124
|
NODE_TYPE,
|
|
140
|
-
RAW_HTML_PREFIX,
|
|
141
125
|
SERVER_PORT,
|
|
142
126
|
SERVE_PORT,
|
|
143
127
|
init_constants
|
|
144
|
-
} from "../../chunks/chunk-
|
|
128
|
+
} from "../../chunks/chunk-LBWIHPN7.js";
|
|
145
129
|
import "../../chunks/chunk-KSBZ2L7C.js";
|
|
146
130
|
|
|
147
|
-
// build-astro.ts
|
|
148
|
-
import { existsSync, readdirSync, mkdirSync, rmSync, statSync, copyFileSync } from "fs";
|
|
149
|
-
import { writeFile as writeFile2, readFile } from "fs/promises";
|
|
150
|
-
import { join } from "path";
|
|
151
|
-
import { createHash } from "crypto";
|
|
152
|
-
|
|
153
|
-
// lib/server/astro/tailwindMapper.ts
|
|
154
|
-
function isStyleMapping(value) {
|
|
155
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
156
|
-
}
|
|
157
|
-
function hasTemplateExpression(value) {
|
|
158
|
-
return /\{\{.+?\}\}/.test(value);
|
|
159
|
-
}
|
|
160
|
-
function isResponsiveStyle(style) {
|
|
161
|
-
return "base" in style || "tablet" in style || "mobile" in style;
|
|
162
|
-
}
|
|
163
|
-
var exactMatches = {
|
|
164
|
-
display: {
|
|
165
|
-
flex: "flex",
|
|
166
|
-
grid: "grid",
|
|
167
|
-
block: "block",
|
|
168
|
-
none: "hidden",
|
|
169
|
-
inline: "inline",
|
|
170
|
-
"inline-block": "inline-block",
|
|
171
|
-
"inline-flex": "inline-flex",
|
|
172
|
-
"inline-grid": "inline-grid"
|
|
173
|
-
},
|
|
174
|
-
flexDirection: {
|
|
175
|
-
column: "flex-col",
|
|
176
|
-
row: "flex-row",
|
|
177
|
-
"column-reverse": "flex-col-reverse",
|
|
178
|
-
"row-reverse": "flex-row-reverse"
|
|
179
|
-
},
|
|
180
|
-
justifyContent: {
|
|
181
|
-
center: "justify-center",
|
|
182
|
-
"flex-start": "justify-start",
|
|
183
|
-
"flex-end": "justify-end",
|
|
184
|
-
"space-between": "justify-between",
|
|
185
|
-
"space-around": "justify-around",
|
|
186
|
-
"space-evenly": "justify-evenly",
|
|
187
|
-
// camelCase aliases (component data uses camelCase)
|
|
188
|
-
spaceBetween: "justify-between",
|
|
189
|
-
spaceAround: "justify-around",
|
|
190
|
-
spaceEvenly: "justify-evenly",
|
|
191
|
-
flexStart: "justify-start",
|
|
192
|
-
flexEnd: "justify-end"
|
|
193
|
-
},
|
|
194
|
-
alignItems: {
|
|
195
|
-
center: "items-center",
|
|
196
|
-
"flex-start": "items-start",
|
|
197
|
-
"flex-end": "items-end",
|
|
198
|
-
stretch: "items-stretch",
|
|
199
|
-
baseline: "items-baseline",
|
|
200
|
-
// camelCase aliases
|
|
201
|
-
flexStart: "items-start",
|
|
202
|
-
flexEnd: "items-end"
|
|
203
|
-
},
|
|
204
|
-
alignContent: {
|
|
205
|
-
center: "content-center",
|
|
206
|
-
"flex-start": "content-start",
|
|
207
|
-
"flex-end": "content-end",
|
|
208
|
-
"space-between": "content-between",
|
|
209
|
-
"space-around": "content-around",
|
|
210
|
-
stretch: "content-stretch"
|
|
211
|
-
},
|
|
212
|
-
alignSelf: {
|
|
213
|
-
auto: "self-auto",
|
|
214
|
-
center: "self-center",
|
|
215
|
-
"flex-start": "self-start",
|
|
216
|
-
"flex-end": "self-end",
|
|
217
|
-
stretch: "self-stretch"
|
|
218
|
-
},
|
|
219
|
-
position: {
|
|
220
|
-
relative: "relative",
|
|
221
|
-
absolute: "absolute",
|
|
222
|
-
fixed: "fixed",
|
|
223
|
-
sticky: "sticky",
|
|
224
|
-
static: "static"
|
|
225
|
-
},
|
|
226
|
-
overflow: {
|
|
227
|
-
hidden: "overflow-hidden",
|
|
228
|
-
auto: "overflow-auto",
|
|
229
|
-
scroll: "overflow-scroll",
|
|
230
|
-
visible: "overflow-visible"
|
|
231
|
-
},
|
|
232
|
-
overflowX: {
|
|
233
|
-
hidden: "overflow-x-hidden",
|
|
234
|
-
auto: "overflow-x-auto",
|
|
235
|
-
scroll: "overflow-x-scroll",
|
|
236
|
-
visible: "overflow-x-visible"
|
|
237
|
-
},
|
|
238
|
-
overflowY: {
|
|
239
|
-
hidden: "overflow-y-hidden",
|
|
240
|
-
auto: "overflow-y-auto",
|
|
241
|
-
scroll: "overflow-y-scroll",
|
|
242
|
-
visible: "overflow-y-visible"
|
|
243
|
-
},
|
|
244
|
-
cursor: {
|
|
245
|
-
pointer: "cursor-pointer",
|
|
246
|
-
default: "cursor-default",
|
|
247
|
-
"not-allowed": "cursor-not-allowed",
|
|
248
|
-
grab: "cursor-grab",
|
|
249
|
-
grabbing: "cursor-grabbing",
|
|
250
|
-
text: "cursor-text",
|
|
251
|
-
move: "cursor-move",
|
|
252
|
-
wait: "cursor-wait"
|
|
253
|
-
},
|
|
254
|
-
textAlign: {
|
|
255
|
-
center: "text-center",
|
|
256
|
-
left: "text-left",
|
|
257
|
-
right: "text-right",
|
|
258
|
-
justify: "text-justify"
|
|
259
|
-
},
|
|
260
|
-
textDecoration: {
|
|
261
|
-
none: "no-underline",
|
|
262
|
-
underline: "underline",
|
|
263
|
-
"line-through": "line-through",
|
|
264
|
-
overline: "overline"
|
|
265
|
-
},
|
|
266
|
-
textTransform: {
|
|
267
|
-
uppercase: "uppercase",
|
|
268
|
-
lowercase: "lowercase",
|
|
269
|
-
capitalize: "capitalize",
|
|
270
|
-
none: "normal-case"
|
|
271
|
-
},
|
|
272
|
-
objectFit: {
|
|
273
|
-
cover: "object-cover",
|
|
274
|
-
contain: "object-contain",
|
|
275
|
-
fill: "object-fill",
|
|
276
|
-
none: "object-none",
|
|
277
|
-
"scale-down": "object-scale-down"
|
|
278
|
-
},
|
|
279
|
-
objectPosition: {
|
|
280
|
-
center: "object-center",
|
|
281
|
-
top: "object-top",
|
|
282
|
-
bottom: "object-bottom",
|
|
283
|
-
left: "object-left",
|
|
284
|
-
right: "object-right"
|
|
285
|
-
},
|
|
286
|
-
flexWrap: {
|
|
287
|
-
wrap: "flex-wrap",
|
|
288
|
-
nowrap: "flex-nowrap",
|
|
289
|
-
"wrap-reverse": "flex-wrap-reverse"
|
|
290
|
-
},
|
|
291
|
-
pointerEvents: {
|
|
292
|
-
none: "pointer-events-none",
|
|
293
|
-
auto: "pointer-events-auto"
|
|
294
|
-
},
|
|
295
|
-
userSelect: {
|
|
296
|
-
none: "select-none",
|
|
297
|
-
auto: "select-auto",
|
|
298
|
-
text: "select-text",
|
|
299
|
-
all: "select-all"
|
|
300
|
-
},
|
|
301
|
-
visibility: {
|
|
302
|
-
hidden: "invisible",
|
|
303
|
-
visible: "visible"
|
|
304
|
-
},
|
|
305
|
-
whiteSpace: {
|
|
306
|
-
normal: "whitespace-normal",
|
|
307
|
-
nowrap: "whitespace-nowrap",
|
|
308
|
-
pre: "whitespace-pre",
|
|
309
|
-
"pre-wrap": "whitespace-pre-wrap",
|
|
310
|
-
"pre-line": "whitespace-pre-line"
|
|
311
|
-
},
|
|
312
|
-
wordBreak: {
|
|
313
|
-
"break-all": "break-all",
|
|
314
|
-
"break-word": "break-words",
|
|
315
|
-
normal: "break-normal"
|
|
316
|
-
},
|
|
317
|
-
listStyleType: {
|
|
318
|
-
none: "list-none",
|
|
319
|
-
disc: "list-disc",
|
|
320
|
-
decimal: "list-decimal"
|
|
321
|
-
},
|
|
322
|
-
listStylePosition: {
|
|
323
|
-
inside: "list-inside",
|
|
324
|
-
outside: "list-outside"
|
|
325
|
-
},
|
|
326
|
-
boxSizing: {
|
|
327
|
-
"border-box": "box-border",
|
|
328
|
-
"content-box": "box-content"
|
|
329
|
-
},
|
|
330
|
-
gridAutoFlow: {
|
|
331
|
-
row: "grid-flow-row",
|
|
332
|
-
column: "grid-flow-col",
|
|
333
|
-
dense: "grid-flow-dense",
|
|
334
|
-
"row dense": "grid-flow-row-dense",
|
|
335
|
-
"column dense": "grid-flow-col-dense"
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
var singleValueMatches = {
|
|
339
|
-
// width/height 100%
|
|
340
|
-
"width:100%": "w-full",
|
|
341
|
-
"height:100%": "h-full",
|
|
342
|
-
"width:100vw": "w-screen",
|
|
343
|
-
"height:100vh": "h-screen",
|
|
344
|
-
"width:auto": "w-auto",
|
|
345
|
-
"height:auto": "h-auto",
|
|
346
|
-
"width:fit-content": "w-fit",
|
|
347
|
-
"height:fit-content": "h-fit",
|
|
348
|
-
"width:min-content": "w-min",
|
|
349
|
-
"height:min-content": "h-min",
|
|
350
|
-
"width:max-content": "w-max",
|
|
351
|
-
"height:max-content": "h-max",
|
|
352
|
-
"maxWidth:100%": "max-w-full",
|
|
353
|
-
"maxWidth:none": "max-w-none",
|
|
354
|
-
"maxHeight:100%": "max-h-full",
|
|
355
|
-
"maxHeight:none": "max-h-none",
|
|
356
|
-
"minWidth:0": "min-w-0",
|
|
357
|
-
"minHeight:0": "min-h-0",
|
|
358
|
-
"margin:auto": "m-auto",
|
|
359
|
-
"margin:0 auto": "mx-auto",
|
|
360
|
-
"marginLeft:auto": "ml-auto",
|
|
361
|
-
"marginRight:auto": "mr-auto",
|
|
362
|
-
"marginInline:auto": "mx-auto",
|
|
363
|
-
"borderRadius:50%": "rounded-full",
|
|
364
|
-
"borderRadius:9999px": "rounded-full",
|
|
365
|
-
"borderRadius:0": "rounded-none",
|
|
366
|
-
"flex:1": "flex-1",
|
|
367
|
-
"flex:none": "flex-none",
|
|
368
|
-
"flex:auto": "flex-auto",
|
|
369
|
-
"flexGrow:0": "grow-0",
|
|
370
|
-
"flexGrow:1": "grow",
|
|
371
|
-
"flexShrink:0": "shrink-0",
|
|
372
|
-
"flexShrink:1": "shrink",
|
|
373
|
-
"opacity:0": "opacity-0",
|
|
374
|
-
"opacity:1": "opacity-100",
|
|
375
|
-
"zIndex:0": "z-0",
|
|
376
|
-
"zIndex:10": "z-10",
|
|
377
|
-
"zIndex:20": "z-20",
|
|
378
|
-
"zIndex:30": "z-30",
|
|
379
|
-
"zIndex:40": "z-40",
|
|
380
|
-
"zIndex:50": "z-50",
|
|
381
|
-
"inset:0": "inset-0",
|
|
382
|
-
"top:0": "top-0",
|
|
383
|
-
"right:0": "right-0",
|
|
384
|
-
"bottom:0": "bottom-0",
|
|
385
|
-
"left:0": "left-0",
|
|
386
|
-
"outline:none": "[outline:none]",
|
|
387
|
-
"background:none": "[background:none]",
|
|
388
|
-
"background:transparent": "[background:transparent]",
|
|
389
|
-
"backgroundColor:transparent": "bg-transparent"
|
|
390
|
-
};
|
|
391
|
-
var arbitraryPrefixMap = {
|
|
392
|
-
// Spacing
|
|
393
|
-
padding: "p",
|
|
394
|
-
paddingTop: "pt",
|
|
395
|
-
paddingRight: "pr",
|
|
396
|
-
paddingBottom: "pb",
|
|
397
|
-
paddingLeft: "pl",
|
|
398
|
-
paddingInline: "px",
|
|
399
|
-
paddingBlock: "py",
|
|
400
|
-
margin: "m",
|
|
401
|
-
marginTop: "mt",
|
|
402
|
-
marginRight: "mr",
|
|
403
|
-
marginBottom: "mb",
|
|
404
|
-
marginLeft: "ml",
|
|
405
|
-
marginInline: "mx",
|
|
406
|
-
marginBlock: "my",
|
|
407
|
-
gap: "gap",
|
|
408
|
-
rowGap: "gap-y",
|
|
409
|
-
columnGap: "gap-x",
|
|
410
|
-
// Sizing
|
|
411
|
-
width: "w",
|
|
412
|
-
height: "h",
|
|
413
|
-
maxWidth: "max-w",
|
|
414
|
-
maxHeight: "max-h",
|
|
415
|
-
minWidth: "min-w",
|
|
416
|
-
minHeight: "min-h",
|
|
417
|
-
// Typography
|
|
418
|
-
fontSize: "text",
|
|
419
|
-
fontWeight: "font",
|
|
420
|
-
fontFamily: "font",
|
|
421
|
-
lineHeight: "leading",
|
|
422
|
-
letterSpacing: "tracking",
|
|
423
|
-
// Borders
|
|
424
|
-
borderRadius: "rounded",
|
|
425
|
-
borderTopLeftRadius: "rounded-tl",
|
|
426
|
-
borderTopRightRadius: "rounded-tr",
|
|
427
|
-
borderBottomLeftRadius: "rounded-bl",
|
|
428
|
-
borderBottomRightRadius: "rounded-br",
|
|
429
|
-
border: "border",
|
|
430
|
-
borderTop: "border-t",
|
|
431
|
-
borderRight: "border-r",
|
|
432
|
-
borderBottom: "border-b",
|
|
433
|
-
borderLeft: "border-l",
|
|
434
|
-
borderColor: "border",
|
|
435
|
-
// Colors
|
|
436
|
-
color: "text",
|
|
437
|
-
backgroundColor: "bg",
|
|
438
|
-
background: "bg",
|
|
439
|
-
backgroundImage: "bg",
|
|
440
|
-
// Effects
|
|
441
|
-
opacity: "opacity",
|
|
442
|
-
boxShadow: "shadow",
|
|
443
|
-
textShadow: "[text-shadow]",
|
|
444
|
-
filter: "[filter]",
|
|
445
|
-
backdropFilter: "backdrop",
|
|
446
|
-
transform: "[transform]",
|
|
447
|
-
transformOrigin: "origin",
|
|
448
|
-
transition: "[transition]",
|
|
449
|
-
mixBlendMode: "mix-blend",
|
|
450
|
-
clipPath: "[clip-path]",
|
|
451
|
-
// Positioning
|
|
452
|
-
top: "top",
|
|
453
|
-
right: "right",
|
|
454
|
-
bottom: "bottom",
|
|
455
|
-
left: "left",
|
|
456
|
-
inset: "inset",
|
|
457
|
-
zIndex: "z",
|
|
458
|
-
// Grid
|
|
459
|
-
gridTemplateColumns: "grid-cols",
|
|
460
|
-
gridTemplateRows: "grid-rows",
|
|
461
|
-
gridColumn: "col",
|
|
462
|
-
gridRow: "row",
|
|
463
|
-
gridAutoRows: "auto-rows",
|
|
464
|
-
gridAutoColumns: "auto-cols",
|
|
465
|
-
// Flexbox extras
|
|
466
|
-
flexGrow: "grow",
|
|
467
|
-
flexShrink: "shrink",
|
|
468
|
-
flexBasis: "basis",
|
|
469
|
-
order: "order",
|
|
470
|
-
flex: "flex",
|
|
471
|
-
// Aspect ratio
|
|
472
|
-
aspectRatio: "aspect",
|
|
473
|
-
// Outline
|
|
474
|
-
outline: "outline",
|
|
475
|
-
outlineWidth: "outline",
|
|
476
|
-
outlineOffset: "outline-offset",
|
|
477
|
-
outlineColor: "outline",
|
|
478
|
-
// Other
|
|
479
|
-
accentColor: "accent",
|
|
480
|
-
textIndent: "[text-indent]",
|
|
481
|
-
verticalAlign: "align",
|
|
482
|
-
overflowWrap: "[overflow-wrap]",
|
|
483
|
-
scrollBehavior: "scroll",
|
|
484
|
-
resize: "resize"
|
|
485
|
-
};
|
|
486
|
-
function propertyToTailwind(property, value) {
|
|
487
|
-
const strValue = String(value);
|
|
488
|
-
if (strValue === "") return null;
|
|
489
|
-
if (hasTemplateExpression(strValue)) return null;
|
|
490
|
-
const singleKey = `${property}:${strValue}`;
|
|
491
|
-
if (singleValueMatches[singleKey]) {
|
|
492
|
-
return singleValueMatches[singleKey];
|
|
493
|
-
}
|
|
494
|
-
if (exactMatches[property]?.[strValue]) {
|
|
495
|
-
return exactMatches[property][strValue];
|
|
496
|
-
}
|
|
497
|
-
if (property === "color" || property === "backgroundColor" || property === "borderColor") {
|
|
498
|
-
const prefix = property === "color" ? "text" : property === "backgroundColor" ? "bg" : "border";
|
|
499
|
-
if (strValue.includes("var(")) {
|
|
500
|
-
return `${prefix}-[color:${strValue}]`;
|
|
501
|
-
}
|
|
502
|
-
if (!strValue.match(/^[#\d]/) && !strValue.includes("rgb") && !strValue.includes("hsl")) {
|
|
503
|
-
return `${prefix}-[color:var(--${strValue})]`;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
if (property === "borderColor" || property === "color") {
|
|
507
|
-
const prefix = property === "color" ? "text" : "border";
|
|
508
|
-
const sanitized2 = strValue.replace(/\s+/g, "_");
|
|
509
|
-
return `${prefix}-[color:${sanitized2}]`;
|
|
510
|
-
}
|
|
511
|
-
if (property === "border" || property === "borderTop" || property === "borderRight" || property === "borderBottom" || property === "borderLeft") {
|
|
512
|
-
if (strValue.includes("solid") || strValue.includes("dashed") || strValue.includes("dotted") || strValue.includes("none")) {
|
|
513
|
-
const cssProp = property.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
514
|
-
const sanitized2 = strValue.replace(/\s+/g, "_");
|
|
515
|
-
return `[${cssProp}:${sanitized2}]`;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
if (property === "background") {
|
|
519
|
-
const isSimpleColor = /^(#[0-9a-fA-F]{3,8}|rgb|hsl|var\()/.test(strValue);
|
|
520
|
-
if (!isSimpleColor) {
|
|
521
|
-
const sanitized2 = strValue.replace(/\s+/g, "_");
|
|
522
|
-
return `[background:${sanitized2}]`;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
const twPrefix = arbitraryPrefixMap[property];
|
|
526
|
-
if (!twPrefix) {
|
|
527
|
-
const cssProp = property.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
528
|
-
const sanitized2 = strValue.replace(/\s+/g, "_");
|
|
529
|
-
return `[${cssProp}:${sanitized2}]`;
|
|
530
|
-
}
|
|
531
|
-
if (twPrefix.startsWith("[")) {
|
|
532
|
-
const sanitized2 = strValue.replace(/\s+/g, "_");
|
|
533
|
-
return `${twPrefix.slice(0, -1)}:${sanitized2}]`;
|
|
534
|
-
}
|
|
535
|
-
const sanitized = strValue.replace(/\s+/g, "_");
|
|
536
|
-
if (property === "fontSize") {
|
|
537
|
-
return `text-[length:${sanitized}]`;
|
|
538
|
-
}
|
|
539
|
-
if (property === "fontFamily") {
|
|
540
|
-
return `font-[family-name:${sanitized}]`;
|
|
541
|
-
}
|
|
542
|
-
if (property === "fontWeight") {
|
|
543
|
-
return `font-[number:${sanitized}]`;
|
|
544
|
-
}
|
|
545
|
-
return `${twPrefix}-[${sanitized}]`;
|
|
546
|
-
}
|
|
547
|
-
function stylesToTailwind(style) {
|
|
548
|
-
const classes = [];
|
|
549
|
-
const dynamicStyles = {};
|
|
550
|
-
const hasBorderColor = "borderColor" in style && !isStyleMapping(style.borderColor);
|
|
551
|
-
const borderShorthands = /* @__PURE__ */ new Set([
|
|
552
|
-
"border",
|
|
553
|
-
"borderTop",
|
|
554
|
-
"borderRight",
|
|
555
|
-
"borderBottom",
|
|
556
|
-
"borderLeft"
|
|
557
|
-
]);
|
|
558
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
559
|
-
if (isStyleMapping(value)) continue;
|
|
560
|
-
const strValue = String(value);
|
|
561
|
-
if (hasTemplateExpression(strValue)) {
|
|
562
|
-
const cssProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
563
|
-
dynamicStyles[cssProp] = strValue;
|
|
564
|
-
continue;
|
|
565
|
-
}
|
|
566
|
-
if (hasBorderColor && borderShorthands.has(prop)) {
|
|
567
|
-
const parts = strValue.split(/\s+/);
|
|
568
|
-
const width = parts.find((p) => /^\d/.test(p) || p === "0");
|
|
569
|
-
const borderStyle = parts.find((p) => /^(solid|dashed|dotted|double|groove|ridge|inset|outset|none|hidden)$/.test(p));
|
|
570
|
-
const cssProp = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
571
|
-
if (width) classes.push(`[${cssProp}-width:${width}]`);
|
|
572
|
-
if (borderStyle) classes.push(`[${cssProp}-style:${borderStyle}]`);
|
|
573
|
-
continue;
|
|
574
|
-
}
|
|
575
|
-
const twClass = propertyToTailwind(prop, value);
|
|
576
|
-
if (twClass) {
|
|
577
|
-
classes.push(twClass);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
return { classes, dynamicStyles };
|
|
581
|
-
}
|
|
582
|
-
function responsiveStylesToTailwind(style, breakpoints) {
|
|
583
|
-
if (!style) return { classes: [], dynamicStyles: {} };
|
|
584
|
-
const allClasses = [];
|
|
585
|
-
const allDynamicStyles = {};
|
|
586
|
-
if (isResponsiveStyle(style)) {
|
|
587
|
-
const responsive = style;
|
|
588
|
-
if (responsive.base) {
|
|
589
|
-
const { classes, dynamicStyles } = stylesToTailwind(responsive.base);
|
|
590
|
-
allClasses.push(...classes);
|
|
591
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
592
|
-
}
|
|
593
|
-
if (responsive.tablet) {
|
|
594
|
-
const bpValue = breakpoints.tablet?.breakpoint ?? 1024;
|
|
595
|
-
const prefix = `max-[${bpValue}px]:`;
|
|
596
|
-
const { classes, dynamicStyles } = stylesToTailwind(responsive.tablet);
|
|
597
|
-
allClasses.push(...classes.map((cls) => `${prefix}${cls}`));
|
|
598
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
599
|
-
}
|
|
600
|
-
if (responsive.mobile) {
|
|
601
|
-
const bpValue = breakpoints.mobile?.breakpoint ?? 540;
|
|
602
|
-
const prefix = `max-[${bpValue}px]:`;
|
|
603
|
-
const { classes, dynamicStyles } = stylesToTailwind(responsive.mobile);
|
|
604
|
-
allClasses.push(...classes.map((cls) => `${prefix}${cls}`));
|
|
605
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
606
|
-
}
|
|
607
|
-
for (const [bpName, bpStyle] of Object.entries(responsive)) {
|
|
608
|
-
if (bpName === "base" || bpName === "tablet" || bpName === "mobile" || !bpStyle) continue;
|
|
609
|
-
const bpValue = breakpoints[bpName]?.breakpoint;
|
|
610
|
-
if (!bpValue) continue;
|
|
611
|
-
const prefix = `max-[${bpValue}px]:`;
|
|
612
|
-
const { classes, dynamicStyles } = stylesToTailwind(bpStyle);
|
|
613
|
-
allClasses.push(...classes.map((cls) => `${prefix}${cls}`));
|
|
614
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
615
|
-
}
|
|
616
|
-
} else {
|
|
617
|
-
const { classes, dynamicStyles } = stylesToTailwind(style);
|
|
618
|
-
allClasses.push(...classes);
|
|
619
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
620
|
-
}
|
|
621
|
-
return { classes: allClasses, dynamicStyles: allDynamicStyles };
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
// lib/server/astro/nodeToAstro.ts
|
|
625
|
-
init_constants();
|
|
626
|
-
|
|
627
|
-
// lib/server/astro/templateTransformer.ts
|
|
628
|
-
var CMS_TEMPLATE_PATTERN = /\{\{cms\.([^}]+)\}\}/g;
|
|
629
|
-
var ITEM_TEMPLATE_PATTERN = /\{\{([^}]+)\}\}/g;
|
|
630
|
-
function isTemplateExpression(text) {
|
|
631
|
-
return /\{\{.+?\}\}/.test(text);
|
|
632
|
-
}
|
|
633
|
-
function transformCMSTemplate(text, binding = "entry", richTextFields, wrapFn) {
|
|
634
|
-
const w = (expr) => wrapFn ? `${wrapFn}(${expr})` : expr;
|
|
635
|
-
const fullMatch = text.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
636
|
-
if (fullMatch) {
|
|
637
|
-
const fieldPath = fullMatch[1].trim();
|
|
638
|
-
const topLevelField = fieldPath.split(".")[0];
|
|
639
|
-
if (richTextFields?.has(topLevelField)) {
|
|
640
|
-
return `<Fragment set:html={${w(`${binding}.data.${fieldPath}`)}} />`;
|
|
641
|
-
}
|
|
642
|
-
return `{${w(`${binding}.data.${fieldPath}`)}}`;
|
|
643
|
-
}
|
|
644
|
-
if (CMS_TEMPLATE_PATTERN.test(text)) {
|
|
645
|
-
CMS_TEMPLATE_PATTERN.lastIndex = 0;
|
|
646
|
-
const replaced = text.replace(CMS_TEMPLATE_PATTERN, (_, fieldPath) => {
|
|
647
|
-
return `\${${w(`${binding}.data.${fieldPath.trim()}`)}}`;
|
|
648
|
-
});
|
|
649
|
-
return `{\`${replaced}\`}`;
|
|
650
|
-
}
|
|
651
|
-
return text;
|
|
652
|
-
}
|
|
653
|
-
function rewriteItemVar(expr, itemVar) {
|
|
654
|
-
if (itemVar === "item") return expr;
|
|
655
|
-
return expr.replace(/\bitem\./g, `${itemVar}.`);
|
|
656
|
-
}
|
|
657
|
-
function replaceItemMetaVars(expr, indexVar, sourceVar, itemVar) {
|
|
658
|
-
const lastExpr = sourceVar ? `(${indexVar} === ${sourceVar}.length - 1)` : `false /* itemLast not supported */`;
|
|
659
|
-
let result = expr.replace(/\bitemIndex\b/g, indexVar).replace(/\bitemFirst\b/g, `(${indexVar} === 0)`).replace(/\bitemLast\b/g, lastExpr);
|
|
660
|
-
if (itemVar) result = rewriteItemVar(result, itemVar);
|
|
661
|
-
return result;
|
|
662
|
-
}
|
|
663
|
-
function transformItemTemplate(text, itemVar = "item", indexVar, sourceVar) {
|
|
664
|
-
const fullMatch = text.match(/^\{\{(.+)\}\}$/);
|
|
665
|
-
if (fullMatch) {
|
|
666
|
-
let expr = fullMatch[1].trim();
|
|
667
|
-
expr = rewriteItemVar(expr, itemVar);
|
|
668
|
-
if (indexVar) expr = replaceItemMetaVars(expr, indexVar, sourceVar);
|
|
669
|
-
if (expr.startsWith(`${itemVar}.`)) {
|
|
670
|
-
return `{${expr}}`;
|
|
671
|
-
}
|
|
672
|
-
return `{${expr}}`;
|
|
673
|
-
}
|
|
674
|
-
if (ITEM_TEMPLATE_PATTERN.test(text)) {
|
|
675
|
-
ITEM_TEMPLATE_PATTERN.lastIndex = 0;
|
|
676
|
-
const replaced = text.replace(ITEM_TEMPLATE_PATTERN, (_, expr) => {
|
|
677
|
-
let trimmed = expr.trim();
|
|
678
|
-
trimmed = rewriteItemVar(trimmed, itemVar);
|
|
679
|
-
if (indexVar) trimmed = replaceItemMetaVars(trimmed, indexVar, sourceVar);
|
|
680
|
-
return `\${${trimmed}}`;
|
|
681
|
-
});
|
|
682
|
-
return `{\`${replaced}\`}`;
|
|
683
|
-
}
|
|
684
|
-
return text;
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
// lib/server/astro/nodeToAstro.ts
|
|
688
|
-
function ind(ctx) {
|
|
689
|
-
return " ".repeat(ctx.indent);
|
|
690
|
-
}
|
|
691
|
-
function localizeHref(href, ctx) {
|
|
692
|
-
if (!href.startsWith("/") || href.startsWith("//")) return href;
|
|
693
|
-
const { locale, i18nDefaultLocale, slugMappings } = ctx;
|
|
694
|
-
if (!locale || !i18nDefaultLocale) return href;
|
|
695
|
-
if (slugMappings && slugMappings.length > 0) {
|
|
696
|
-
const slugIndex = buildSlugIndex(slugMappings);
|
|
697
|
-
return translatePath(href, locale, i18nDefaultLocale, i18nDefaultLocale, slugIndex);
|
|
698
|
-
} else if (locale !== i18nDefaultLocale) {
|
|
699
|
-
return buildLocalizedPath(href, locale);
|
|
700
|
-
}
|
|
701
|
-
return href;
|
|
702
|
-
}
|
|
703
|
-
function isStyleMapping2(value) {
|
|
704
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
705
|
-
}
|
|
706
|
-
function isLinkMapping(value) {
|
|
707
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
708
|
-
}
|
|
709
|
-
function emitAttrValue(key, value, ctx) {
|
|
710
|
-
if (ctx.cmsMode && /\{\{cms\./.test(value)) {
|
|
711
|
-
const b = ctx.cmsEntryBinding || "entry";
|
|
712
|
-
const w = (expr) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
713
|
-
const fullMatch = value.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
714
|
-
if (fullMatch) {
|
|
715
|
-
return `${key}={${w(`${b}.data.${fullMatch[1].trim()}`)}}`;
|
|
716
|
-
}
|
|
717
|
-
const replaced = value.replace(
|
|
718
|
-
/\{\{cms\.([^}]+)\}\}/g,
|
|
719
|
-
(_, fp) => `\${${w(`${b}.data.${fp.trim()}`)}}`
|
|
720
|
-
);
|
|
721
|
-
return `${key}={\`${replaced}\`}`;
|
|
722
|
-
}
|
|
723
|
-
if (ctx.listItemBinding && /\{\{/.test(value)) {
|
|
724
|
-
const fullMatch = value.match(/^\{\{(.+)\}\}$/);
|
|
725
|
-
if (fullMatch) {
|
|
726
|
-
let expr = fullMatch[1].trim();
|
|
727
|
-
expr = rewriteItemVar(expr, ctx.listItemBinding);
|
|
728
|
-
if (ctx.listIndexVar) expr = replaceItemMetaVars(expr, ctx.listIndexVar, ctx.listSourceVar);
|
|
729
|
-
return `${key}={${expr}}`;
|
|
730
|
-
}
|
|
731
|
-
const replaced = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
732
|
-
let trimmed = expr.trim();
|
|
733
|
-
trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
734
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
735
|
-
return `\${${trimmed}}`;
|
|
736
|
-
});
|
|
737
|
-
return `${key}={\`${replaced}\`}`;
|
|
738
|
-
}
|
|
739
|
-
return `${key}="${escapeJSX(value)}"`;
|
|
740
|
-
}
|
|
741
|
-
function isHtmlMapping(value) {
|
|
742
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
743
|
-
}
|
|
744
|
-
function isResponsiveStyle2(style) {
|
|
745
|
-
return "base" in style || "tablet" in style || "mobile" in style;
|
|
746
|
-
}
|
|
747
|
-
function escapeJSX(s) {
|
|
748
|
-
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
749
|
-
}
|
|
750
|
-
function escapeTemplateLiteral(s) {
|
|
751
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
752
|
-
}
|
|
753
|
-
function collectStyleMappings(style) {
|
|
754
|
-
if (!style) return [];
|
|
755
|
-
const result = [];
|
|
756
|
-
if (isResponsiveStyle2(style)) {
|
|
757
|
-
const responsive = style;
|
|
758
|
-
for (const [bp, bpStyle] of Object.entries(responsive)) {
|
|
759
|
-
if (!bpStyle) continue;
|
|
760
|
-
for (const [prop, value] of Object.entries(bpStyle)) {
|
|
761
|
-
if (isStyleMapping2(value)) {
|
|
762
|
-
result.push({ property: prop, mapping: value, breakpoint: bp });
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
} else {
|
|
767
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
768
|
-
if (isStyleMapping2(value)) {
|
|
769
|
-
result.push({ property: prop, mapping: value });
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
return result;
|
|
774
|
-
}
|
|
775
|
-
function mappingToClassListEntries(mapping, property, breakpointPrefix, ctx) {
|
|
776
|
-
const entries = [];
|
|
777
|
-
const values = Object.entries(mapping.values);
|
|
778
|
-
if (values.length === 0) return entries;
|
|
779
|
-
const propRef = ctx.isComponentDef ? mapping.prop : mapping.prop;
|
|
780
|
-
if (values.length === 2) {
|
|
781
|
-
const [[val1, css1], [val2, css2]] = values;
|
|
782
|
-
const cls1 = getClassForValue(property, css1, breakpointPrefix);
|
|
783
|
-
const cls2 = getClassForValue(property, css2, breakpointPrefix);
|
|
784
|
-
if (cls1 && cls2) {
|
|
785
|
-
entries.push(`String(${propRef}) === ${JSON.stringify(String(coerceValue(val1)))} ? '${cls1}' : '${cls2}'`);
|
|
786
|
-
}
|
|
787
|
-
} else {
|
|
788
|
-
for (const [val, cssValue] of values) {
|
|
789
|
-
const cls = getClassForValue(property, cssValue, breakpointPrefix);
|
|
790
|
-
if (cls) {
|
|
791
|
-
entries.push(`String(${propRef}) === ${JSON.stringify(String(coerceValue(val)))} && '${cls}'`);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
return entries;
|
|
796
|
-
}
|
|
797
|
-
function coerceValue(val) {
|
|
798
|
-
if (val === "true") return true;
|
|
799
|
-
if (val === "false") return false;
|
|
800
|
-
return val;
|
|
801
|
-
}
|
|
802
|
-
function getClassForValue(property, value, breakpointPrefix) {
|
|
803
|
-
const twClass = propertyToTailwind(property, value);
|
|
804
|
-
if (!twClass) return null;
|
|
805
|
-
return breakpointPrefix ? `${breakpointPrefix}${twClass}` : twClass;
|
|
806
|
-
}
|
|
807
|
-
function buildClassAndStyleExpression(style, interactiveStyles, elementClass, ctx) {
|
|
808
|
-
const result = style ? responsiveStylesToTailwind(style, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
809
|
-
const staticClasses = result.classes;
|
|
810
|
-
const dynamicStyles = result.dynamicStyles;
|
|
811
|
-
if (elementClass) {
|
|
812
|
-
staticClasses.unshift(elementClass);
|
|
813
|
-
}
|
|
814
|
-
const conditionals = [];
|
|
815
|
-
const mappings = collectStyleMappings(style);
|
|
816
|
-
for (const { property, mapping, breakpoint } of mappings) {
|
|
817
|
-
const bpValue = breakpoint === "tablet" ? ctx.breakpoints.tablet?.breakpoint ?? 1024 : breakpoint === "mobile" ? ctx.breakpoints.mobile?.breakpoint ?? 540 : 0;
|
|
818
|
-
const prefix = bpValue ? `max-[${bpValue}px]:` : "";
|
|
819
|
-
const entries = mappingToClassListEntries(mapping, property, prefix, ctx);
|
|
820
|
-
conditionals.push(...entries);
|
|
821
|
-
}
|
|
822
|
-
let styleAttr = "";
|
|
823
|
-
if (Object.keys(dynamicStyles).length > 0 && ctx.isComponentDef) {
|
|
824
|
-
const styleParts = [];
|
|
825
|
-
for (const [cssProp, value] of Object.entries(dynamicStyles)) {
|
|
826
|
-
const resolved = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
827
|
-
let trimmed = expr.trim();
|
|
828
|
-
if (ctx.listItemBinding) trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
829
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
830
|
-
return `\${${trimmed}}`;
|
|
831
|
-
});
|
|
832
|
-
styleParts.push(`${cssProp}: \${${resolved.includes("${") ? resolved.replace(/\$\{(.+?)\}/g, "$1") : `'${resolved}'`}}`);
|
|
833
|
-
}
|
|
834
|
-
const entries = [];
|
|
835
|
-
for (const [cssProp, value] of Object.entries(dynamicStyles)) {
|
|
836
|
-
const resolved = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
837
|
-
let trimmed = expr.trim();
|
|
838
|
-
if (ctx.listItemBinding) trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
839
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
840
|
-
return `\${${trimmed}}`;
|
|
841
|
-
});
|
|
842
|
-
entries.push(`${cssProp}: ${resolved}`);
|
|
843
|
-
}
|
|
844
|
-
styleAttr = ` style={\`${entries.join("; ")}\`}`;
|
|
845
|
-
}
|
|
846
|
-
if (interactiveStyles && interactiveStyles.length > 0 && ctx.isComponentDef && hasInteractiveStyleMappings(interactiveStyles)) {
|
|
847
|
-
const { mappings: mappings2 } = extractInteractiveStyleMappings(interactiveStyles);
|
|
848
|
-
if (mappings2.length > 0) {
|
|
849
|
-
const varParts = [];
|
|
850
|
-
for (const extracted of mappings2) {
|
|
851
|
-
const { mapping, variableIndex } = extracted;
|
|
852
|
-
const varName = `--is-${variableIndex}`;
|
|
853
|
-
const entries = Object.entries(mapping.values);
|
|
854
|
-
if (entries.length === 2) {
|
|
855
|
-
const [[val1, css1], [val2, css2]] = entries;
|
|
856
|
-
varParts.push(`'${varName}': ${mapping.prop} === ${JSON.stringify(coerceValue(val1))} ? '${css1}' : '${css2}'`);
|
|
857
|
-
} else {
|
|
858
|
-
const lookupEntries = entries.filter(([, v]) => v !== "").map(([k, v]) => `${JSON.stringify(coerceValue(k))}: '${v}'`).join(", ");
|
|
859
|
-
varParts.push(`'${varName}': ({${lookupEntries}})[${mapping.prop}] || ''`);
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
if (varParts.length > 0) {
|
|
863
|
-
const existingStyleParts = styleAttr ? styleAttr.replace(/^ style=\{`/, "").replace(/`\}$/, "") : "";
|
|
864
|
-
const varStyleExpr = varParts.join(", ");
|
|
865
|
-
if (existingStyleParts) {
|
|
866
|
-
styleAttr = ` style={\`${existingStyleParts}; \${ Object.entries({${varStyleExpr}}).map(([k,v]) => \`\${k}:\${v}\`).join(';') }\`}`;
|
|
867
|
-
} else {
|
|
868
|
-
styleAttr = ` style={Object.entries({${varStyleExpr}}).map(([k,v]) => \`\${k}:\${v}\`).join(';')}`;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
let classExpr;
|
|
874
|
-
if (conditionals.length === 0) {
|
|
875
|
-
if (staticClasses.length === 0) {
|
|
876
|
-
classExpr = "";
|
|
877
|
-
} else {
|
|
878
|
-
classExpr = ` class="${staticClasses.join(" ")}"`;
|
|
879
|
-
}
|
|
880
|
-
} else {
|
|
881
|
-
const parts = [];
|
|
882
|
-
if (staticClasses.length > 0) {
|
|
883
|
-
parts.push(`'${staticClasses.join(" ")}'`);
|
|
884
|
-
}
|
|
885
|
-
parts.push(...conditionals);
|
|
886
|
-
classExpr = ` class:list={[${parts.join(", ")}]}`;
|
|
887
|
-
}
|
|
888
|
-
return { classExpr, styleAttr };
|
|
889
|
-
}
|
|
890
|
-
function resolveTemplate(text, ctx) {
|
|
891
|
-
if (!ctx.isComponentDef) {
|
|
892
|
-
return text;
|
|
893
|
-
}
|
|
894
|
-
const fullMatch = text.match(/^\{\{(.+)\}\}$/);
|
|
895
|
-
if (fullMatch) {
|
|
896
|
-
let propName = fullMatch[1].trim();
|
|
897
|
-
if (ctx.listItemBinding) propName = rewriteItemVar(propName, ctx.listItemBinding);
|
|
898
|
-
if (ctx.listIndexVar) propName = replaceItemMetaVars(propName, ctx.listIndexVar, ctx.listSourceVar);
|
|
899
|
-
if (ctx.componentProps[propName]?.type === "rich-text") {
|
|
900
|
-
return `<Fragment set:html={${propName}} />`;
|
|
901
|
-
}
|
|
902
|
-
return `{${propName}}`;
|
|
903
|
-
}
|
|
904
|
-
return text.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
905
|
-
let trimmed = expr.trim();
|
|
906
|
-
if (ctx.listItemBinding) trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
907
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
908
|
-
return `{${trimmed}}`;
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
function hasTemplates(text) {
|
|
912
|
-
return /\{\{.+?\}\}/.test(text);
|
|
913
|
-
}
|
|
914
|
-
function buildElementClass(ctx, label) {
|
|
915
|
-
return generateElementClassName({
|
|
916
|
-
fileType: ctx.fileType,
|
|
917
|
-
fileName: ctx.fileName,
|
|
918
|
-
label,
|
|
919
|
-
path: ctx.elementPath
|
|
920
|
-
});
|
|
921
|
-
}
|
|
922
|
-
function buildAttributesString(attributes, ctx) {
|
|
923
|
-
if (!attributes) return "";
|
|
924
|
-
const parts = [];
|
|
925
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
926
|
-
if (typeof value === "boolean") {
|
|
927
|
-
if (value) parts.push(key);
|
|
928
|
-
} else {
|
|
929
|
-
const strVal = String(value);
|
|
930
|
-
if (hasTemplates(strVal) && ctx.isComponentDef) {
|
|
931
|
-
const fullMatch = strVal.match(/^\{\{(.+)\}\}$/);
|
|
932
|
-
if (fullMatch) {
|
|
933
|
-
let expr = fullMatch[1].trim();
|
|
934
|
-
if (ctx.listItemBinding) expr = rewriteItemVar(expr, ctx.listItemBinding);
|
|
935
|
-
if (ctx.listIndexVar) expr = replaceItemMetaVars(expr, ctx.listIndexVar, ctx.listSourceVar);
|
|
936
|
-
const propDef = ctx.componentProps[expr];
|
|
937
|
-
if (propDef && propDef.type === "link") {
|
|
938
|
-
parts.push(`${key}={${expr}?.href ?? "#"}`);
|
|
939
|
-
} else {
|
|
940
|
-
parts.push(`${key}={${expr} || undefined}`);
|
|
941
|
-
}
|
|
942
|
-
} else {
|
|
943
|
-
const resolved = strVal.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
944
|
-
let trimmed = expr.trim();
|
|
945
|
-
if (ctx.listItemBinding) trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
946
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
947
|
-
const pd = ctx.componentProps[trimmed];
|
|
948
|
-
return pd?.type === "link" ? `\${${trimmed}?.href ?? "#"}` : `\${${trimmed}}`;
|
|
949
|
-
});
|
|
950
|
-
parts.push(`${key}={\`${resolved}\`}`);
|
|
951
|
-
}
|
|
952
|
-
} else if (ctx.listItemBinding && hasTemplates(strVal)) {
|
|
953
|
-
const fullMatch = strVal.match(/^\{\{(.+)\}\}$/);
|
|
954
|
-
if (fullMatch) {
|
|
955
|
-
let expr = fullMatch[1].trim();
|
|
956
|
-
expr = rewriteItemVar(expr, ctx.listItemBinding);
|
|
957
|
-
if (ctx.listIndexVar) expr = replaceItemMetaVars(expr, ctx.listIndexVar, ctx.listSourceVar);
|
|
958
|
-
parts.push(`${key}={${expr} || undefined}`);
|
|
959
|
-
} else {
|
|
960
|
-
const resolved = strVal.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
961
|
-
let trimmed = expr.trim();
|
|
962
|
-
trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
963
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
964
|
-
return `\${${trimmed}}`;
|
|
965
|
-
});
|
|
966
|
-
parts.push(`${key}={\`${resolved}\`}`);
|
|
967
|
-
}
|
|
968
|
-
} else if (ctx.cmsMode && /\{\{cms\./.test(strVal)) {
|
|
969
|
-
const b = ctx.cmsEntryBinding || "entry";
|
|
970
|
-
const w = (expr) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
971
|
-
const fullMatch = strVal.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
972
|
-
if (fullMatch) {
|
|
973
|
-
parts.push(`${key}={${w(`${b}.data.${fullMatch[1].trim()}`)}}`);
|
|
974
|
-
} else {
|
|
975
|
-
const replaced = strVal.replace(/\{\{cms\.([^}]+)\}\}/g, (_, fieldPath) => {
|
|
976
|
-
return `\${${w(`${b}.data.${fieldPath.trim()}`)}}`;
|
|
977
|
-
});
|
|
978
|
-
parts.push(`${key}={\`${replaced}\`}`);
|
|
979
|
-
}
|
|
980
|
-
} else {
|
|
981
|
-
parts.push(`${key}="${escapeJSX(strVal)}"`);
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
return parts.length > 0 ? " " + parts.join(" ") : "";
|
|
986
|
-
}
|
|
987
|
-
function formatPropValue(value) {
|
|
988
|
-
if (typeof value === "string") return `"${escapeJSX(value)}"`;
|
|
989
|
-
if (typeof value === "number") return `{${value}}`;
|
|
990
|
-
if (typeof value === "boolean") return `{${value}}`;
|
|
991
|
-
if (value === null || value === void 0) return `{undefined}`;
|
|
992
|
-
return `{${JSON.stringify(value)}}`;
|
|
993
|
-
}
|
|
994
|
-
function resolveI18n(value, ctx) {
|
|
995
|
-
if (ctx.locale && isI18nValue(value)) {
|
|
996
|
-
return resolveI18nValue(value, ctx.locale, DEFAULT_I18N_CONFIG);
|
|
997
|
-
}
|
|
998
|
-
return value;
|
|
999
|
-
}
|
|
1000
|
-
function nodeToAstro(node, ctx) {
|
|
1001
|
-
if (node === null || node === void 0) return "";
|
|
1002
|
-
if (typeof node === "object" && !Array.isArray(node) && isI18nValue(node)) {
|
|
1003
|
-
const resolved = resolveI18n(node, ctx);
|
|
1004
|
-
if (typeof resolved === "string") {
|
|
1005
|
-
return `${ind(ctx)}${escapeJSX(resolved)}
|
|
1006
|
-
`;
|
|
1007
|
-
}
|
|
1008
|
-
if (ctx.isComponentDef && isI18nValue(resolved)) {
|
|
1009
|
-
ctx.needsI18nResolver = true;
|
|
1010
|
-
return `${ind(ctx)}{r(${JSON.stringify(resolved)})}
|
|
1011
|
-
`;
|
|
1012
|
-
}
|
|
1013
|
-
return `${ind(ctx)}${String(resolved ?? "")}
|
|
1014
|
-
`;
|
|
1015
|
-
}
|
|
1016
|
-
if (typeof node === "string") {
|
|
1017
|
-
if (ctx.cmsMode && isTemplateExpression(node) && /\{\{cms\./.test(node)) {
|
|
1018
|
-
const transformed = transformCMSTemplate(node, ctx.cmsEntryBinding || "entry", ctx.cmsRichTextFields, ctx.cmsWrapFn);
|
|
1019
|
-
return `${ind(ctx)}${transformed}
|
|
1020
|
-
`;
|
|
1021
|
-
}
|
|
1022
|
-
if (ctx.listItemBinding && isTemplateExpression(node)) {
|
|
1023
|
-
const transformed = transformItemTemplate(node, ctx.listItemBinding, ctx.listIndexVar, ctx.listSourceVar);
|
|
1024
|
-
return `${ind(ctx)}${transformed}
|
|
1025
|
-
`;
|
|
1026
|
-
}
|
|
1027
|
-
if (hasTemplates(node) && ctx.isComponentDef) {
|
|
1028
|
-
return `${ind(ctx)}${resolveTemplate(node, ctx)}
|
|
1029
|
-
`;
|
|
1030
|
-
}
|
|
1031
|
-
if (node.startsWith(RAW_HTML_PREFIX)) {
|
|
1032
|
-
const rawHtml = node.slice(RAW_HTML_PREFIX.length);
|
|
1033
|
-
return `${ind(ctx)}<Fragment set:html={\`${escapeTemplateLiteral(rawHtml)}\`} />
|
|
1034
|
-
`;
|
|
1035
|
-
}
|
|
1036
|
-
return `${ind(ctx)}${escapeJSX(node)}
|
|
1037
|
-
`;
|
|
1038
|
-
}
|
|
1039
|
-
if (typeof node === "number") {
|
|
1040
|
-
return `${ind(ctx)}${node}
|
|
1041
|
-
`;
|
|
1042
|
-
}
|
|
1043
|
-
if (Array.isArray(node)) {
|
|
1044
|
-
let result = "";
|
|
1045
|
-
for (let i = 0; i < node.length; i++) {
|
|
1046
|
-
const child = node[i];
|
|
1047
|
-
const savedPath = [...ctx.elementPath];
|
|
1048
|
-
ctx.elementPath = [...ctx.elementPath.slice(0, -1), i];
|
|
1049
|
-
result += nodeToAstro(child, ctx);
|
|
1050
|
-
ctx.elementPath = savedPath;
|
|
1051
|
-
}
|
|
1052
|
-
return result;
|
|
1053
|
-
}
|
|
1054
|
-
switch (node.type) {
|
|
1055
|
-
case NODE_TYPE.NODE:
|
|
1056
|
-
return emitHtmlNode(node, ctx);
|
|
1057
|
-
case NODE_TYPE.COMPONENT:
|
|
1058
|
-
return emitComponentInstance(node, ctx);
|
|
1059
|
-
case NODE_TYPE.SLOT:
|
|
1060
|
-
return emitSlotMarker(node, ctx);
|
|
1061
|
-
case NODE_TYPE.EMBED:
|
|
1062
|
-
return emitEmbedNode(node, ctx);
|
|
1063
|
-
case NODE_TYPE.LINK:
|
|
1064
|
-
return emitLinkNode(node, ctx);
|
|
1065
|
-
case NODE_TYPE.LOCALE_LIST:
|
|
1066
|
-
return emitLocaleListNode(node, ctx);
|
|
1067
|
-
case NODE_TYPE.LIST:
|
|
1068
|
-
case "cms-list":
|
|
1069
|
-
return emitListNode(node, ctx);
|
|
1070
|
-
case "image":
|
|
1071
|
-
return emitImageTypeNode(node, ctx);
|
|
1072
|
-
default:
|
|
1073
|
-
return emitFallback(ctx);
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
var IMG_TAILWIND_PREFIXES = ["object-", "rounded", "border", "shadow", "[filter", "[transform", "mix-blend"];
|
|
1077
|
-
var IMG_OPACITY_PATTERN = /^opacity-/;
|
|
1078
|
-
var DEFAULT_SIZES2 = "100vw";
|
|
1079
|
-
function splitImageClasses(allClasses) {
|
|
1080
|
-
const imgClasses = [];
|
|
1081
|
-
const pictureClasses = [];
|
|
1082
|
-
for (const cls of allClasses) {
|
|
1083
|
-
const baseCls = cls.includes(":") ? cls.split(":").pop() : cls;
|
|
1084
|
-
if (IMG_TAILWIND_PREFIXES.some((p) => baseCls.startsWith(p)) || IMG_OPACITY_PATTERN.test(baseCls)) {
|
|
1085
|
-
imgClasses.push(cls);
|
|
1086
|
-
} else {
|
|
1087
|
-
pictureClasses.push(cls);
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
return { pictureClasses, imgClasses };
|
|
1091
|
-
}
|
|
1092
|
-
function emitImageNode(node, ctx) {
|
|
1093
|
-
const style = node.style;
|
|
1094
|
-
let elementClass = null;
|
|
1095
|
-
if (node.interactiveStyles && node.interactiveStyles.length > 0 || node.generateElementClass) {
|
|
1096
|
-
elementClass = buildElementClass(ctx, node.label);
|
|
1097
|
-
}
|
|
1098
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1099
|
-
style,
|
|
1100
|
-
node.interactiveStyles,
|
|
1101
|
-
elementClass,
|
|
1102
|
-
ctx
|
|
1103
|
-
);
|
|
1104
|
-
const attrs = node.attributes || {};
|
|
1105
|
-
const src = attrs.src;
|
|
1106
|
-
const alt = attrs.alt;
|
|
1107
|
-
const loading = attrs.loading;
|
|
1108
|
-
const fetchpriority = attrs.fetchpriority;
|
|
1109
|
-
let width = attrs.width;
|
|
1110
|
-
let height = attrs.height;
|
|
1111
|
-
const sizes = attrs.sizes;
|
|
1112
|
-
const metadata = src ? ctx.imageMetadataMap?.get(String(src)) : void 0;
|
|
1113
|
-
if (metadata) {
|
|
1114
|
-
if (width === void 0 && metadata.width) width = metadata.width;
|
|
1115
|
-
if (height === void 0 && metadata.height) height = metadata.height;
|
|
1116
|
-
}
|
|
1117
|
-
const sizesValue = sizes || DEFAULT_SIZES2;
|
|
1118
|
-
const imageSpecificKeys = /* @__PURE__ */ new Set(["src", "alt", "loading", "width", "height", "sizes", "srcset", "fetchpriority"]);
|
|
1119
|
-
const otherAttrs = {};
|
|
1120
|
-
if (node.attributes) {
|
|
1121
|
-
for (const [k, v] of Object.entries(node.attributes)) {
|
|
1122
|
-
if (!imageSpecificKeys.has(k)) otherAttrs[k] = v;
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
const otherAttrsStr = buildAttributesString(otherAttrs, ctx);
|
|
1126
|
-
let imgAttrs = "";
|
|
1127
|
-
if (src) imgAttrs += ` ${emitAttrValue("src", String(src), ctx)}`;
|
|
1128
|
-
if (alt !== void 0) imgAttrs += ` ${emitAttrValue("alt", String(alt), ctx)}`;
|
|
1129
|
-
if (fetchpriority) imgAttrs += ` fetchpriority="${escapeJSX(String(fetchpriority))}"`;
|
|
1130
|
-
if (loading) imgAttrs += ` loading="${escapeJSX(String(loading))}"`;
|
|
1131
|
-
if (width !== void 0) imgAttrs += ` width="${escapeJSX(String(width))}"`;
|
|
1132
|
-
if (height !== void 0) imgAttrs += ` height="${escapeJSX(String(height))}"`;
|
|
1133
|
-
let blurStyle = "";
|
|
1134
|
-
if (metadata?.blurHash) {
|
|
1135
|
-
blurStyle = ` style="background-image: url(${escapeJSX(metadata.blurHash)}); background-size: cover;" onload="this.style.backgroundImage=''"`;
|
|
1136
|
-
}
|
|
1137
|
-
const ifExpr = emitIfOpen(node, ctx);
|
|
1138
|
-
const ifClose = emitIfClose(node, ctx);
|
|
1139
|
-
if (metadata?.avifSrcset) {
|
|
1140
|
-
const classMatch = classExpr.match(/class="([^"]*)"/);
|
|
1141
|
-
const classListMatch = classExpr.match(/class:list={\[(.+)\]}/);
|
|
1142
|
-
if (classListMatch) {
|
|
1143
|
-
return `${ifExpr}${ind(ctx)}<picture${classExpr}${styleAttr}>
|
|
1144
|
-
${ind(ctx)} <source type="image/avif" srcset="${escapeJSX(metadata.avifSrcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1145
|
-
${ind(ctx)} <source type="image/webp" srcset="${escapeJSX(metadata.srcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1146
|
-
${ind(ctx)} <img${imgAttrs}${blurStyle}${otherAttrsStr} />
|
|
1147
|
-
${ind(ctx)}</picture>
|
|
1148
|
-
${ifClose}`;
|
|
1149
|
-
}
|
|
1150
|
-
const allClasses = classMatch ? classMatch[1].split(/\s+/).filter(Boolean) : [];
|
|
1151
|
-
const { pictureClasses, imgClasses } = splitImageClasses(allClasses);
|
|
1152
|
-
const pictureClassAttr = pictureClasses.length > 0 ? ` class="${pictureClasses.join(" ")}"` : "";
|
|
1153
|
-
const imgClassAttr = imgClasses.length > 0 ? ` class="${imgClasses.join(" ")}"` : "";
|
|
1154
|
-
return `${ifExpr}${ind(ctx)}<picture${pictureClassAttr}${styleAttr}>
|
|
1155
|
-
${ind(ctx)} <source type="image/avif" srcset="${escapeJSX(metadata.avifSrcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1156
|
-
${ind(ctx)} <source type="image/webp" srcset="${escapeJSX(metadata.srcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1157
|
-
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${blurStyle}${otherAttrsStr} />
|
|
1158
|
-
${ind(ctx)}</picture>
|
|
1159
|
-
${ifClose}`;
|
|
1160
|
-
}
|
|
1161
|
-
if (metadata?.srcset) {
|
|
1162
|
-
imgAttrs += ` srcset="${escapeJSX(metadata.srcset)}"`;
|
|
1163
|
-
imgAttrs += ` sizes="${escapeJSX(sizesValue)}"`;
|
|
1164
|
-
}
|
|
1165
|
-
return `${ifExpr}${ind(ctx)}<img${classExpr}${styleAttr}${imgAttrs}${blurStyle}${otherAttrsStr} />
|
|
1166
|
-
${ifClose}`;
|
|
1167
|
-
}
|
|
1168
|
-
function emitHtmlNode(node, ctx) {
|
|
1169
|
-
let tag = node.tag;
|
|
1170
|
-
if (tag && /^[A-Z]/.test(tag)) {
|
|
1171
|
-
tag = tag.toLowerCase();
|
|
1172
|
-
}
|
|
1173
|
-
if (tag === "img" && ctx.imageMetadataMap) {
|
|
1174
|
-
return emitImageNode(node, ctx);
|
|
1175
|
-
}
|
|
1176
|
-
const label = node.label;
|
|
1177
|
-
const style = node.style;
|
|
1178
|
-
let isDynamic = false;
|
|
1179
|
-
let dynamicTagVar = "";
|
|
1180
|
-
if (hasTemplates(tag) && ctx.isComponentDef) {
|
|
1181
|
-
isDynamic = true;
|
|
1182
|
-
dynamicTagVar = `Tag_${ctx.elementPath.join("_")}`;
|
|
1183
|
-
const resolved = tag.replace(/\{\{(.+?)\}\}/g, (_, expr) => `\${${expr.trim()}}`);
|
|
1184
|
-
if (!ctx.dynamicTags) ctx.dynamicTags = /* @__PURE__ */ new Map();
|
|
1185
|
-
ctx.dynamicTags.set(dynamicTagVar, resolved);
|
|
1186
|
-
tag = dynamicTagVar;
|
|
1187
|
-
}
|
|
1188
|
-
const ifExpr = emitIfOpen(node, ctx);
|
|
1189
|
-
let elementClass = null;
|
|
1190
|
-
if (node.interactiveStyles && node.interactiveStyles.length > 0 || node.generateElementClass) {
|
|
1191
|
-
elementClass = buildElementClass(ctx, label);
|
|
1192
|
-
}
|
|
1193
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(style, node.interactiveStyles, elementClass, ctx);
|
|
1194
|
-
const attrs = buildAttributesString(node.attributes, ctx);
|
|
1195
|
-
const openClose = isDynamic ? dynamicTagVar : tag;
|
|
1196
|
-
if (!isDynamic && isVoidElement(tag)) {
|
|
1197
|
-
return `${ifExpr}${ind(ctx)}<${tag}${classExpr}${styleAttr}${attrs} />
|
|
1198
|
-
${emitIfClose(node, ctx)}`;
|
|
1199
|
-
}
|
|
1200
|
-
const children = emitChildren(node.children, ctx);
|
|
1201
|
-
if (!children.trim() && !isDynamic) {
|
|
1202
|
-
return `${ifExpr}${ind(ctx)}<${tag}${classExpr}${styleAttr}${attrs} />
|
|
1203
|
-
${emitIfClose(node, ctx)}`;
|
|
1204
|
-
}
|
|
1205
|
-
return `${ifExpr}${ind(ctx)}<${openClose}${classExpr}${styleAttr}${attrs}>
|
|
1206
|
-
` + children + `${ind(ctx)}</${openClose}>
|
|
1207
|
-
${emitIfClose(node, ctx)}`;
|
|
1208
|
-
}
|
|
1209
|
-
function emitComponentInstance(node, ctx) {
|
|
1210
|
-
const name = node.component;
|
|
1211
|
-
ctx.imports.add(name);
|
|
1212
|
-
const ifExpr = emitIfOpen(node, ctx);
|
|
1213
|
-
const propParts = [];
|
|
1214
|
-
if (node.props) {
|
|
1215
|
-
for (const [key, rawValue] of Object.entries(node.props)) {
|
|
1216
|
-
if (key === "children") continue;
|
|
1217
|
-
const value = resolveI18n(rawValue, ctx);
|
|
1218
|
-
if (typeof value === "string" && hasTemplates(value) && ctx.isComponentDef) {
|
|
1219
|
-
const fullMatch = value.match(/^\{\{(.+)\}\}$/);
|
|
1220
|
-
if (fullMatch) {
|
|
1221
|
-
let expr = fullMatch[1].trim();
|
|
1222
|
-
if (ctx.listItemBinding) expr = rewriteItemVar(expr, ctx.listItemBinding);
|
|
1223
|
-
if (ctx.listIndexVar) expr = replaceItemMetaVars(expr, ctx.listIndexVar, ctx.listSourceVar);
|
|
1224
|
-
propParts.push(`${key}={${expr}}`);
|
|
1225
|
-
} else {
|
|
1226
|
-
const resolved = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
1227
|
-
let trimmed = expr.trim();
|
|
1228
|
-
if (ctx.listItemBinding) trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
1229
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
1230
|
-
return `\${${trimmed}}`;
|
|
1231
|
-
});
|
|
1232
|
-
propParts.push(`${key}={\`${resolved}\`}`);
|
|
1233
|
-
}
|
|
1234
|
-
} else if (typeof value === "string" && ctx.cmsMode && /\{\{cms\./.test(value)) {
|
|
1235
|
-
const b = ctx.cmsEntryBinding || "entry";
|
|
1236
|
-
const w = (expr) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
1237
|
-
const fullMatch = value.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
1238
|
-
if (fullMatch) {
|
|
1239
|
-
propParts.push(`${key}={${w(`${b}.data.${fullMatch[1].trim()}`)}}`);
|
|
1240
|
-
} else {
|
|
1241
|
-
const replaced = value.replace(/\{\{cms\.([^}]+)\}\}/g, (_, fieldPath) => {
|
|
1242
|
-
return `\${${w(`${b}.data.${fieldPath.trim()}`)}}`;
|
|
1243
|
-
});
|
|
1244
|
-
propParts.push(`${key}={\`${replaced}\`}`);
|
|
1245
|
-
}
|
|
1246
|
-
} else if (ctx.isComponentDef && isI18nValue(value)) {
|
|
1247
|
-
ctx.needsI18nResolver = true;
|
|
1248
|
-
propParts.push(`${key}={r(${JSON.stringify(value)})}`);
|
|
1249
|
-
} else {
|
|
1250
|
-
propParts.push(`${key}=${formatPropValue(value)}`);
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
if (node.style) {
|
|
1255
|
-
const { classes: instanceClasses } = responsiveStylesToTailwind(node.style, ctx.breakpoints);
|
|
1256
|
-
if (instanceClasses.length > 0) {
|
|
1257
|
-
propParts.push(`class="${instanceClasses.join(" ")}"`);
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
const propsStr = propParts.length > 0 ? " " + propParts.join(" ") : "";
|
|
1261
|
-
const children = emitChildren(node.children, ctx);
|
|
1262
|
-
if (!children.trim()) {
|
|
1263
|
-
return `${ifExpr}${ind(ctx)}<${name}${propsStr} />
|
|
1264
|
-
${emitIfClose(node, ctx)}`;
|
|
1265
|
-
}
|
|
1266
|
-
return `${ifExpr}${ind(ctx)}<${name}${propsStr}>
|
|
1267
|
-
` + children + `${ind(ctx)}</${name}>
|
|
1268
|
-
${emitIfClose(node, ctx)}`;
|
|
1269
|
-
}
|
|
1270
|
-
function emitSlotMarker(node, ctx) {
|
|
1271
|
-
if (node.default) {
|
|
1272
|
-
const defaultContent = emitChildren(node.default, ctx);
|
|
1273
|
-
if (defaultContent.trim()) {
|
|
1274
|
-
return `${ind(ctx)}<slot>
|
|
1275
|
-
` + defaultContent + `${ind(ctx)}</slot>
|
|
1276
|
-
`;
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
return `${ind(ctx)}<slot />
|
|
1280
|
-
`;
|
|
1281
|
-
}
|
|
1282
|
-
function emitEmbedNode(node, ctx) {
|
|
1283
|
-
const ifExpr = emitIfOpen(node, ctx);
|
|
1284
|
-
const style = node.style;
|
|
1285
|
-
let elementClass = null;
|
|
1286
|
-
if (node.interactiveStyles && node.interactiveStyles.length > 0 || node.generateElementClass) {
|
|
1287
|
-
elementClass = buildElementClass(ctx, node.label);
|
|
1288
|
-
}
|
|
1289
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(style, node.interactiveStyles, elementClass, ctx);
|
|
1290
|
-
const attrs = buildAttributesString(node.attributes, ctx);
|
|
1291
|
-
if (isHtmlMapping(node.html)) {
|
|
1292
|
-
if (ctx.isComponentDef) {
|
|
1293
|
-
const propRef = node.html.prop;
|
|
1294
|
-
return `${ifExpr}${ind(ctx)}<div${classExpr.replace('"', '"oem ') || ' class="oem"'}${attrs}>
|
|
1295
|
-
${ind(ctx)} <Fragment set:html={${propRef}} />
|
|
1296
|
-
${ind(ctx)}</div>
|
|
1297
|
-
${emitIfClose(node, ctx)}`;
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
const htmlStr = typeof node.html === "string" ? node.html : "";
|
|
1301
|
-
const escapedHtml = escapeTemplateLiteral(htmlStr);
|
|
1302
|
-
let finalClassExpr = classExpr;
|
|
1303
|
-
if (!classExpr.includes("oem")) {
|
|
1304
|
-
if (classExpr) {
|
|
1305
|
-
finalClassExpr = classExpr.replace(/class="/, 'class="oem ').replace(/class:list={\['/, "class:list={['oem ");
|
|
1306
|
-
} else {
|
|
1307
|
-
finalClassExpr = ' class="oem"';
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
return `${ifExpr}${ind(ctx)}<div${finalClassExpr}${attrs}>
|
|
1311
|
-
${ind(ctx)} <Fragment set:html={\`${escapedHtml}\`} />
|
|
1312
|
-
${ind(ctx)}</div>
|
|
1313
|
-
${emitIfClose(node, ctx)}`;
|
|
1314
|
-
}
|
|
1315
|
-
function emitLinkNode(node, ctx) {
|
|
1316
|
-
const ifExpr = emitIfOpen(node, ctx);
|
|
1317
|
-
const style = node.style;
|
|
1318
|
-
let elementClass = null;
|
|
1319
|
-
if (node.interactiveStyles && node.interactiveStyles.length > 0 || node.generateElementClass) {
|
|
1320
|
-
elementClass = buildElementClass(ctx, node.label);
|
|
1321
|
-
}
|
|
1322
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(style, node.interactiveStyles, elementClass, ctx);
|
|
1323
|
-
let finalClassExpr = classExpr;
|
|
1324
|
-
if (!classExpr.includes("olink")) {
|
|
1325
|
-
if (classExpr) {
|
|
1326
|
-
finalClassExpr = classExpr.replace(/class="/, 'class="olink ').replace(/class:list={\['/, "class:list={['olink ");
|
|
1327
|
-
} else {
|
|
1328
|
-
finalClassExpr = ' class="olink"';
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
const resolvedHref = resolveI18n(node.href, ctx);
|
|
1332
|
-
const nodeHref = resolvedHref;
|
|
1333
|
-
let hrefAttr;
|
|
1334
|
-
if (isLinkMapping(nodeHref)) {
|
|
1335
|
-
if (ctx.isComponentDef) {
|
|
1336
|
-
const propRef = nodeHref.prop;
|
|
1337
|
-
hrefAttr = ` href={${propRef}?.href ?? "#"}`;
|
|
1338
|
-
} else {
|
|
1339
|
-
hrefAttr = ' href="#"';
|
|
1340
|
-
}
|
|
1341
|
-
} else {
|
|
1342
|
-
const href = typeof nodeHref === "string" ? nodeHref : "#";
|
|
1343
|
-
if (hasTemplates(href) && ctx.isComponentDef) {
|
|
1344
|
-
const fullMatch = href.match(/^\{\{(.+)\}\}$/);
|
|
1345
|
-
if (fullMatch) {
|
|
1346
|
-
let expr = fullMatch[1].trim();
|
|
1347
|
-
if (ctx.listItemBinding) expr = rewriteItemVar(expr, ctx.listItemBinding);
|
|
1348
|
-
if (ctx.listIndexVar) expr = replaceItemMetaVars(expr, ctx.listIndexVar, ctx.listSourceVar);
|
|
1349
|
-
const propDef = ctx.componentProps[expr];
|
|
1350
|
-
if (propDef && propDef.type === "link") {
|
|
1351
|
-
hrefAttr = ` href={${expr}?.href ?? "#"}`;
|
|
1352
|
-
} else {
|
|
1353
|
-
hrefAttr = ` href={${expr}}`;
|
|
1354
|
-
}
|
|
1355
|
-
} else {
|
|
1356
|
-
const resolved = href.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
1357
|
-
let trimmed = expr.trim();
|
|
1358
|
-
if (ctx.listItemBinding) trimmed = rewriteItemVar(trimmed, ctx.listItemBinding);
|
|
1359
|
-
if (ctx.listIndexVar) trimmed = replaceItemMetaVars(trimmed, ctx.listIndexVar, ctx.listSourceVar);
|
|
1360
|
-
const pd = ctx.componentProps[trimmed];
|
|
1361
|
-
return pd?.type === "link" ? `\${${trimmed}?.href ?? "#"}` : `\${${trimmed}}`;
|
|
1362
|
-
});
|
|
1363
|
-
hrefAttr = ` href={\`${resolved}\`}`;
|
|
1364
|
-
}
|
|
1365
|
-
} else if (ctx.cmsMode && /\{\{cms\./.test(href)) {
|
|
1366
|
-
const b = ctx.cmsEntryBinding || "entry";
|
|
1367
|
-
const w = (expr) => ctx.cmsWrapFn ? `${ctx.cmsWrapFn}(${expr})` : expr;
|
|
1368
|
-
const fullMatch = href.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
1369
|
-
if (fullMatch) {
|
|
1370
|
-
hrefAttr = ` href={${w(`${b}.data.${fullMatch[1].trim()}`)}}`;
|
|
1371
|
-
} else {
|
|
1372
|
-
const replaced = href.replace(/\{\{cms\.([^}]+)\}\}/g, (_, fieldPath) => {
|
|
1373
|
-
return `\${${w(`${b}.data.${fieldPath.trim()}`)}}`;
|
|
1374
|
-
});
|
|
1375
|
-
hrefAttr = ` href={\`${replaced}\`}`;
|
|
1376
|
-
}
|
|
1377
|
-
} else {
|
|
1378
|
-
const localizedHref = localizeHref(href, ctx);
|
|
1379
|
-
hrefAttr = ` href="${escapeJSX(localizedHref)}"`;
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
const attrs = buildAttributesString(node.attributes, ctx);
|
|
1383
|
-
const children = emitChildren(node.children, ctx);
|
|
1384
|
-
if (!children.trim()) {
|
|
1385
|
-
return `${ifExpr}${ind(ctx)}<a${hrefAttr}${finalClassExpr}${styleAttr}${attrs} />
|
|
1386
|
-
${emitIfClose(node, ctx)}`;
|
|
1387
|
-
}
|
|
1388
|
-
return `${ifExpr}${ind(ctx)}<a${hrefAttr}${finalClassExpr}${styleAttr}${attrs}>
|
|
1389
|
-
` + children + `${ind(ctx)}</a>
|
|
1390
|
-
${emitIfClose(node, ctx)}`;
|
|
1391
|
-
}
|
|
1392
|
-
function emitImageTypeNode(node, ctx) {
|
|
1393
|
-
const style = node.style;
|
|
1394
|
-
let elementClass = null;
|
|
1395
|
-
if (node.interactiveStyles && node.interactiveStyles.length > 0 || node.generateElementClass) {
|
|
1396
|
-
elementClass = buildElementClass(ctx, node.label);
|
|
1397
|
-
}
|
|
1398
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(
|
|
1399
|
-
style,
|
|
1400
|
-
node.interactiveStyles,
|
|
1401
|
-
elementClass,
|
|
1402
|
-
ctx
|
|
1403
|
-
);
|
|
1404
|
-
const src = node.src;
|
|
1405
|
-
const alt = node.alt;
|
|
1406
|
-
let imgAttrs = "";
|
|
1407
|
-
if (src) imgAttrs += ` src="${escapeJSX(String(src))}"`;
|
|
1408
|
-
if (alt !== void 0) imgAttrs += ` alt="${escapeJSX(String(alt))}"`;
|
|
1409
|
-
const metadata = src ? ctx.imageMetadataMap?.get(String(src)) : void 0;
|
|
1410
|
-
if (metadata) {
|
|
1411
|
-
let width = metadata.width;
|
|
1412
|
-
let height = metadata.height;
|
|
1413
|
-
if (width !== void 0) imgAttrs += ` width="${width}"`;
|
|
1414
|
-
if (height !== void 0) imgAttrs += ` height="${height}"`;
|
|
1415
|
-
let blurStyle = "";
|
|
1416
|
-
if (metadata.blurHash) {
|
|
1417
|
-
blurStyle = ` style="background-image: url(${escapeJSX(metadata.blurHash)}); background-size: cover;" onload="this.style.backgroundImage=''"`;
|
|
1418
|
-
}
|
|
1419
|
-
const sizesValue = DEFAULT_SIZES2;
|
|
1420
|
-
if (metadata.avifSrcset) {
|
|
1421
|
-
const classMatch = classExpr.match(/class="([^"]*)"/);
|
|
1422
|
-
const allClasses = classMatch ? classMatch[1].split(/\s+/).filter(Boolean) : [];
|
|
1423
|
-
const { pictureClasses, imgClasses } = splitImageClasses(allClasses);
|
|
1424
|
-
const pictureClassAttr = pictureClasses.length > 0 ? ` class="${pictureClasses.join(" ")}"` : "";
|
|
1425
|
-
const imgClassAttr = imgClasses.length > 0 ? ` class="${imgClasses.join(" ")}"` : "";
|
|
1426
|
-
return `${ind(ctx)}<picture${pictureClassAttr}${styleAttr}>
|
|
1427
|
-
${ind(ctx)} <source type="image/avif" srcset="${escapeJSX(metadata.avifSrcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1428
|
-
${ind(ctx)} <source type="image/webp" srcset="${escapeJSX(metadata.srcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1429
|
-
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${blurStyle} />
|
|
1430
|
-
${ind(ctx)}</picture>
|
|
1431
|
-
`;
|
|
1432
|
-
}
|
|
1433
|
-
if (metadata.srcset) {
|
|
1434
|
-
imgAttrs += ` srcset="${escapeJSX(metadata.srcset)}"`;
|
|
1435
|
-
imgAttrs += ` sizes="${escapeJSX(sizesValue)}"`;
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
return `${ind(ctx)}<img${classExpr}${styleAttr}${imgAttrs} />
|
|
1439
|
-
`;
|
|
1440
|
-
}
|
|
1441
|
-
function emitListNode(node, ctx) {
|
|
1442
|
-
const sourceType = node.sourceType || "prop";
|
|
1443
|
-
const itemAs = node.itemAs || "item";
|
|
1444
|
-
if (sourceType === "collection") {
|
|
1445
|
-
return emitCollectionListNode(node, ctx);
|
|
1446
|
-
}
|
|
1447
|
-
if (!ctx.isComponentDef && !ctx.listItemBinding) {
|
|
1448
|
-
return emitFallback(ctx);
|
|
1449
|
-
}
|
|
1450
|
-
let source = node.source || "items";
|
|
1451
|
-
const templateMatch = source.match(/^\{\{(.+)\}\}$/);
|
|
1452
|
-
if (templateMatch) {
|
|
1453
|
-
source = templateMatch[1].trim();
|
|
1454
|
-
}
|
|
1455
|
-
let mapSource = source;
|
|
1456
|
-
if (node.offset && node.limit) {
|
|
1457
|
-
mapSource = `${source}.slice(${node.offset}, ${node.offset + node.limit})`;
|
|
1458
|
-
} else if (node.offset) {
|
|
1459
|
-
mapSource = `${source}.slice(${node.offset})`;
|
|
1460
|
-
} else if (node.limit) {
|
|
1461
|
-
mapSource = `${source}.slice(0, ${node.limit})`;
|
|
1462
|
-
}
|
|
1463
|
-
const indexVar = `${itemAs}Index`;
|
|
1464
|
-
const innerCtx = {
|
|
1465
|
-
...ctx,
|
|
1466
|
-
indent: ctx.indent + 1,
|
|
1467
|
-
listItemBinding: itemAs,
|
|
1468
|
-
listIndexVar: indexVar,
|
|
1469
|
-
listSourceVar: mapSource,
|
|
1470
|
-
elementPath: [...ctx.elementPath, 0]
|
|
1471
|
-
};
|
|
1472
|
-
const children = node.children ? node.children.map((child, i) => {
|
|
1473
|
-
const childCtx = { ...innerCtx, elementPath: [...ctx.elementPath, i] };
|
|
1474
|
-
const out = nodeToAstro(child, childCtx);
|
|
1475
|
-
if (childCtx.needsI18nResolver) ctx.needsI18nResolver = true;
|
|
1476
|
-
return out;
|
|
1477
|
-
}).join("") : "";
|
|
1478
|
-
return `${ind(ctx)}{${mapSource}.map((${itemAs}, ${indexVar}) => (
|
|
1479
|
-
` + children + `${ind(ctx)}))}
|
|
1480
|
-
`;
|
|
1481
|
-
}
|
|
1482
|
-
function emitCollectionListNode(node, ctx) {
|
|
1483
|
-
const source = node.source || "";
|
|
1484
|
-
const itemAs = node.itemAs || singularize(source);
|
|
1485
|
-
if (!ctx.frontmatterLines) ctx.frontmatterLines = [];
|
|
1486
|
-
if (!ctx.astroImports) ctx.astroImports = /* @__PURE__ */ new Set();
|
|
1487
|
-
ctx.astroImports.add("getCollection");
|
|
1488
|
-
const collectionVar = `${source}List`;
|
|
1489
|
-
let queryChain = `await getCollection('${source}')`;
|
|
1490
|
-
if (node.filter) {
|
|
1491
|
-
if (typeof node.filter === "object" && !Array.isArray(node.filter) && "field" in node.filter) {
|
|
1492
|
-
const f = node.filter;
|
|
1493
|
-
const op = f.operator || "eq";
|
|
1494
|
-
if (op === "eq") {
|
|
1495
|
-
queryChain += `.then(items => items.filter(e => e.data.${f.field} === ${JSON.stringify(f.value)}))`;
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
if (node.sort) {
|
|
1500
|
-
const sortConfig = Array.isArray(node.sort) ? node.sort[0] : node.sort;
|
|
1501
|
-
if (sortConfig) {
|
|
1502
|
-
const order = sortConfig.order === "desc" ? -1 : 1;
|
|
1503
|
-
queryChain += `.then(items => items.sort((a, b) => a.data.${sortConfig.field} > b.data.${sortConfig.field} ? ${order} : ${-order}))`;
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
if (node.offset || node.limit) {
|
|
1507
|
-
const start = node.offset || 0;
|
|
1508
|
-
const end = node.limit ? start + node.limit : void 0;
|
|
1509
|
-
queryChain += `.then(items => items.slice(${start}${end !== void 0 ? `, ${end}` : ""}))`;
|
|
1510
|
-
}
|
|
1511
|
-
ctx.frontmatterLines.push(`const ${collectionVar} = ${queryChain};`);
|
|
1512
|
-
const indexVar = `${itemAs}Index`;
|
|
1513
|
-
const innerCtx = {
|
|
1514
|
-
...ctx,
|
|
1515
|
-
indent: ctx.indent + 1,
|
|
1516
|
-
listItemBinding: itemAs,
|
|
1517
|
-
listIndexVar: indexVar,
|
|
1518
|
-
listSourceVar: collectionVar,
|
|
1519
|
-
cmsMode: true,
|
|
1520
|
-
cmsEntryBinding: itemAs,
|
|
1521
|
-
elementPath: [...ctx.elementPath, 0]
|
|
1522
|
-
};
|
|
1523
|
-
const children = node.children ? node.children.map((child, i) => {
|
|
1524
|
-
const childCtx = { ...innerCtx, elementPath: [...ctx.elementPath, i] };
|
|
1525
|
-
const out = nodeToAstro(child, childCtx);
|
|
1526
|
-
if (childCtx.needsI18nResolver) ctx.needsI18nResolver = true;
|
|
1527
|
-
return out;
|
|
1528
|
-
}).join("") : "";
|
|
1529
|
-
return `${ind(ctx)}{${collectionVar}.map((${itemAs}, ${indexVar}) => (
|
|
1530
|
-
` + children + `${ind(ctx)}))}
|
|
1531
|
-
`;
|
|
1532
|
-
}
|
|
1533
|
-
function emitLocaleListNode(node, ctx) {
|
|
1534
|
-
if (!ctx.i18nConfig || !ctx.currentPageSlugMap) {
|
|
1535
|
-
return emitFallback(ctx);
|
|
1536
|
-
}
|
|
1537
|
-
const i18nConfig = ctx.i18nConfig;
|
|
1538
|
-
const slugMap = ctx.currentPageSlugMap;
|
|
1539
|
-
const showCurrent = node.showCurrent !== false;
|
|
1540
|
-
const showSeparator = node.showSeparator !== false;
|
|
1541
|
-
const showFlag = node.showFlag !== false;
|
|
1542
|
-
const displayType = node.displayType || "nativeName";
|
|
1543
|
-
const style = node.style;
|
|
1544
|
-
let elementClass = null;
|
|
1545
|
-
if (node.interactiveStyles && node.interactiveStyles.length > 0 || node.generateElementClass) {
|
|
1546
|
-
elementClass = buildElementClass(ctx, node.label);
|
|
1547
|
-
}
|
|
1548
|
-
const { classExpr: containerClassExpr, styleAttr: containerStyleAttr } = buildClassAndStyleExpression(
|
|
1549
|
-
style,
|
|
1550
|
-
node.interactiveStyles,
|
|
1551
|
-
elementClass,
|
|
1552
|
-
ctx
|
|
1553
|
-
);
|
|
1554
|
-
const itemStyle = node.itemStyle;
|
|
1555
|
-
const itemResult = itemStyle ? responsiveStylesToTailwind(itemStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1556
|
-
const itemClasses = itemResult.classes;
|
|
1557
|
-
const activeItemStyle = node.activeItemStyle;
|
|
1558
|
-
const activeResult = activeItemStyle ? responsiveStylesToTailwind(activeItemStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1559
|
-
const activeItemClasses = [...itemClasses, ...activeResult.classes];
|
|
1560
|
-
const separatorStyle = node.separatorStyle;
|
|
1561
|
-
const sepResult = separatorStyle ? responsiveStylesToTailwind(separatorStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1562
|
-
const separatorClasses = sepResult.classes;
|
|
1563
|
-
const localeIconMap = /* @__PURE__ */ new Map();
|
|
1564
|
-
for (const localeConfig of i18nConfig.locales) {
|
|
1565
|
-
if (localeConfig.icon) {
|
|
1566
|
-
localeIconMap.set(localeConfig.code, localeConfig.icon);
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
const flagStyle = node.flagStyle;
|
|
1570
|
-
const flagResult = flagStyle ? responsiveStylesToTailwind(flagStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1571
|
-
const flagClasses = flagResult.classes;
|
|
1572
|
-
const links = [];
|
|
1573
|
-
const currentLocale = ctx.locale || i18nConfig.defaultLocale;
|
|
1574
|
-
for (const localeConfig of i18nConfig.locales) {
|
|
1575
|
-
const code = localeConfig.code;
|
|
1576
|
-
const isCurrent = code === currentLocale;
|
|
1577
|
-
if (!showCurrent && isCurrent) continue;
|
|
1578
|
-
const path = slugMap[code] || "/";
|
|
1579
|
-
const classes = isCurrent ? activeItemClasses : itemClasses;
|
|
1580
|
-
const classAttr = classes.length > 0 ? ` class="${classes.join(" ")}"` : "";
|
|
1581
|
-
const currentAttr = isCurrent ? ' data-current="true"' : ' data-current="false"';
|
|
1582
|
-
const hreflangAttr = ` hreflang="${localeConfig.langTag}"`;
|
|
1583
|
-
let displayText;
|
|
1584
|
-
switch (displayType) {
|
|
1585
|
-
case "code":
|
|
1586
|
-
displayText = code.toUpperCase();
|
|
1587
|
-
break;
|
|
1588
|
-
case "name":
|
|
1589
|
-
displayText = localeConfig.name;
|
|
1590
|
-
break;
|
|
1591
|
-
case "nativeName":
|
|
1592
|
-
default:
|
|
1593
|
-
displayText = localeConfig.nativeName;
|
|
1594
|
-
break;
|
|
1595
|
-
}
|
|
1596
|
-
let linkContent = "";
|
|
1597
|
-
const localeIcon = localeIconMap.get(code);
|
|
1598
|
-
if (showFlag && localeIcon) {
|
|
1599
|
-
const flagClassAttr = flagClasses.length > 0 ? ` class="${flagClasses.join(" ")}"` : "";
|
|
1600
|
-
linkContent += `<img src="${escapeJSX(localeIcon)}" alt="${escapeJSX(localeConfig.nativeName)} flag"${flagClassAttr}>`;
|
|
1601
|
-
}
|
|
1602
|
-
linkContent += `<div>${escapeJSX(displayText)}</div>`;
|
|
1603
|
-
links.push(`${ind(ctx)} <a href="${escapeJSX(path)}"${hreflangAttr}${currentAttr} data-locale="${escapeJSX(code)}"${classAttr}>${linkContent}</a>`);
|
|
1604
|
-
}
|
|
1605
|
-
let linksContent;
|
|
1606
|
-
if (showSeparator && links.length > 1) {
|
|
1607
|
-
const sepClassAttr = separatorClasses.length > 0 ? ` class="${separatorClasses.join(" ")}"` : "";
|
|
1608
|
-
linksContent = links.join(`
|
|
1609
|
-
${ind(ctx)} <span${sepClassAttr}></span>
|
|
1610
|
-
`);
|
|
1611
|
-
} else {
|
|
1612
|
-
linksContent = links.join("\n");
|
|
1613
|
-
}
|
|
1614
|
-
const attrs = buildAttributesString(node.attributes, ctx);
|
|
1615
|
-
return `${ind(ctx)}<div data-locale-list="true"${containerClassExpr}${containerStyleAttr}${attrs}>
|
|
1616
|
-
` + linksContent + `
|
|
1617
|
-
${ind(ctx)}</div>
|
|
1618
|
-
`;
|
|
1619
|
-
}
|
|
1620
|
-
function emitFallback(ctx) {
|
|
1621
|
-
const pathKey = ctx.elementPath.join(".");
|
|
1622
|
-
const ssrHtml = ctx.ssrFallbacks.get(pathKey);
|
|
1623
|
-
if (ssrHtml) {
|
|
1624
|
-
const escaped = escapeTemplateLiteral(ssrHtml);
|
|
1625
|
-
return `${ind(ctx)}<Fragment set:html={\`${escaped}\`} />
|
|
1626
|
-
`;
|
|
1627
|
-
}
|
|
1628
|
-
return `${ind(ctx)}{/* Complex node - SSR fallback not available */}
|
|
1629
|
-
`;
|
|
1630
|
-
}
|
|
1631
|
-
function emitIfOpen(node, ctx) {
|
|
1632
|
-
const ifValue = node.if;
|
|
1633
|
-
if (ifValue === void 0 || ifValue === true) return "";
|
|
1634
|
-
if (typeof ifValue === "boolean") {
|
|
1635
|
-
return ifValue ? "" : `${ind(ctx)}{/* hidden */}
|
|
1636
|
-
`;
|
|
1637
|
-
}
|
|
1638
|
-
if (typeof ifValue === "object" && ifValue._mapping && ctx.isComponentDef) {
|
|
1639
|
-
const trueValues = Object.entries(ifValue.values).filter(([, v]) => v === true).map(([k]) => `'${k}'`);
|
|
1640
|
-
if (trueValues.length === 0) return `${ind(ctx)}{/* hidden */}
|
|
1641
|
-
`;
|
|
1642
|
-
if (trueValues.length === 1) {
|
|
1643
|
-
return `${ind(ctx)}{${ifValue.prop} === ${trueValues[0]} && (
|
|
1644
|
-
`;
|
|
1645
|
-
}
|
|
1646
|
-
return `${ind(ctx)}{[${trueValues.join(", ")}].includes(${ifValue.prop}) && (
|
|
1647
|
-
`;
|
|
1648
|
-
}
|
|
1649
|
-
if (typeof ifValue === "string") {
|
|
1650
|
-
if (ctx.cmsMode && ifValue.includes("{{cms.")) {
|
|
1651
|
-
const match = ifValue.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
1652
|
-
if (match) {
|
|
1653
|
-
const binding = ctx.cmsEntryBinding || "entry";
|
|
1654
|
-
return `${ind(ctx)}{${binding}.data.${match[1].trim()} && (
|
|
1655
|
-
`;
|
|
1656
|
-
}
|
|
1657
|
-
}
|
|
1658
|
-
if (ctx.listItemBinding && /\{\{/.test(ifValue)) {
|
|
1659
|
-
const match = ifValue.match(/^\{\{([^}]+)\}\}$/);
|
|
1660
|
-
if (match) {
|
|
1661
|
-
let expr = match[1].trim();
|
|
1662
|
-
expr = rewriteItemVar(expr, ctx.listItemBinding);
|
|
1663
|
-
if (ctx.listIndexVar) expr = replaceItemMetaVars(expr, ctx.listIndexVar, ctx.listSourceVar);
|
|
1664
|
-
return `${ind(ctx)}{${expr} && (
|
|
1665
|
-
`;
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
if (ctx.isComponentDef) {
|
|
1669
|
-
const fullMatch = ifValue.match(/^\{\{(.+)\}\}$/);
|
|
1670
|
-
let expr = fullMatch ? fullMatch[1].trim() : ifValue.replace(/\{\{(.+?)\}\}/g, "$1");
|
|
1671
|
-
if (ctx.listItemBinding) expr = rewriteItemVar(expr, ctx.listItemBinding);
|
|
1672
|
-
if (ctx.listIndexVar) expr = replaceItemMetaVars(expr, ctx.listIndexVar, ctx.listSourceVar);
|
|
1673
|
-
return `${ind(ctx)}{${expr} && (
|
|
1674
|
-
`;
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
return "";
|
|
1678
|
-
}
|
|
1679
|
-
function emitIfClose(node, ctx) {
|
|
1680
|
-
const ifValue = node.if;
|
|
1681
|
-
if (ifValue === void 0 || ifValue === true) return "";
|
|
1682
|
-
if (typeof ifValue === "boolean") return "";
|
|
1683
|
-
if (typeof ifValue === "object" && ifValue._mapping && ctx.isComponentDef) {
|
|
1684
|
-
return `${ind(ctx)})}
|
|
1685
|
-
`;
|
|
1686
|
-
}
|
|
1687
|
-
if (typeof ifValue === "string") {
|
|
1688
|
-
const hasCmsCondition = ctx.cmsMode && ifValue.includes("{{cms.");
|
|
1689
|
-
const hasItemCondition = ctx.listItemBinding && /\{\{/.test(ifValue);
|
|
1690
|
-
if (hasCmsCondition || hasItemCondition || ctx.isComponentDef) {
|
|
1691
|
-
return `${ind(ctx)})}
|
|
1692
|
-
`;
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
return "";
|
|
1696
|
-
}
|
|
1697
|
-
function emitChildren(children, ctx) {
|
|
1698
|
-
if (!children) return "";
|
|
1699
|
-
const innerCtx = { ...ctx, indent: ctx.indent + 1, elementPath: [...ctx.elementPath] };
|
|
1700
|
-
if (typeof children === "string") {
|
|
1701
|
-
const out2 = nodeToAstro(children, innerCtx);
|
|
1702
|
-
if (innerCtx.needsI18nResolver) ctx.needsI18nResolver = true;
|
|
1703
|
-
return out2;
|
|
1704
|
-
}
|
|
1705
|
-
if (Array.isArray(children)) {
|
|
1706
|
-
let result = "";
|
|
1707
|
-
for (let i = 0; i < children.length; i++) {
|
|
1708
|
-
const childCtx = { ...innerCtx, elementPath: [...ctx.elementPath, i] };
|
|
1709
|
-
result += nodeToAstro(children[i], childCtx);
|
|
1710
|
-
if (childCtx.needsI18nResolver) ctx.needsI18nResolver = true;
|
|
1711
|
-
}
|
|
1712
|
-
return result;
|
|
1713
|
-
}
|
|
1714
|
-
const out = nodeToAstro(children, innerCtx);
|
|
1715
|
-
if (innerCtx.needsI18nResolver) ctx.needsI18nResolver = true;
|
|
1716
|
-
return out;
|
|
1717
|
-
}
|
|
1718
|
-
|
|
1719
|
-
// lib/server/astro/componentEmitter.ts
|
|
1720
|
-
function propDefToTSType(def) {
|
|
1721
|
-
switch (def.type) {
|
|
1722
|
-
case "string":
|
|
1723
|
-
case "rich-text":
|
|
1724
|
-
case "file":
|
|
1725
|
-
return "string";
|
|
1726
|
-
case "number":
|
|
1727
|
-
return "number";
|
|
1728
|
-
case "boolean":
|
|
1729
|
-
return "boolean";
|
|
1730
|
-
case "select":
|
|
1731
|
-
if ("options" in def && def.options && def.options.length > 0) {
|
|
1732
|
-
return def.options.map((o) => `'${o}'`).join(" | ");
|
|
1733
|
-
}
|
|
1734
|
-
return "string";
|
|
1735
|
-
case "link":
|
|
1736
|
-
return "{ href: string; target?: string }";
|
|
1737
|
-
case "list":
|
|
1738
|
-
return "any[]";
|
|
1739
|
-
default:
|
|
1740
|
-
return "any";
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
function formatDefault(def) {
|
|
1744
|
-
if (!("default" in def) || def.default === void 0) return null;
|
|
1745
|
-
const val = def.default;
|
|
1746
|
-
if (typeof val === "string") return JSON.stringify(val);
|
|
1747
|
-
if (typeof val === "number" || typeof val === "boolean") return String(val);
|
|
1748
|
-
if (typeof val === "object" && val !== null && "_i18n" in val) {
|
|
1749
|
-
for (const [key, v] of Object.entries(val)) {
|
|
1750
|
-
if (key !== "_i18n" && typeof v === "string") return JSON.stringify(v);
|
|
1751
|
-
}
|
|
1752
|
-
return null;
|
|
1753
|
-
}
|
|
1754
|
-
if (typeof val === "object" && val !== null && "href" in val) {
|
|
1755
|
-
return JSON.stringify(val);
|
|
1756
|
-
}
|
|
1757
|
-
if (Array.isArray(val)) {
|
|
1758
|
-
return JSON.stringify(val);
|
|
1759
|
-
}
|
|
1760
|
-
return JSON.stringify(val);
|
|
1761
|
-
}
|
|
1762
|
-
function emitAstroComponent(name, def, allComponents, breakpoints = DEFAULT_BREAKPOINTS, defaultLocale = "en") {
|
|
1763
|
-
const comp = def.component;
|
|
1764
|
-
const propDefs = comp.interface || {};
|
|
1765
|
-
const structure = comp.structure;
|
|
1766
|
-
if (!structure) {
|
|
1767
|
-
return buildNoStructureComponent(name, comp);
|
|
1768
|
-
}
|
|
1769
|
-
const ctx = {
|
|
1770
|
-
imports: /* @__PURE__ */ new Set(),
|
|
1771
|
-
isComponentDef: true,
|
|
1772
|
-
componentProps: propDefs,
|
|
1773
|
-
globalComponents: allComponents,
|
|
1774
|
-
indent: 0,
|
|
1775
|
-
ssrFallbacks: /* @__PURE__ */ new Map(),
|
|
1776
|
-
elementPath: [0],
|
|
1777
|
-
fileType: "component",
|
|
1778
|
-
fileName: name,
|
|
1779
|
-
breakpoints,
|
|
1780
|
-
defaultLocale
|
|
1781
|
-
};
|
|
1782
|
-
const templateBody = nodeToAstro(structure, ctx);
|
|
1783
|
-
const frontmatter = buildFrontmatter(name, propDefs, ctx.imports, ctx.dynamicTags, ctx.needsI18nResolver ? defaultLocale : void 0);
|
|
1784
|
-
const styleSection = comp.css ? `
|
|
1785
|
-
<style>
|
|
1786
|
-
${comp.css}
|
|
1787
|
-
</style>
|
|
1788
|
-
` : "";
|
|
1789
|
-
const scriptSection = comp.javascript ? buildScriptSection(comp.javascript, comp, propDefs) : "";
|
|
1790
|
-
return `---
|
|
1791
|
-
${frontmatter}---
|
|
1792
|
-
${templateBody}${styleSection}${scriptSection}`;
|
|
1793
|
-
}
|
|
1794
|
-
function buildFrontmatter(componentName, propDefs, imports, dynamicTags, i18nDefaultLocale) {
|
|
1795
|
-
const lines = [];
|
|
1796
|
-
for (const imp of Array.from(imports).sort()) {
|
|
1797
|
-
lines.push(`import ${imp} from './${imp}.astro';`);
|
|
1798
|
-
}
|
|
1799
|
-
if (lines.length > 0) lines.push("");
|
|
1800
|
-
const propEntries = Object.entries(propDefs);
|
|
1801
|
-
if (propEntries.length > 0) {
|
|
1802
|
-
lines.push("interface Props {");
|
|
1803
|
-
for (const [propName, propDef] of propEntries) {
|
|
1804
|
-
if (propName === "children") continue;
|
|
1805
|
-
const tsType = propDefToTSType(propDef);
|
|
1806
|
-
const optional = "default" in propDef && propDef.default !== void 0;
|
|
1807
|
-
lines.push(` ${propName}${optional ? "?" : ""}: ${tsType};`);
|
|
1808
|
-
}
|
|
1809
|
-
lines.push("}");
|
|
1810
|
-
lines.push("");
|
|
1811
|
-
const destructParts = [];
|
|
1812
|
-
for (const [propName, propDef] of propEntries) {
|
|
1813
|
-
if (propName === "children") continue;
|
|
1814
|
-
const defaultVal = formatDefault(propDef);
|
|
1815
|
-
if (defaultVal !== null) {
|
|
1816
|
-
destructParts.push(`${propName} = ${defaultVal}`);
|
|
1817
|
-
} else if (propDef.type === "link") {
|
|
1818
|
-
destructParts.push(`${propName} = { href: "#" }`);
|
|
1819
|
-
} else {
|
|
1820
|
-
destructParts.push(propName);
|
|
1821
|
-
}
|
|
1822
|
-
}
|
|
1823
|
-
if (destructParts.length > 0) {
|
|
1824
|
-
if (destructParts.length <= 3 && destructParts.join(", ").length < 80) {
|
|
1825
|
-
lines.push(`const { ${destructParts.join(", ")} } = Astro.props;`);
|
|
1826
|
-
} else {
|
|
1827
|
-
lines.push("const {");
|
|
1828
|
-
for (const part of destructParts) {
|
|
1829
|
-
lines.push(` ${part},`);
|
|
1830
|
-
}
|
|
1831
|
-
lines.push("} = Astro.props;");
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1835
|
-
if (dynamicTags && dynamicTags.size > 0) {
|
|
1836
|
-
lines.push("");
|
|
1837
|
-
for (const [varName, templateExpr] of dynamicTags) {
|
|
1838
|
-
lines.push(`const ${varName} = \`${templateExpr}\`;`);
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
if (i18nDefaultLocale) {
|
|
1842
|
-
lines.push("");
|
|
1843
|
-
lines.push(`const r = (v: any) => {`);
|
|
1844
|
-
lines.push(` if (v && typeof v === 'object' && v._i18n) {`);
|
|
1845
|
-
lines.push(` const locale = Astro.currentLocale ?? '${i18nDefaultLocale}';`);
|
|
1846
|
-
lines.push(` return v[locale] ?? v['${i18nDefaultLocale}'] ?? Object.values(v).find((s: any) => typeof s === 'string' && s !== '') ?? '';`);
|
|
1847
|
-
lines.push(` }`);
|
|
1848
|
-
lines.push(` return v ?? '';`);
|
|
1849
|
-
lines.push(`};`);
|
|
1850
|
-
}
|
|
1851
|
-
if (lines.length > 0) lines.push("");
|
|
1852
|
-
return lines.join("\n");
|
|
1853
|
-
}
|
|
1854
|
-
function buildNoStructureComponent(name, comp) {
|
|
1855
|
-
let content = "---\n---\n<slot />\n";
|
|
1856
|
-
if (comp.css) content += `
|
|
1857
|
-
<style>
|
|
1858
|
-
${comp.css}
|
|
1859
|
-
</style>
|
|
1860
|
-
`;
|
|
1861
|
-
if (comp.javascript) content += `
|
|
1862
|
-
<script is:inline>
|
|
1863
|
-
${comp.javascript}
|
|
1864
|
-
</script>
|
|
1865
|
-
`;
|
|
1866
|
-
return content;
|
|
1867
|
-
}
|
|
1868
|
-
function transformDefineVarsJS(js, varNames) {
|
|
1869
|
-
let result = js;
|
|
1870
|
-
result = result.replace(
|
|
1871
|
-
/^\s*(const|let|var)\s+\{([^}]+)\}\s*=\s*props\s*;?\s*$/gm,
|
|
1872
|
-
(match, _keyword, inner) => {
|
|
1873
|
-
const names = inner.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1874
|
-
if (names.every((n) => varNames.includes(n))) return "";
|
|
1875
|
-
return match;
|
|
1876
|
-
}
|
|
1877
|
-
);
|
|
1878
|
-
const sorted = [...varNames].sort((a, b) => b.length - a.length);
|
|
1879
|
-
for (const name of sorted) {
|
|
1880
|
-
result = result.replace(new RegExp(`props\\.${name}\\b`, "g"), name);
|
|
1881
|
-
}
|
|
1882
|
-
for (const name of varNames) {
|
|
1883
|
-
result = result.replace(
|
|
1884
|
-
new RegExp(`^\\s*(var|let|const)\\s+${name}\\s*=[^;]*;?\\s*$`, "gm"),
|
|
1885
|
-
""
|
|
1886
|
-
);
|
|
1887
|
-
}
|
|
1888
|
-
return result;
|
|
1889
|
-
}
|
|
1890
|
-
function buildScriptSection(js, comp, propDefs) {
|
|
1891
|
-
const elInit = "const el = document.currentScript.previousElementSibling;";
|
|
1892
|
-
if (comp.defineVars) {
|
|
1893
|
-
const vars = comp.defineVars === true ? Object.keys(propDefs).filter((k) => k !== "children") : comp.defineVars;
|
|
1894
|
-
if (vars.length > 0) {
|
|
1895
|
-
const transformedJS = transformDefineVarsJS(js, vars);
|
|
1896
|
-
const defineVarsObj = `{ ${vars.join(", ")} }`;
|
|
1897
|
-
return `
|
|
1898
|
-
<script define:vars={${defineVarsObj}}>
|
|
1899
|
-
${elInit}
|
|
1900
|
-
${transformedJS}
|
|
1901
|
-
</script>
|
|
1902
|
-
`;
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
return `
|
|
1906
|
-
<script is:inline>
|
|
1907
|
-
${elInit}
|
|
1908
|
-
${js}
|
|
1909
|
-
</script>
|
|
1910
|
-
`;
|
|
1911
|
-
}
|
|
1912
|
-
|
|
1913
|
-
// lib/server/astro/pageEmitter.ts
|
|
1914
|
-
function escapeTemplateLiteral2(s) {
|
|
1915
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
1916
|
-
}
|
|
1917
|
-
function escapeJSX2(s) {
|
|
1918
|
-
return s.replace(/&/g, "&").replace(/"/g, """);
|
|
1919
|
-
}
|
|
1920
|
-
function componentImportPath(fileDepth, componentName) {
|
|
1921
|
-
const ups = "../".repeat(fileDepth + 1);
|
|
1922
|
-
return `${ups}components/${componentName}.astro`;
|
|
1923
|
-
}
|
|
1924
|
-
function emitAstroPage(options) {
|
|
1925
|
-
const {
|
|
1926
|
-
pageData,
|
|
1927
|
-
globalComponents,
|
|
1928
|
-
title,
|
|
1929
|
-
meta,
|
|
1930
|
-
locale,
|
|
1931
|
-
theme,
|
|
1932
|
-
fontPreloads,
|
|
1933
|
-
libraryTags,
|
|
1934
|
-
scriptPaths,
|
|
1935
|
-
layoutImportPath: layoutImportPath2,
|
|
1936
|
-
fileDepth,
|
|
1937
|
-
ssrFallbacks,
|
|
1938
|
-
pageName,
|
|
1939
|
-
breakpoints: breakpointsOpt,
|
|
1940
|
-
imageMetadataMap,
|
|
1941
|
-
i18nConfig,
|
|
1942
|
-
currentPageSlugMap,
|
|
1943
|
-
slugMappings
|
|
1944
|
-
} = options;
|
|
1945
|
-
const breakpoints = breakpointsOpt ?? DEFAULT_BREAKPOINTS;
|
|
1946
|
-
const root = pageData.root;
|
|
1947
|
-
if (!root) {
|
|
1948
|
-
return buildEmptyPage(layoutImportPath2, title, meta, locale, theme, fontPreloads, libraryTags, scriptPaths);
|
|
1949
|
-
}
|
|
1950
|
-
const ctx = {
|
|
1951
|
-
imports: /* @__PURE__ */ new Set(),
|
|
1952
|
-
isComponentDef: false,
|
|
1953
|
-
componentProps: {},
|
|
1954
|
-
globalComponents,
|
|
1955
|
-
indent: 1,
|
|
1956
|
-
// inside BaseLayout
|
|
1957
|
-
ssrFallbacks,
|
|
1958
|
-
elementPath: [0],
|
|
1959
|
-
fileType: "page",
|
|
1960
|
-
fileName: pageName,
|
|
1961
|
-
breakpoints,
|
|
1962
|
-
imageMetadataMap,
|
|
1963
|
-
locale,
|
|
1964
|
-
i18nConfig,
|
|
1965
|
-
currentPageSlugMap,
|
|
1966
|
-
frontmatterLines: [],
|
|
1967
|
-
astroImports: /* @__PURE__ */ new Set(),
|
|
1968
|
-
slugMappings,
|
|
1969
|
-
i18nDefaultLocale: i18nConfig?.defaultLocale
|
|
1970
|
-
};
|
|
1971
|
-
const templateBody = nodeToAstro(root, ctx);
|
|
1972
|
-
const importLines = [];
|
|
1973
|
-
if (ctx.astroImports && ctx.astroImports.size > 0) {
|
|
1974
|
-
const astroImports = Array.from(ctx.astroImports);
|
|
1975
|
-
importLines.push(`import { ${astroImports.join(", ")} } from 'astro:content';`);
|
|
1976
|
-
}
|
|
1977
|
-
importLines.push(`import BaseLayout from '${layoutImportPath2}';`);
|
|
1978
|
-
const componentImports = Array.from(ctx.imports).sort();
|
|
1979
|
-
for (const comp of componentImports) {
|
|
1980
|
-
const path = componentImportPath(fileDepth, comp);
|
|
1981
|
-
importLines.push(`import ${comp} from '${path}';`);
|
|
1982
|
-
}
|
|
1983
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
1984
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral2(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral2(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral2(libraryTags.bodyEndJS || "")}\` }`;
|
|
1985
|
-
const escapedMeta = escapeTemplateLiteral2(meta);
|
|
1986
|
-
const escapedFontPreloads = escapeTemplateLiteral2(fontPreloads);
|
|
1987
|
-
const extraFrontmatter = ctx.frontmatterLines && ctx.frontmatterLines.length > 0 ? "\n" + ctx.frontmatterLines.join("\n") : "";
|
|
1988
|
-
return `---
|
|
1989
|
-
${importLines.join("\n")}${extraFrontmatter}
|
|
1990
|
-
---
|
|
1991
|
-
<BaseLayout
|
|
1992
|
-
title="${escapeJSX2(title)}"
|
|
1993
|
-
meta={\`${escapedMeta}\`}
|
|
1994
|
-
scripts={${scriptsArrayLiteral}}
|
|
1995
|
-
locale="${locale}"
|
|
1996
|
-
theme="${theme}"
|
|
1997
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
1998
|
-
libraryTags={${libraryTagsLiteral}}
|
|
1999
|
-
>
|
|
2000
|
-
<div id="root">
|
|
2001
|
-
${templateBody} </div>
|
|
2002
|
-
</BaseLayout>
|
|
2003
|
-
`;
|
|
2004
|
-
}
|
|
2005
|
-
function buildEmptyPage(layoutImport, title, meta, locale, theme, fontPreloads, libraryTags, scriptPaths) {
|
|
2006
|
-
const escapedMeta = escapeTemplateLiteral2(meta);
|
|
2007
|
-
const escapedFontPreloads = escapeTemplateLiteral2(fontPreloads);
|
|
2008
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
2009
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral2(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral2(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral2(libraryTags.bodyEndJS || "")}\` }`;
|
|
2010
|
-
return `---
|
|
2011
|
-
import BaseLayout from '${layoutImport}';
|
|
2012
|
-
---
|
|
2013
|
-
<BaseLayout
|
|
2014
|
-
title="${escapeJSX2(title)}"
|
|
2015
|
-
meta={\`${escapedMeta}\`}
|
|
2016
|
-
scripts={${scriptsArrayLiteral}}
|
|
2017
|
-
locale="${locale}"
|
|
2018
|
-
theme="${theme}"
|
|
2019
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
2020
|
-
libraryTags={${libraryTagsLiteral}}
|
|
2021
|
-
>
|
|
2022
|
-
</BaseLayout>
|
|
2023
|
-
`;
|
|
2024
|
-
}
|
|
2025
|
-
|
|
2026
|
-
// lib/server/astro/cmsPageEmitter.ts
|
|
2027
|
-
function escapeTemplateLiteral3(s) {
|
|
2028
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
2029
|
-
}
|
|
2030
|
-
function escapeJSX3(s) {
|
|
2031
|
-
return s.replace(/&/g, "&").replace(/"/g, """);
|
|
2032
|
-
}
|
|
2033
|
-
function componentImportPath2(fileDepth, componentName) {
|
|
2034
|
-
const ups = "../".repeat(fileDepth + 1);
|
|
2035
|
-
return `${ups}components/${componentName}.astro`;
|
|
2036
|
-
}
|
|
2037
|
-
function collectRichTextFields(schema) {
|
|
2038
|
-
const richTextFields = /* @__PURE__ */ new Set();
|
|
2039
|
-
for (const [fieldName, fieldDef] of Object.entries(schema.fields)) {
|
|
2040
|
-
if (fieldDef.type === "rich-text") {
|
|
2041
|
-
richTextFields.add(fieldName);
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
return richTextFields;
|
|
2045
|
-
}
|
|
2046
|
-
function transformTitleExpression(title, binding, richTextFields, wrapFn) {
|
|
2047
|
-
if (!/\{\{cms\./.test(title)) {
|
|
2048
|
-
return `"${escapeJSX3(title)}"`;
|
|
2049
|
-
}
|
|
2050
|
-
const w = (expr) => wrapFn ? `${wrapFn}(${expr})` : expr;
|
|
2051
|
-
const fullMatch = title.match(/^\{\{cms\.([^}]+)\}\}$/);
|
|
2052
|
-
if (fullMatch) {
|
|
2053
|
-
return `{${w(`${binding}.data.${fullMatch[1].trim()}`)}}`;
|
|
2054
|
-
}
|
|
2055
|
-
const replaced = title.replace(/\{\{cms\.([^}]+)\}\}/g, (_, fieldPath) => {
|
|
2056
|
-
return `\${${w(`${binding}.data.${fieldPath.trim()}`)}}`;
|
|
2057
|
-
});
|
|
2058
|
-
return `{\`${replaced}\`}`;
|
|
2059
|
-
}
|
|
2060
|
-
function extractPathPrefix(urlPattern) {
|
|
2061
|
-
const withoutLeading = urlPattern.replace(/^\//, "");
|
|
2062
|
-
const idx = withoutLeading.indexOf("{{");
|
|
2063
|
-
if (idx <= 0) return "";
|
|
2064
|
-
return withoutLeading.substring(0, idx);
|
|
2065
|
-
}
|
|
2066
|
-
function buildGetStaticPaths(schema, isMultiLocale, i18nConfig, locale) {
|
|
2067
|
-
const collectionId = schema.id;
|
|
2068
|
-
const slugField = schema.slugField || "slug";
|
|
2069
|
-
const pathPrefix = extractPathPrefix(schema.urlPattern);
|
|
2070
|
-
const targetLocale = locale || i18nConfig.defaultLocale;
|
|
2071
|
-
if (!isMultiLocale) {
|
|
2072
|
-
const slugExpr = i18nConfig.locales.length > 1 ? `entry.data.${slugField}?.${targetLocale} || entry.data.${slugField} || entry.id` : `entry.data.${slugField} || entry.id`;
|
|
2073
|
-
return [
|
|
2074
|
-
`export async function getStaticPaths() {`,
|
|
2075
|
-
` const entries = await getCollection('${collectionId}');`,
|
|
2076
|
-
` return entries.map(entry => ({`,
|
|
2077
|
-
` params: { slug: ${slugExpr} },`,
|
|
2078
|
-
` props: { entry },`,
|
|
2079
|
-
` }));`,
|
|
2080
|
-
`}`,
|
|
2081
|
-
``,
|
|
2082
|
-
`const { entry } = Astro.props;`
|
|
2083
|
-
].join("\n");
|
|
2084
|
-
}
|
|
2085
|
-
const defaultLocale = i18nConfig.defaultLocale;
|
|
2086
|
-
const locales = i18nConfig.locales;
|
|
2087
|
-
const lines = [
|
|
2088
|
-
`export async function getStaticPaths() {`,
|
|
2089
|
-
` const entries = await getCollection('${collectionId}');`,
|
|
2090
|
-
` const paths = [];`,
|
|
2091
|
-
` for (const entry of entries) {`
|
|
2092
|
-
];
|
|
2093
|
-
for (const locale2 of locales) {
|
|
2094
|
-
const code = locale2.code;
|
|
2095
|
-
const slugExpr = `entry.data.${slugField}?.${code} || entry.data.${slugField} || entry.id`;
|
|
2096
|
-
if (code === defaultLocale) {
|
|
2097
|
-
if (pathPrefix) {
|
|
2098
|
-
lines.push(
|
|
2099
|
-
` paths.push({`,
|
|
2100
|
-
` params: { slug: \`${pathPrefix}\${${slugExpr}}\` },`,
|
|
2101
|
-
` props: { entry, locale: '${code}' },`,
|
|
2102
|
-
` });`
|
|
2103
|
-
);
|
|
2104
|
-
} else {
|
|
2105
|
-
lines.push(
|
|
2106
|
-
` paths.push({`,
|
|
2107
|
-
` params: { slug: ${slugExpr} },`,
|
|
2108
|
-
` props: { entry, locale: '${code}' },`,
|
|
2109
|
-
` });`
|
|
2110
|
-
);
|
|
2111
|
-
}
|
|
2112
|
-
} else {
|
|
2113
|
-
lines.push(
|
|
2114
|
-
` paths.push({`,
|
|
2115
|
-
` params: { slug: \`${code}/${pathPrefix}\${${slugExpr}}\` },`,
|
|
2116
|
-
` props: { entry, locale: '${code}' },`,
|
|
2117
|
-
` });`
|
|
2118
|
-
);
|
|
2119
|
-
}
|
|
2120
|
-
}
|
|
2121
|
-
lines.push(
|
|
2122
|
-
` }`,
|
|
2123
|
-
` return paths;`,
|
|
2124
|
-
`}`,
|
|
2125
|
-
``,
|
|
2126
|
-
`const { entry, locale = '${defaultLocale}' } = Astro.props;`
|
|
2127
|
-
);
|
|
2128
|
-
return lines.join("\n");
|
|
2129
|
-
}
|
|
2130
|
-
function emitCMSPage(options) {
|
|
2131
|
-
const {
|
|
2132
|
-
pageData,
|
|
2133
|
-
globalComponents,
|
|
2134
|
-
cmsSchema,
|
|
2135
|
-
title,
|
|
2136
|
-
meta,
|
|
2137
|
-
locale,
|
|
2138
|
-
theme,
|
|
2139
|
-
fontPreloads,
|
|
2140
|
-
libraryTags,
|
|
2141
|
-
scriptPaths,
|
|
2142
|
-
layoutImportPath: layoutImportPath2,
|
|
2143
|
-
fileDepth,
|
|
2144
|
-
ssrFallbacks,
|
|
2145
|
-
pageName,
|
|
2146
|
-
breakpoints: breakpointsOpt,
|
|
2147
|
-
imageMetadataMap,
|
|
2148
|
-
i18nConfig,
|
|
2149
|
-
isMultiLocale,
|
|
2150
|
-
slugMappings
|
|
2151
|
-
} = options;
|
|
2152
|
-
const breakpoints = breakpointsOpt ?? DEFAULT_BREAKPOINTS;
|
|
2153
|
-
const binding = "entry";
|
|
2154
|
-
const richTextFields = collectRichTextFields(cmsSchema);
|
|
2155
|
-
const wrapFn = "r";
|
|
2156
|
-
const root = pageData.root;
|
|
2157
|
-
if (!root) {
|
|
2158
|
-
return buildEmptyCMSPage(
|
|
2159
|
-
layoutImportPath2,
|
|
2160
|
-
title,
|
|
2161
|
-
meta,
|
|
2162
|
-
locale,
|
|
2163
|
-
theme,
|
|
2164
|
-
fontPreloads,
|
|
2165
|
-
libraryTags,
|
|
2166
|
-
scriptPaths,
|
|
2167
|
-
cmsSchema,
|
|
2168
|
-
isMultiLocale,
|
|
2169
|
-
i18nConfig,
|
|
2170
|
-
binding,
|
|
2171
|
-
richTextFields
|
|
2172
|
-
);
|
|
2173
|
-
}
|
|
2174
|
-
const ctx = {
|
|
2175
|
-
imports: /* @__PURE__ */ new Set(),
|
|
2176
|
-
isComponentDef: false,
|
|
2177
|
-
componentProps: {},
|
|
2178
|
-
globalComponents,
|
|
2179
|
-
indent: 1,
|
|
2180
|
-
// inside BaseLayout
|
|
2181
|
-
ssrFallbacks,
|
|
2182
|
-
elementPath: [0],
|
|
2183
|
-
fileType: "page",
|
|
2184
|
-
fileName: pageName,
|
|
2185
|
-
breakpoints,
|
|
2186
|
-
imageMetadataMap,
|
|
2187
|
-
locale,
|
|
2188
|
-
cmsMode: true,
|
|
2189
|
-
cmsEntryBinding: binding,
|
|
2190
|
-
cmsRichTextFields: richTextFields,
|
|
2191
|
-
cmsWrapFn: wrapFn,
|
|
2192
|
-
slugMappings,
|
|
2193
|
-
i18nDefaultLocale: i18nConfig.defaultLocale
|
|
2194
|
-
};
|
|
2195
|
-
const templateBody = nodeToAstro(root, ctx);
|
|
2196
|
-
const importLines = [];
|
|
2197
|
-
importLines.push(`import { getCollection } from 'astro:content';`);
|
|
2198
|
-
importLines.push(`import BaseLayout from '${layoutImportPath2}';`);
|
|
2199
|
-
const componentImports = Array.from(ctx.imports).sort();
|
|
2200
|
-
for (const comp of componentImports) {
|
|
2201
|
-
const path = componentImportPath2(fileDepth, comp);
|
|
2202
|
-
importLines.push(`import ${comp} from '${path}';`);
|
|
2203
|
-
}
|
|
2204
|
-
const staticPaths = buildGetStaticPaths(cmsSchema, isMultiLocale, i18nConfig, locale);
|
|
2205
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
2206
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral3(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral3(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral3(libraryTags.bodyEndJS || "")}\` }`;
|
|
2207
|
-
const escapedMeta = escapeTemplateLiteral3(meta).replace(
|
|
2208
|
-
/\{\{cms\.([^}]+)\}\}/g,
|
|
2209
|
-
(_, fieldPath) => `\${${wrapFn}(${binding}.data.${fieldPath.trim()})}`
|
|
2210
|
-
);
|
|
2211
|
-
const escapedFontPreloads = escapeTemplateLiteral3(fontPreloads);
|
|
2212
|
-
const titleExpr = transformTitleExpression(title, binding, richTextFields, wrapFn);
|
|
2213
|
-
const resolverHelper = `function r(v) {
|
|
2214
|
-
if (v && typeof v === 'object' && v._i18n) return v['${locale}'] ?? v['${i18nConfig.defaultLocale}'] ?? Object.values(v).find(x => x !== true && x !== undefined) ?? '';
|
|
2215
|
-
return v ?? '';
|
|
2216
|
-
}`;
|
|
2217
|
-
return `---
|
|
2218
|
-
${importLines.join("\n")}
|
|
2219
|
-
|
|
2220
|
-
${staticPaths}
|
|
2221
|
-
|
|
2222
|
-
${resolverHelper}
|
|
2223
|
-
---
|
|
2224
|
-
<BaseLayout
|
|
2225
|
-
title=${titleExpr}
|
|
2226
|
-
meta={\`${escapedMeta}\`}
|
|
2227
|
-
scripts={${scriptsArrayLiteral}}
|
|
2228
|
-
locale="${locale}"
|
|
2229
|
-
theme="${theme}"
|
|
2230
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
2231
|
-
libraryTags={${libraryTagsLiteral}}
|
|
2232
|
-
>
|
|
2233
|
-
<div id="root">
|
|
2234
|
-
${templateBody} </div>
|
|
2235
|
-
</BaseLayout>
|
|
2236
|
-
`;
|
|
2237
|
-
}
|
|
2238
|
-
function buildEmptyCMSPage(layoutImport, title, meta, locale, theme, fontPreloads, libraryTags, scriptPaths, cmsSchema, isMultiLocale, i18nConfig, binding, richTextFields) {
|
|
2239
|
-
const escapedMeta = escapeTemplateLiteral3(meta);
|
|
2240
|
-
const escapedFontPreloads = escapeTemplateLiteral3(fontPreloads);
|
|
2241
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
2242
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral3(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral3(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral3(libraryTags.bodyEndJS || "")}\` }`;
|
|
2243
|
-
const wrapFn = "r";
|
|
2244
|
-
const staticPaths = buildGetStaticPaths(cmsSchema, isMultiLocale, i18nConfig, locale);
|
|
2245
|
-
const titleExpr = transformTitleExpression(title, binding, richTextFields, wrapFn);
|
|
2246
|
-
const resolverHelper = `function r(v) {
|
|
2247
|
-
if (v && typeof v === 'object' && v._i18n) return v['${locale}'] ?? v['${i18nConfig.defaultLocale}'] ?? Object.values(v).find(x => x !== true && x !== undefined) ?? '';
|
|
2248
|
-
return v ?? '';
|
|
2249
|
-
}`;
|
|
2250
|
-
return `---
|
|
2251
|
-
import { getCollection } from 'astro:content';
|
|
2252
|
-
import BaseLayout from '${layoutImport}';
|
|
2253
|
-
|
|
2254
|
-
${staticPaths}
|
|
2255
|
-
|
|
2256
|
-
${resolverHelper}
|
|
2257
|
-
---
|
|
2258
|
-
<BaseLayout
|
|
2259
|
-
title=${titleExpr}
|
|
2260
|
-
meta={\`${escapedMeta}\`}
|
|
2261
|
-
scripts={${scriptsArrayLiteral}}
|
|
2262
|
-
locale="${locale}"
|
|
2263
|
-
theme="${theme}"
|
|
2264
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
2265
|
-
libraryTags={${libraryTagsLiteral}}
|
|
2266
|
-
>
|
|
2267
|
-
</BaseLayout>
|
|
2268
|
-
`;
|
|
2269
|
-
}
|
|
2270
|
-
|
|
2271
|
-
// lib/server/astro/cssCollector.ts
|
|
2272
|
-
function isStyleMapping3(value) {
|
|
2273
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
2274
|
-
}
|
|
2275
|
-
function isResponsiveStyle3(style) {
|
|
2276
|
-
return "base" in style || "tablet" in style || "mobile" in style;
|
|
2277
|
-
}
|
|
2278
|
-
function collectFromStyle(style, classes, breakpoints) {
|
|
2279
|
-
if (!style) return;
|
|
2280
|
-
if (isResponsiveStyle3(style)) {
|
|
2281
|
-
for (const [bp, bpStyle] of Object.entries(style)) {
|
|
2282
|
-
if (!bpStyle) continue;
|
|
2283
|
-
let prefix = "";
|
|
2284
|
-
if (bp !== "base") {
|
|
2285
|
-
const bpValue = breakpoints[bp]?.breakpoint;
|
|
2286
|
-
if (bpValue) {
|
|
2287
|
-
prefix = `max-[${bpValue}px]:`;
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
collectFromFlatStyle(bpStyle, prefix, classes);
|
|
2291
|
-
}
|
|
2292
|
-
} else {
|
|
2293
|
-
collectFromFlatStyle(style, "", classes);
|
|
2294
|
-
}
|
|
2295
|
-
}
|
|
2296
|
-
function collectFromFlatStyle(style, prefix, classes) {
|
|
2297
|
-
for (const [property, value] of Object.entries(style)) {
|
|
2298
|
-
if (!isStyleMapping3(value)) continue;
|
|
2299
|
-
for (const [, cssValue] of Object.entries(value.values)) {
|
|
2300
|
-
const twClass = propertyToTailwind(property, cssValue);
|
|
2301
|
-
if (twClass) {
|
|
2302
|
-
classes.add(prefix ? `${prefix}${twClass}` : twClass);
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
function walkNode(node, classes, breakpoints) {
|
|
2308
|
-
if (!node || typeof node === "string" || typeof node === "number") return;
|
|
2309
|
-
if (Array.isArray(node)) {
|
|
2310
|
-
for (const child of node) {
|
|
2311
|
-
walkNode(child, classes, breakpoints);
|
|
2312
|
-
}
|
|
2313
|
-
return;
|
|
2314
|
-
}
|
|
2315
|
-
if ("style" in node && node.style) {
|
|
2316
|
-
collectFromStyle(node.style, classes, breakpoints);
|
|
2317
|
-
}
|
|
2318
|
-
if ("interactiveStyles" in node && Array.isArray(node.interactiveStyles)) {
|
|
2319
|
-
for (const rule of node.interactiveStyles) {
|
|
2320
|
-
if (rule.style) {
|
|
2321
|
-
collectFromStyle(rule.style, classes, breakpoints);
|
|
2322
|
-
}
|
|
2323
|
-
}
|
|
2324
|
-
}
|
|
2325
|
-
if ("children" in node && node.children) {
|
|
2326
|
-
if (Array.isArray(node.children)) {
|
|
2327
|
-
for (const child of node.children) {
|
|
2328
|
-
walkNode(child, classes, breakpoints);
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
}
|
|
2333
|
-
function collectAllMappingClasses(componentDefs, breakpoints = DEFAULT_BREAKPOINTS) {
|
|
2334
|
-
const classes = /* @__PURE__ */ new Set();
|
|
2335
|
-
for (const def of Object.values(componentDefs)) {
|
|
2336
|
-
const structure = def.component?.structure;
|
|
2337
|
-
if (structure) {
|
|
2338
|
-
walkNode(structure, classes, breakpoints);
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
return classes;
|
|
2342
|
-
}
|
|
2343
|
-
|
|
2344
|
-
// build-astro.ts
|
|
2345
|
-
function hashContent2(content) {
|
|
2346
|
-
return createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
2347
|
-
}
|
|
2348
|
-
function copyDirectory(src, dest) {
|
|
2349
|
-
if (!existsSync(src)) return;
|
|
2350
|
-
if (!existsSync(dest)) mkdirSync(dest, { recursive: true });
|
|
2351
|
-
const files = readdirSync(src);
|
|
2352
|
-
for (const file of files) {
|
|
2353
|
-
const srcPath = join(src, file);
|
|
2354
|
-
const destPath = join(dest, file);
|
|
2355
|
-
const stat = statSync(srcPath);
|
|
2356
|
-
if (stat.isDirectory()) copyDirectory(srcPath, destPath);
|
|
2357
|
-
else copyFileSync(srcPath, destPath);
|
|
2358
|
-
}
|
|
2359
|
-
}
|
|
2360
|
-
function isCMSPage(pageData) {
|
|
2361
|
-
return pageData.meta?.source === "cms" && !!pageData.meta?.cms;
|
|
2362
|
-
}
|
|
2363
|
-
function scanJSONFiles(dir, prefix = "") {
|
|
2364
|
-
const results = [];
|
|
2365
|
-
if (!existsSync(dir)) return results;
|
|
2366
|
-
const entries = readdirSync(dir, { withFileTypes: true });
|
|
2367
|
-
for (const entry of entries) {
|
|
2368
|
-
if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
2369
|
-
results.push(prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
2370
|
-
} else if (entry.isDirectory()) {
|
|
2371
|
-
results.push(...scanJSONFiles(join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name));
|
|
2372
|
-
}
|
|
2373
|
-
}
|
|
2374
|
-
return results;
|
|
2375
|
-
}
|
|
2376
|
-
function layoutImportPath(fileDepth) {
|
|
2377
|
-
const ups = "../".repeat(fileDepth + 1);
|
|
2378
|
-
return `${ups}layouts/BaseLayout.astro`;
|
|
2379
|
-
}
|
|
2380
|
-
function escapeTemplateLiteral4(s) {
|
|
2381
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
2382
|
-
}
|
|
2383
|
-
function computePageSlugMap(slugs, i18nConfig) {
|
|
2384
|
-
const map = {};
|
|
2385
|
-
for (const localeConfig of i18nConfig.locales) {
|
|
2386
|
-
const code = localeConfig.code;
|
|
2387
|
-
const isDefault = code === i18nConfig.defaultLocale;
|
|
2388
|
-
const slug = slugs[code] || "";
|
|
2389
|
-
if (isDefault) {
|
|
2390
|
-
map[code] = slug === "" ? "/" : `/${slug}`;
|
|
2391
|
-
} else {
|
|
2392
|
-
map[code] = slug === "" ? `/${code}` : `/${code}/${slug}`;
|
|
2393
|
-
}
|
|
2394
|
-
}
|
|
2395
|
-
return map;
|
|
2396
|
-
}
|
|
2397
|
-
function cmsFieldToZod(field) {
|
|
2398
|
-
switch (field.type) {
|
|
2399
|
-
case "string":
|
|
2400
|
-
case "text":
|
|
2401
|
-
case "rich-text":
|
|
2402
|
-
return "z.union([z.string(), z.object({ _i18n: z.literal(true) }).passthrough()])";
|
|
2403
|
-
case "number":
|
|
2404
|
-
return "z.number()";
|
|
2405
|
-
case "boolean":
|
|
2406
|
-
return "z.boolean()";
|
|
2407
|
-
case "date":
|
|
2408
|
-
return "z.coerce.date()";
|
|
2409
|
-
case "select":
|
|
2410
|
-
if (field.options && field.options.length > 0) {
|
|
2411
|
-
const opts = field.options.map((o) => `'${o.replace(/'/g, "\\'")}'`).join(", ");
|
|
2412
|
-
return `z.enum([${opts}])`;
|
|
2413
|
-
}
|
|
2414
|
-
return "z.string()";
|
|
2415
|
-
case "image":
|
|
2416
|
-
case "file":
|
|
2417
|
-
return "z.string()";
|
|
2418
|
-
case "reference":
|
|
2419
|
-
return "z.string()";
|
|
2420
|
-
default:
|
|
2421
|
-
return "z.string()";
|
|
2422
|
-
}
|
|
2423
|
-
}
|
|
2424
|
-
function buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths) {
|
|
2425
|
-
const escapedMeta = escapeTemplateLiteral4(result.meta);
|
|
2426
|
-
const escapedHTML = escapeTemplateLiteral4(result.html);
|
|
2427
|
-
const escapedFontPreloads = escapeTemplateLiteral4(fontPreloads);
|
|
2428
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
2429
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral4(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral4(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral4(libraryTags.bodyEndJS || "")}\` }`;
|
|
2430
|
-
return `---
|
|
2431
|
-
import BaseLayout from '${importPath}';
|
|
2432
|
-
---
|
|
2433
|
-
<BaseLayout
|
|
2434
|
-
title="${result.title.replace(/"/g, """)}"
|
|
2435
|
-
meta={\`${escapedMeta}\`}
|
|
2436
|
-
scripts={${scriptsArrayLiteral}}
|
|
2437
|
-
locale="${result.locale}"
|
|
2438
|
-
theme="${defaultTheme}"
|
|
2439
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
2440
|
-
libraryTags={${libraryTagsLiteral}}
|
|
2441
|
-
>
|
|
2442
|
-
<Fragment set:html={\`<div id="root">${escapedHTML}</div>\`} />
|
|
2443
|
-
</BaseLayout>
|
|
2444
|
-
`;
|
|
2445
|
-
}
|
|
2446
|
-
async function buildAstroProject(projectRoot, outputDir) {
|
|
2447
|
-
const startTime = Date.now();
|
|
2448
|
-
console.log("\u{1F3D7}\uFE0F Building Astro export...\n");
|
|
2449
|
-
configService.reset();
|
|
2450
|
-
const projectConfig = await loadProjectConfig();
|
|
2451
|
-
const siteUrl = projectConfig.siteUrl?.replace(/\/$/, "") || "";
|
|
2452
|
-
const i18nConfig = await loadI18nConfig();
|
|
2453
|
-
console.log(`\u{1F310} Locales: ${i18nConfig.locales.map((l) => l.code).join(", ")} (default: ${i18nConfig.defaultLocale})
|
|
2454
|
-
`);
|
|
2455
|
-
await migrateTemplatesDirectory();
|
|
2456
|
-
const { components, warnings, errors: compErrors } = await loadComponentDirectory(projectPaths.components());
|
|
2457
|
-
const globalComponents = {};
|
|
2458
|
-
components.forEach((value, key) => {
|
|
2459
|
-
globalComponents[key] = value;
|
|
2460
|
-
});
|
|
2461
|
-
for (const w of warnings) console.warn(` Warning: ${w}`);
|
|
2462
|
-
for (const e of compErrors) console.error(` Error: ${e}`);
|
|
2463
|
-
console.log(`Loaded ${components.size} global component(s)
|
|
2464
|
-
`);
|
|
2465
|
-
const cmsProvider = new FileSystemCMSProvider(projectPaths.templates(), projectPaths.cms());
|
|
2466
|
-
const cmsService = new CMSService(cmsProvider);
|
|
2467
|
-
await cmsService.initialize();
|
|
2468
|
-
console.log("CMS service initialized\n");
|
|
2469
|
-
const themeConfig = await colorService.loadThemeConfig();
|
|
2470
|
-
const variablesConfig = await variableService.loadConfig();
|
|
2471
|
-
const breakpoints = await loadBreakpointConfig();
|
|
2472
|
-
const responsiveScales = await loadResponsiveScalesConfig();
|
|
2473
|
-
await configService.load();
|
|
2474
|
-
const globalLibraries = configService.getLibraries();
|
|
2475
|
-
const componentLibraries = collectComponentLibraries(globalComponents);
|
|
2476
|
-
const imageMetadataMap = await buildImageMetadataMap();
|
|
2477
|
-
if (imageMetadataMap.size > 0) {
|
|
2478
|
-
console.log(`Loaded image metadata for ${imageMetadataMap.size} image(s)
|
|
2479
|
-
`);
|
|
2480
|
-
}
|
|
2481
|
-
const outDir = outputDir || join(projectPaths.project, "astro-export");
|
|
2482
|
-
if (existsSync(outDir)) {
|
|
2483
|
-
rmSync(outDir, { recursive: true, force: true });
|
|
2484
|
-
}
|
|
2485
|
-
mkdirSync(outDir, { recursive: true });
|
|
2486
|
-
const srcDir = join(outDir, "src");
|
|
2487
|
-
const pagesOutDir = join(srcDir, "pages");
|
|
2488
|
-
const layoutsDir = join(srcDir, "layouts");
|
|
2489
|
-
const stylesDir = join(srcDir, "styles");
|
|
2490
|
-
const componentsOutDir = join(srcDir, "components");
|
|
2491
|
-
const publicDir = join(outDir, "public");
|
|
2492
|
-
const scriptsDir = join(publicDir, "_scripts");
|
|
2493
|
-
for (const d of [srcDir, pagesOutDir, layoutsDir, stylesDir, componentsOutDir, publicDir]) {
|
|
2494
|
-
mkdirSync(d, { recursive: true });
|
|
2495
|
-
}
|
|
2496
|
-
const pagesDir = projectPaths.pages();
|
|
2497
|
-
if (!existsSync(pagesDir)) {
|
|
2498
|
-
console.error("Pages directory not found!");
|
|
2499
|
-
return { pages: 0, cmsPages: 0, collections: 0, errors: 1 };
|
|
2500
|
-
}
|
|
2501
|
-
const pageFiles = scanJSONFiles(pagesDir);
|
|
2502
|
-
if (pageFiles.length === 0) {
|
|
2503
|
-
console.warn("No pages found in ./pages directory");
|
|
2504
|
-
return { pages: 0, cmsPages: 0, collections: 0, errors: 0 };
|
|
2505
|
-
}
|
|
2506
|
-
console.log(`Found ${pageFiles.length} page(s) to process
|
|
2507
|
-
`);
|
|
2508
|
-
const slugMappings = [];
|
|
2509
|
-
for (const file of pageFiles) {
|
|
2510
|
-
const pageName = file.replace(".json", "");
|
|
2511
|
-
const basePath = mapPageNameToPath(pageName);
|
|
2512
|
-
const pageContent = await loadJSONFile(join(pagesDir, file));
|
|
2513
|
-
if (!pageContent) continue;
|
|
2514
|
-
try {
|
|
2515
|
-
const pageData = parseJSON(pageContent);
|
|
2516
|
-
if (pageData.meta?.slugs) {
|
|
2517
|
-
const pageId = basePath === "/" ? "index" : basePath.substring(1);
|
|
2518
|
-
slugMappings.push({ pageId, slugs: pageData.meta.slugs });
|
|
2519
|
-
}
|
|
2520
|
-
} catch {
|
|
2521
|
-
}
|
|
2522
|
-
}
|
|
2523
|
-
const allResults = [];
|
|
2524
|
-
const allInteractiveStyles = /* @__PURE__ */ new Map();
|
|
2525
|
-
const allComponentCSS = /* @__PURE__ */ new Set();
|
|
2526
|
-
const jsContents = /* @__PURE__ */ new Map();
|
|
2527
|
-
let errorCount = 0;
|
|
2528
|
-
function mergeInteractiveStyles(source) {
|
|
2529
|
-
for (const [key, value] of source) {
|
|
2530
|
-
if (!allInteractiveStyles.has(key)) {
|
|
2531
|
-
allInteractiveStyles.set(key, value);
|
|
2532
|
-
}
|
|
2533
|
-
}
|
|
2534
|
-
}
|
|
2535
|
-
function processRenderResult(result, urlPath, astroFilePath, fileDepth, pageData, pageName, isCMSPage3) {
|
|
2536
|
-
mergeInteractiveStyles(result.interactiveStylesMap);
|
|
2537
|
-
if (result.componentCSS) {
|
|
2538
|
-
allComponentCSS.add(result.componentCSS);
|
|
2539
|
-
}
|
|
2540
|
-
if (result.javascript) {
|
|
2541
|
-
const hash = hashContent2(result.javascript);
|
|
2542
|
-
if (!jsContents.has(hash)) {
|
|
2543
|
-
jsContents.set(hash, result.javascript);
|
|
2544
|
-
}
|
|
2545
|
-
}
|
|
2546
|
-
allResults.push({
|
|
2547
|
-
html: result.html,
|
|
2548
|
-
meta: result.meta,
|
|
2549
|
-
title: result.title,
|
|
2550
|
-
javascript: result.javascript,
|
|
2551
|
-
componentCSS: result.componentCSS,
|
|
2552
|
-
locale: result.locale,
|
|
2553
|
-
interactiveStylesMap: result.interactiveStylesMap,
|
|
2554
|
-
urlPath,
|
|
2555
|
-
fileDepth,
|
|
2556
|
-
astroFilePath,
|
|
2557
|
-
pageData,
|
|
2558
|
-
pageName,
|
|
2559
|
-
isCMSPage: isCMSPage3,
|
|
2560
|
-
ssrFallbackCollector: result.ssrFallbackCollector
|
|
2561
|
-
});
|
|
2562
|
-
}
|
|
2563
|
-
for (const file of pageFiles) {
|
|
2564
|
-
const pageName = file.replace(".json", "");
|
|
2565
|
-
const basePath = mapPageNameToPath(pageName);
|
|
2566
|
-
const pageContent = await loadJSONFile(join(pagesDir, file));
|
|
2567
|
-
if (!pageContent) {
|
|
2568
|
-
console.warn(` Skipping ${basePath} (empty file)`);
|
|
2569
|
-
errorCount++;
|
|
2570
|
-
continue;
|
|
2571
|
-
}
|
|
2572
|
-
try {
|
|
2573
|
-
const pageData = parseJSON(pageContent);
|
|
2574
|
-
const isDevBuild = process.env.MENO_DEV_BUILD === "true";
|
|
2575
|
-
if (pageData.meta?.draft === true && !isDevBuild) {
|
|
2576
|
-
console.log(` Skipping draft: ${basePath}`);
|
|
2577
|
-
continue;
|
|
2578
|
-
}
|
|
2579
|
-
const slugs = pageData.meta?.slugs;
|
|
2580
|
-
for (const localeConfig of i18nConfig.locales) {
|
|
2581
|
-
const locale = localeConfig.code;
|
|
2582
|
-
const isDefault = locale === i18nConfig.defaultLocale;
|
|
2583
|
-
let slug;
|
|
2584
|
-
if (slugs && slugs[locale]) {
|
|
2585
|
-
slug = slugs[locale];
|
|
2586
|
-
} else if (basePath === "/") {
|
|
2587
|
-
slug = "";
|
|
2588
|
-
} else {
|
|
2589
|
-
slug = basePath.substring(1);
|
|
2590
|
-
}
|
|
2591
|
-
const urlPath = isDefault ? slug === "" ? "/" : `/${slug}` : slug === "" ? `/${locale}` : `/${locale}/${slug}`;
|
|
2592
|
-
const astroFileName = slug === "" ? "index.astro" : `${slug}.astro`;
|
|
2593
|
-
const astroFilePath = isDefault ? astroFileName : `${locale}/${astroFileName}`;
|
|
2594
|
-
const fileDepth = astroFilePath.split("/").length - 1;
|
|
2595
|
-
const result = await renderPageSSR(
|
|
2596
|
-
pageData,
|
|
2597
|
-
globalComponents,
|
|
2598
|
-
urlPath,
|
|
2599
|
-
siteUrl,
|
|
2600
|
-
locale,
|
|
2601
|
-
i18nConfig,
|
|
2602
|
-
slugMappings,
|
|
2603
|
-
void 0,
|
|
2604
|
-
// cmsContext
|
|
2605
|
-
cmsService,
|
|
2606
|
-
true
|
|
2607
|
-
// isProductionBuild
|
|
2608
|
-
);
|
|
2609
|
-
processRenderResult(result, urlPath, astroFilePath, fileDepth, pageData, pageName, false);
|
|
2610
|
-
console.log(` Rendered: ${urlPath}`);
|
|
2611
|
-
}
|
|
2612
|
-
} catch (error) {
|
|
2613
|
-
console.error(` Error rendering ${basePath}:`, error?.message || error);
|
|
2614
|
-
errorCount++;
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
|
-
const fontPreloads = generateFontPreloadTags();
|
|
2618
|
-
const mergedLibraries = mergeLibraries(globalLibraries, componentLibraries);
|
|
2619
|
-
const buildLibraries = filterLibrariesByContext(mergedLibraries, "build");
|
|
2620
|
-
const libraryTags = generateLibraryTags(buildLibraries);
|
|
2621
|
-
const defaultTheme = themeConfig.default || "light";
|
|
2622
|
-
const templatesDir = projectPaths.templates();
|
|
2623
|
-
const templateSchemas = [];
|
|
2624
|
-
let cmsPageCount = 0;
|
|
2625
|
-
if (existsSync(templatesDir)) {
|
|
2626
|
-
const templateFiles = readdirSync(templatesDir).filter((f) => f.endsWith(".json"));
|
|
2627
|
-
if (templateFiles.length > 0) {
|
|
2628
|
-
console.log(`
|
|
2629
|
-
Processing ${templateFiles.length} CMS template(s)...
|
|
2630
|
-
`);
|
|
2631
|
-
}
|
|
2632
|
-
for (const file of templateFiles) {
|
|
2633
|
-
const templateContent = await loadJSONFile(join(templatesDir, file));
|
|
2634
|
-
if (!templateContent) continue;
|
|
2635
|
-
try {
|
|
2636
|
-
const pageData = parseJSON(templateContent);
|
|
2637
|
-
const isDevBuild = process.env.MENO_DEV_BUILD === "true";
|
|
2638
|
-
if (pageData.meta?.draft === true && !isDevBuild) {
|
|
2639
|
-
console.log(` Skipping draft template: ${file}`);
|
|
2640
|
-
continue;
|
|
2641
|
-
}
|
|
2642
|
-
if (!isCMSPage(pageData)) {
|
|
2643
|
-
console.warn(` ${file} is in templates/ but missing meta.source: "cms"`);
|
|
2644
|
-
continue;
|
|
2645
|
-
}
|
|
2646
|
-
const cmsSchema = pageData.meta.cms;
|
|
2647
|
-
templateSchemas.push(cmsSchema);
|
|
2648
|
-
console.log(` CMS Collection: ${cmsSchema.id}`);
|
|
2649
|
-
const items = await cmsService.queryItems({ collection: cmsSchema.id });
|
|
2650
|
-
const itemCount = items.length;
|
|
2651
|
-
if (itemCount === 0) {
|
|
2652
|
-
console.log(` No items found in cms/${cmsSchema.id}/`);
|
|
2653
|
-
} else {
|
|
2654
|
-
console.log(` Found ${itemCount} item(s)`);
|
|
2655
|
-
}
|
|
2656
|
-
const defaultLocale = i18nConfig.defaultLocale;
|
|
2657
|
-
const dummyPath = cmsSchema.urlPattern.replace("{{slug}}", "__placeholder__");
|
|
2658
|
-
const metaResult = await renderPageSSR(
|
|
2659
|
-
pageData,
|
|
2660
|
-
globalComponents,
|
|
2661
|
-
dummyPath,
|
|
2662
|
-
siteUrl,
|
|
2663
|
-
defaultLocale,
|
|
2664
|
-
i18nConfig,
|
|
2665
|
-
slugMappings,
|
|
2666
|
-
void 0,
|
|
2667
|
-
// no CMS context - just collecting metadata
|
|
2668
|
-
cmsService,
|
|
2669
|
-
true
|
|
2670
|
-
);
|
|
2671
|
-
mergeInteractiveStyles(metaResult.interactiveStylesMap);
|
|
2672
|
-
if (metaResult.componentCSS) {
|
|
2673
|
-
allComponentCSS.add(metaResult.componentCSS);
|
|
2674
|
-
}
|
|
2675
|
-
const scriptPaths = [];
|
|
2676
|
-
if (metaResult.javascript) {
|
|
2677
|
-
const hash = hashContent2(metaResult.javascript);
|
|
2678
|
-
if (!jsContents.has(hash)) {
|
|
2679
|
-
jsContents.set(hash, metaResult.javascript);
|
|
2680
|
-
}
|
|
2681
|
-
scriptPaths.push(`/_scripts/${hash}.js`);
|
|
2682
|
-
}
|
|
2683
|
-
const isMultiLocale = i18nConfig.locales.length > 1;
|
|
2684
|
-
const urlPatternWithoutSlash = cmsSchema.urlPattern.replace(/^\//, "");
|
|
2685
|
-
const slugPlaceholderIdx = urlPatternWithoutSlash.indexOf("{{");
|
|
2686
|
-
const pathPrefix = slugPlaceholderIdx > 0 ? urlPatternWithoutSlash.substring(0, slugPlaceholderIdx) : "";
|
|
2687
|
-
const ssrFallbacks = metaResult.ssrFallbackCollector ?? /* @__PURE__ */ new Map();
|
|
2688
|
-
const localesToEmit = isMultiLocale ? i18nConfig.locales : [{ code: i18nConfig.defaultLocale }];
|
|
2689
|
-
for (const localeEntry of localesToEmit) {
|
|
2690
|
-
const localeCode = localeEntry.code;
|
|
2691
|
-
const isDefault = localeCode === i18nConfig.defaultLocale;
|
|
2692
|
-
let astroFilePath;
|
|
2693
|
-
if (pathPrefix) {
|
|
2694
|
-
astroFilePath = isDefault ? `${pathPrefix}[slug].astro` : `${localeCode}/${pathPrefix}[slug].astro`;
|
|
2695
|
-
} else {
|
|
2696
|
-
astroFilePath = isDefault ? "[slug].astro" : `${localeCode}/[slug].astro`;
|
|
2697
|
-
}
|
|
2698
|
-
const fileDepth = astroFilePath.split("/").length - 1;
|
|
2699
|
-
const importPath = layoutImportPath(fileDepth);
|
|
2700
|
-
const astroContent = emitCMSPage({
|
|
2701
|
-
pageData,
|
|
2702
|
-
globalComponents,
|
|
2703
|
-
cmsSchema,
|
|
2704
|
-
title: String(pageData.meta?.title || cmsSchema.name),
|
|
2705
|
-
meta: metaResult.meta,
|
|
2706
|
-
locale: localeCode,
|
|
2707
|
-
theme: defaultTheme,
|
|
2708
|
-
fontPreloads,
|
|
2709
|
-
libraryTags,
|
|
2710
|
-
scriptPaths,
|
|
2711
|
-
layoutImportPath: importPath,
|
|
2712
|
-
fileDepth,
|
|
2713
|
-
ssrFallbacks,
|
|
2714
|
-
pageName: file.replace(".json", ""),
|
|
2715
|
-
breakpoints,
|
|
2716
|
-
imageMetadataMap,
|
|
2717
|
-
i18nConfig,
|
|
2718
|
-
isMultiLocale: false,
|
|
2719
|
-
// Each file handles one locale
|
|
2720
|
-
slugMappings
|
|
2721
|
-
});
|
|
2722
|
-
const astroFileFull = join(pagesOutDir, astroFilePath);
|
|
2723
|
-
const astroFileDir = astroFileFull.substring(0, astroFileFull.lastIndexOf("/"));
|
|
2724
|
-
if (!existsSync(astroFileDir)) {
|
|
2725
|
-
mkdirSync(astroFileDir, { recursive: true });
|
|
2726
|
-
}
|
|
2727
|
-
await writeFile2(astroFileFull, astroContent, "utf-8");
|
|
2728
|
-
}
|
|
2729
|
-
console.log(` Generated: ${pathPrefix}[slug].astro (${itemCount} items \xD7 ${localesToEmit.length} locale(s))`);
|
|
2730
|
-
cmsPageCount += itemCount * i18nConfig.locales.length;
|
|
2731
|
-
} catch (error) {
|
|
2732
|
-
console.error(` Error processing template ${file}:`, error?.message || error);
|
|
2733
|
-
errorCount++;
|
|
2734
|
-
}
|
|
2735
|
-
}
|
|
2736
|
-
}
|
|
2737
|
-
const mappingClasses = collectAllMappingClasses(globalComponents, breakpoints);
|
|
2738
|
-
const fontCSS = generateFontCSS();
|
|
2739
|
-
const themeColorCSS = generateThemeColorVariablesCSS(themeConfig);
|
|
2740
|
-
const variablesCSS = generateVariablesCSS(variablesConfig, breakpoints, responsiveScales);
|
|
2741
|
-
const interactiveCSS = generateAllInteractiveCSS(allInteractiveStyles, breakpoints);
|
|
2742
|
-
const componentCSSCombined = Array.from(allComponentCSS).join("\n");
|
|
2743
|
-
const baseCSS = `@layer base {
|
|
2744
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
2745
|
-
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif; }
|
|
2746
|
-
button { background: none; border: none; padding: 0; font: inherit; cursor: pointer; outline: inherit; }
|
|
2747
|
-
img { display: block; width: 100%; height: 100%; }
|
|
2748
|
-
picture { display: block; }
|
|
2749
|
-
.olink { text-decoration: none; display: block; }
|
|
2750
|
-
.oem { display: inline-block; }
|
|
2751
|
-
}`;
|
|
2752
|
-
const tailwindDirectives = `@tailwind base;
|
|
2753
|
-
@tailwind components;
|
|
2754
|
-
@tailwind utilities;`;
|
|
2755
|
-
const globalCSS = [tailwindDirectives, fontCSS, themeColorCSS, variablesCSS, baseCSS, componentCSSCombined, interactiveCSS].filter(Boolean).join("\n\n");
|
|
2756
|
-
await writeFile2(join(stylesDir, "global.css"), globalCSS, "utf-8");
|
|
2757
|
-
console.log(`
|
|
2758
|
-
Generated global.css (${(globalCSS.length / 1024).toFixed(1)} KB)`);
|
|
2759
|
-
const baseLayoutContent = `---
|
|
2760
|
-
import '../styles/global.css';
|
|
2761
|
-
|
|
2762
|
-
interface Props {
|
|
2763
|
-
title: string;
|
|
2764
|
-
meta?: string;
|
|
2765
|
-
scripts?: string[];
|
|
2766
|
-
locale?: string;
|
|
2767
|
-
theme?: string;
|
|
2768
|
-
fontPreloads?: string;
|
|
2769
|
-
libraryTags?: { headCSS?: string; headJS?: string; bodyEndJS?: string };
|
|
2770
|
-
}
|
|
2771
|
-
|
|
2772
|
-
const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.default || "light"}', fontPreloads = '', libraryTags = {} } = Astro.props;
|
|
2773
|
-
---
|
|
2774
|
-
<!DOCTYPE html>
|
|
2775
|
-
<html lang={locale} data-theme={theme}>
|
|
2776
|
-
<head>
|
|
2777
|
-
<meta charset="UTF-8">
|
|
2778
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2779
|
-
<Fragment set:html={fontPreloads} />
|
|
2780
|
-
<Fragment set:html={libraryTags.headCSS || ''} />
|
|
2781
|
-
<Fragment set:html={libraryTags.headJS || ''} />
|
|
2782
|
-
<Fragment set:html={meta} />
|
|
2783
|
-
<title>{title}</title>
|
|
2784
|
-
</head>
|
|
2785
|
-
<body>
|
|
2786
|
-
<slot />
|
|
2787
|
-
{scripts.map((s) => <script src={s} />)}
|
|
2788
|
-
<Fragment set:html={libraryTags.bodyEndJS || ''} />
|
|
2789
|
-
</body>
|
|
2790
|
-
</html>
|
|
2791
|
-
`;
|
|
2792
|
-
await writeFile2(join(layoutsDir, "BaseLayout.astro"), baseLayoutContent, "utf-8");
|
|
2793
|
-
console.log("Generated BaseLayout.astro");
|
|
2794
|
-
let componentFileCount = 0;
|
|
2795
|
-
for (const [compName, compDef] of Object.entries(globalComponents)) {
|
|
2796
|
-
try {
|
|
2797
|
-
const astroContent = emitAstroComponent(compName, compDef, globalComponents, breakpoints, i18nConfig.defaultLocale);
|
|
2798
|
-
await writeFile2(join(componentsOutDir, `${compName}.astro`), astroContent, "utf-8");
|
|
2799
|
-
componentFileCount++;
|
|
2800
|
-
} catch (error) {
|
|
2801
|
-
console.warn(` Warning: could not generate component ${compName}: ${error?.message}`);
|
|
2802
|
-
}
|
|
2803
|
-
}
|
|
2804
|
-
console.log(`Generated ${componentFileCount} component .astro file(s)`);
|
|
2805
|
-
const allFallbackHtml = [];
|
|
2806
|
-
for (const result of allResults) {
|
|
2807
|
-
const importPath = layoutImportPath(result.fileDepth);
|
|
2808
|
-
const scriptPaths = [];
|
|
2809
|
-
if (result.javascript) {
|
|
2810
|
-
const hash = hashContent2(result.javascript);
|
|
2811
|
-
const scriptFile = `${hash}.js`;
|
|
2812
|
-
const scriptPublicPath = `/_scripts/${scriptFile}`;
|
|
2813
|
-
if (!existsSync(scriptsDir)) {
|
|
2814
|
-
mkdirSync(scriptsDir, { recursive: true });
|
|
2815
|
-
}
|
|
2816
|
-
const fullScriptPath = join(scriptsDir, scriptFile);
|
|
2817
|
-
if (!existsSync(fullScriptPath)) {
|
|
2818
|
-
await writeFile2(fullScriptPath, result.javascript, "utf-8");
|
|
2819
|
-
}
|
|
2820
|
-
scriptPaths.push(scriptPublicPath);
|
|
2821
|
-
}
|
|
2822
|
-
let astroContent;
|
|
2823
|
-
if (result.pageData) {
|
|
2824
|
-
try {
|
|
2825
|
-
const ssrFallbacks = result.ssrFallbackCollector ?? /* @__PURE__ */ new Map();
|
|
2826
|
-
ssrFallbacks.forEach((html) => {
|
|
2827
|
-
allFallbackHtml.push(html);
|
|
2828
|
-
});
|
|
2829
|
-
const pageSlugMap = result.pageData.meta?.slugs ? computePageSlugMap(result.pageData.meta.slugs, i18nConfig) : void 0;
|
|
2830
|
-
astroContent = emitAstroPage({
|
|
2831
|
-
pageData: result.pageData,
|
|
2832
|
-
globalComponents,
|
|
2833
|
-
title: result.title,
|
|
2834
|
-
meta: result.meta,
|
|
2835
|
-
locale: result.locale,
|
|
2836
|
-
theme: defaultTheme,
|
|
2837
|
-
fontPreloads,
|
|
2838
|
-
libraryTags,
|
|
2839
|
-
scriptPaths,
|
|
2840
|
-
layoutImportPath: importPath,
|
|
2841
|
-
fileDepth: result.fileDepth,
|
|
2842
|
-
ssrFallbacks,
|
|
2843
|
-
pageName: result.pageName || "index",
|
|
2844
|
-
breakpoints,
|
|
2845
|
-
imageMetadataMap,
|
|
2846
|
-
i18nConfig: i18nConfig.locales.length > 1 ? i18nConfig : void 0,
|
|
2847
|
-
currentPageSlugMap: pageSlugMap,
|
|
2848
|
-
slugMappings: i18nConfig.locales.length > 1 ? slugMappings : void 0
|
|
2849
|
-
});
|
|
2850
|
-
} catch (error) {
|
|
2851
|
-
console.warn(` Warning: component emission failed for ${result.urlPath}, using SSR fallback: ${error?.message}`);
|
|
2852
|
-
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
2853
|
-
}
|
|
2854
|
-
} else {
|
|
2855
|
-
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
2856
|
-
allFallbackHtml.push(result.html);
|
|
2857
|
-
}
|
|
2858
|
-
const astroFileFull = join(pagesOutDir, result.astroFilePath);
|
|
2859
|
-
const astroFileDir = astroFileFull.substring(0, astroFileFull.lastIndexOf("/"));
|
|
2860
|
-
if (!existsSync(astroFileDir)) {
|
|
2861
|
-
mkdirSync(astroFileDir, { recursive: true });
|
|
2862
|
-
}
|
|
2863
|
-
await writeFile2(astroFileFull, astroContent, "utf-8");
|
|
2864
|
-
}
|
|
2865
|
-
console.log(`Generated ${allResults.length} .astro page file(s)`);
|
|
2866
|
-
if (allFallbackHtml.length > 0) {
|
|
2867
|
-
const allClasses = /* @__PURE__ */ new Set();
|
|
2868
|
-
for (const html of allFallbackHtml) {
|
|
2869
|
-
for (const cls of extractUtilityClassesFromHTML(html)) {
|
|
2870
|
-
allClasses.add(cls);
|
|
2871
|
-
}
|
|
2872
|
-
}
|
|
2873
|
-
if (allClasses.size > 0) {
|
|
2874
|
-
const utilityCSS = generateUtilityCSS(allClasses, breakpoints, responsiveScales);
|
|
2875
|
-
if (utilityCSS) {
|
|
2876
|
-
const existingCSS = await readFile(join(stylesDir, "global.css"), "utf-8");
|
|
2877
|
-
await writeFile2(join(stylesDir, "global.css"), existingCSS + "\n\n/* SSR fallback utility classes */\n" + utilityCSS, "utf-8");
|
|
2878
|
-
console.log(`Added ${allClasses.size} utility classes for SSR fallback content`);
|
|
2879
|
-
}
|
|
2880
|
-
}
|
|
2881
|
-
}
|
|
2882
|
-
let collectionCount = 0;
|
|
2883
|
-
if (templateSchemas.length > 0) {
|
|
2884
|
-
const contentDir = join(srcDir, "content");
|
|
2885
|
-
mkdirSync(contentDir, { recursive: true });
|
|
2886
|
-
const collectionDefs = [];
|
|
2887
|
-
for (const schema of templateSchemas) {
|
|
2888
|
-
const collectionDir = join(contentDir, schema.id);
|
|
2889
|
-
mkdirSync(collectionDir, { recursive: true });
|
|
2890
|
-
const cmsItemsDir = join(projectPaths.cms(), schema.id);
|
|
2891
|
-
if (existsSync(cmsItemsDir)) {
|
|
2892
|
-
const itemFiles = readdirSync(cmsItemsDir).filter((f) => f.endsWith(".json"));
|
|
2893
|
-
for (const itemFile of itemFiles) {
|
|
2894
|
-
try {
|
|
2895
|
-
const rawContent = await readFile(join(cmsItemsDir, itemFile), "utf-8");
|
|
2896
|
-
const item = JSON.parse(rawContent);
|
|
2897
|
-
const resolved = { ...item };
|
|
2898
|
-
await writeFile2(
|
|
2899
|
-
join(collectionDir, itemFile),
|
|
2900
|
-
JSON.stringify(resolved, null, 2),
|
|
2901
|
-
"utf-8"
|
|
2902
|
-
);
|
|
2903
|
-
} catch (err) {
|
|
2904
|
-
console.warn(` Warning: could not process CMS item ${itemFile}: ${err?.message}`);
|
|
2905
|
-
}
|
|
2906
|
-
}
|
|
2907
|
-
}
|
|
2908
|
-
const fieldDefs = [];
|
|
2909
|
-
if (schema.fields) {
|
|
2910
|
-
for (const [fieldName, fieldDef] of Object.entries(schema.fields)) {
|
|
2911
|
-
const zodType = cmsFieldToZod(fieldDef);
|
|
2912
|
-
const optional = fieldDef.required ? "" : ".optional()";
|
|
2913
|
-
fieldDefs.push(` ${fieldName}: ${zodType}${optional}`);
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
collectionDefs.push(` '${schema.id}': defineCollection({
|
|
2917
|
-
type: 'data',
|
|
2918
|
-
schema: z.object({
|
|
2919
|
-
${fieldDefs.join(",\n")}
|
|
2920
|
-
})
|
|
2921
|
-
})`);
|
|
2922
|
-
collectionCount++;
|
|
2923
|
-
}
|
|
2924
|
-
const configContent = `import { z, defineCollection } from 'astro:content';
|
|
2925
|
-
|
|
2926
|
-
const collections = {
|
|
2927
|
-
${collectionDefs.join(",\n")}
|
|
2928
|
-
};
|
|
2929
|
-
|
|
2930
|
-
export { collections };
|
|
2931
|
-
`;
|
|
2932
|
-
await writeFile2(join(contentDir, "config.ts"), configContent, "utf-8");
|
|
2933
|
-
console.log(`Generated ${collectionCount} content collection(s) with config.ts`);
|
|
2934
|
-
}
|
|
2935
|
-
const assetDirs = ["fonts", "images", "icons", "videos", "assets"];
|
|
2936
|
-
let copiedAssets = 0;
|
|
2937
|
-
for (const dir of assetDirs) {
|
|
2938
|
-
const srcAssetDir = join(projectPaths.project, dir);
|
|
2939
|
-
if (existsSync(srcAssetDir)) {
|
|
2940
|
-
copyDirectory(srcAssetDir, join(publicDir, dir));
|
|
2941
|
-
copiedAssets++;
|
|
2942
|
-
}
|
|
2943
|
-
}
|
|
2944
|
-
const librariesDir = join(projectPaths.project, "libraries");
|
|
2945
|
-
if (existsSync(librariesDir)) {
|
|
2946
|
-
copyDirectory(librariesDir, join(publicDir, "libraries"));
|
|
2947
|
-
copiedAssets++;
|
|
2948
|
-
}
|
|
2949
|
-
if (copiedAssets > 0) {
|
|
2950
|
-
console.log(`Copied ${copiedAssets} asset director${copiedAssets === 1 ? "y" : "ies"} to public/`);
|
|
2951
|
-
}
|
|
2952
|
-
const packageJson = {
|
|
2953
|
-
name: "astro-export",
|
|
2954
|
-
type: "module",
|
|
2955
|
-
version: "0.0.1",
|
|
2956
|
-
private: true,
|
|
2957
|
-
scripts: {
|
|
2958
|
-
dev: "astro dev",
|
|
2959
|
-
start: "astro dev",
|
|
2960
|
-
build: "astro build",
|
|
2961
|
-
preview: "astro preview"
|
|
2962
|
-
},
|
|
2963
|
-
dependencies: {
|
|
2964
|
-
"astro": "^4.0.0",
|
|
2965
|
-
"@astrojs/tailwind": "^5.0.0",
|
|
2966
|
-
"tailwindcss": "^3.4.0"
|
|
2967
|
-
}
|
|
2968
|
-
};
|
|
2969
|
-
await writeFile2(join(outDir, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8");
|
|
2970
|
-
const localeCodes = i18nConfig.locales.map((l) => l.code);
|
|
2971
|
-
const i18nBlock = i18nConfig.locales.length > 1 ? `
|
|
2972
|
-
i18n: {
|
|
2973
|
-
defaultLocale: '${i18nConfig.defaultLocale}',
|
|
2974
|
-
locales: [${localeCodes.map((c) => `'${c}'`).join(", ")}],
|
|
2975
|
-
routing: { prefixDefaultLocale: false },
|
|
2976
|
-
},` : "";
|
|
2977
|
-
const astroConfig = `import { defineConfig } from 'astro/config';
|
|
2978
|
-
import tailwind from '@astrojs/tailwind';
|
|
2979
|
-
|
|
2980
|
-
export default defineConfig({${siteUrl ? `
|
|
2981
|
-
site: '${siteUrl}',` : ""}${i18nBlock}
|
|
2982
|
-
integrations: [tailwind({ applyBaseStyles: false })],
|
|
2983
|
-
});
|
|
2984
|
-
`;
|
|
2985
|
-
const safelistArray = Array.from(mappingClasses);
|
|
2986
|
-
const safelistLiteral = safelistArray.length > 0 ? `
|
|
2987
|
-
safelist: [
|
|
2988
|
-
${safelistArray.map((c) => ` '${c}'`).join(",\n")}
|
|
2989
|
-
],` : "";
|
|
2990
|
-
const tailwindConfig = `/** @type {import('tailwindcss').Config} */
|
|
2991
|
-
export default {
|
|
2992
|
-
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],${safelistLiteral}
|
|
2993
|
-
theme: {
|
|
2994
|
-
extend: {},
|
|
2995
|
-
},
|
|
2996
|
-
plugins: [],
|
|
2997
|
-
};
|
|
2998
|
-
`;
|
|
2999
|
-
await writeFile2(join(outDir, "tailwind.config.mjs"), tailwindConfig, "utf-8");
|
|
3000
|
-
await writeFile2(join(outDir, "astro.config.mjs"), astroConfig, "utf-8");
|
|
3001
|
-
const tsConfig = {
|
|
3002
|
-
extends: "astro/tsconfigs/strict"
|
|
3003
|
-
};
|
|
3004
|
-
await writeFile2(join(outDir, "tsconfig.json"), JSON.stringify(tsConfig, null, 2), "utf-8");
|
|
3005
|
-
console.log("Generated package.json, astro.config.mjs, tailwind.config.mjs, tsconfig.json");
|
|
3006
|
-
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
3007
|
-
const totalPages = allResults.length;
|
|
3008
|
-
console.log("\n" + "=".repeat(50));
|
|
3009
|
-
console.log("Astro export complete!");
|
|
3010
|
-
console.log(` Pages: ${totalPages - cmsPageCount}`);
|
|
3011
|
-
if (cmsPageCount > 0) {
|
|
3012
|
-
console.log(` CMS pages: ${cmsPageCount}`);
|
|
3013
|
-
}
|
|
3014
|
-
if (collectionCount > 0) {
|
|
3015
|
-
console.log(` Content collections: ${collectionCount}`);
|
|
3016
|
-
}
|
|
3017
|
-
if (errorCount > 0) {
|
|
3018
|
-
console.log(` Errors: ${errorCount}`);
|
|
3019
|
-
}
|
|
3020
|
-
console.log(` Time: ${elapsed}s`);
|
|
3021
|
-
console.log(` Output: ${outDir}`);
|
|
3022
|
-
console.log("");
|
|
3023
|
-
return {
|
|
3024
|
-
pages: totalPages - cmsPageCount,
|
|
3025
|
-
cmsPages: cmsPageCount,
|
|
3026
|
-
collections: collectionCount,
|
|
3027
|
-
errors: errorCount
|
|
3028
|
-
};
|
|
3029
|
-
}
|
|
3030
|
-
|
|
3031
131
|
// lib/server/webflow/buildWebflow.ts
|
|
3032
|
-
import { existsSync
|
|
3033
|
-
import { join
|
|
132
|
+
import { existsSync, readdirSync } from "fs";
|
|
133
|
+
import { join } from "path";
|
|
3034
134
|
|
|
3035
135
|
// lib/server/webflow/types.ts
|
|
3036
136
|
function mapCMSFieldType(menoType) {
|
|
@@ -3076,10 +176,10 @@ var UNITLESS_PROPERTIES = /* @__PURE__ */ new Set([
|
|
|
3076
176
|
"font-weight",
|
|
3077
177
|
"tab-size"
|
|
3078
178
|
]);
|
|
3079
|
-
function
|
|
179
|
+
function isStyleMapping(value) {
|
|
3080
180
|
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
3081
181
|
}
|
|
3082
|
-
function
|
|
182
|
+
function isResponsiveStyle(style) {
|
|
3083
183
|
return "base" in style || "tablet" in style || "mobile" in style;
|
|
3084
184
|
}
|
|
3085
185
|
function toKebabCase(prop) {
|
|
@@ -3088,7 +188,7 @@ function toKebabCase(prop) {
|
|
|
3088
188
|
function styleObjectToCSS(style) {
|
|
3089
189
|
const css = {};
|
|
3090
190
|
for (const [prop, value] of Object.entries(style)) {
|
|
3091
|
-
if (
|
|
191
|
+
if (isStyleMapping(value)) continue;
|
|
3092
192
|
if (value === "" || value === void 0 || value === null) continue;
|
|
3093
193
|
if (typeof value === "boolean" || typeof value === "object") continue;
|
|
3094
194
|
const cssProp = toKebabCase(prop);
|
|
@@ -3101,21 +201,21 @@ function styleObjectToCSS(style) {
|
|
|
3101
201
|
}
|
|
3102
202
|
return css;
|
|
3103
203
|
}
|
|
3104
|
-
function
|
|
204
|
+
function collectStyleMappings(style) {
|
|
3105
205
|
if (!style) return [];
|
|
3106
206
|
const result = [];
|
|
3107
|
-
if (
|
|
207
|
+
if (isResponsiveStyle(style)) {
|
|
3108
208
|
const base = style.base;
|
|
3109
209
|
if (base) {
|
|
3110
210
|
for (const [prop, value] of Object.entries(base)) {
|
|
3111
|
-
if (
|
|
211
|
+
if (isStyleMapping(value)) {
|
|
3112
212
|
result.push({ property: prop, mapping: value });
|
|
3113
213
|
}
|
|
3114
214
|
}
|
|
3115
215
|
}
|
|
3116
216
|
} else {
|
|
3117
217
|
for (const [prop, value] of Object.entries(style)) {
|
|
3118
|
-
if (
|
|
218
|
+
if (isStyleMapping(value)) {
|
|
3119
219
|
result.push({ property: prop, mapping: value });
|
|
3120
220
|
}
|
|
3121
221
|
}
|
|
@@ -3137,7 +237,7 @@ function mapStylesToWebflow(className, style, interactiveStyles, breakpoints) {
|
|
|
3137
237
|
base: {}
|
|
3138
238
|
};
|
|
3139
239
|
if (style) {
|
|
3140
|
-
if (
|
|
240
|
+
if (isResponsiveStyle(style)) {
|
|
3141
241
|
const responsive = style;
|
|
3142
242
|
if (responsive.base) {
|
|
3143
243
|
primaryClass.base = styleObjectToCSS(responsive.base);
|
|
@@ -3169,7 +269,7 @@ function mapStylesToWebflow(className, style, interactiveStyles, breakpoints) {
|
|
|
3169
269
|
if (!pseudoState) continue;
|
|
3170
270
|
const ruleStyle = rule.style;
|
|
3171
271
|
if (!primaryClass.pseudoStates) primaryClass.pseudoStates = {};
|
|
3172
|
-
if (
|
|
272
|
+
if (isResponsiveStyle(ruleStyle)) {
|
|
3173
273
|
const responsive = ruleStyle;
|
|
3174
274
|
if (responsive.base) {
|
|
3175
275
|
primaryClass.pseudoStates[pseudoState] = {
|
|
@@ -3186,7 +286,7 @@ function mapStylesToWebflow(className, style, interactiveStyles, breakpoints) {
|
|
|
3186
286
|
}
|
|
3187
287
|
}
|
|
3188
288
|
const comboClasses = [];
|
|
3189
|
-
const mappings =
|
|
289
|
+
const mappings = collectStyleMappings(style);
|
|
3190
290
|
for (const { property, mapping } of mappings) {
|
|
3191
291
|
for (const [value, cssValue] of Object.entries(mapping.values)) {
|
|
3192
292
|
if (cssValue === "" || cssValue === void 0) continue;
|
|
@@ -3208,7 +308,7 @@ function sanitizeClassName(name) {
|
|
|
3208
308
|
}
|
|
3209
309
|
|
|
3210
310
|
// lib/server/webflow/nodeToWebflow.ts
|
|
3211
|
-
function
|
|
311
|
+
function buildElementClass(ctx, label) {
|
|
3212
312
|
return generateElementClassName({
|
|
3213
313
|
fileType: ctx.fileType,
|
|
3214
314
|
fileName: ctx.fileName,
|
|
@@ -3216,7 +316,7 @@ function buildElementClass2(ctx, label) {
|
|
|
3216
316
|
path: ctx.elementPath
|
|
3217
317
|
});
|
|
3218
318
|
}
|
|
3219
|
-
function
|
|
319
|
+
function resolveTemplate(text, props) {
|
|
3220
320
|
if (!props) return text;
|
|
3221
321
|
return text.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
3222
322
|
const trimmed = expr.trim();
|
|
@@ -3243,13 +343,13 @@ function resolveNestedProp(obj, path) {
|
|
|
3243
343
|
}
|
|
3244
344
|
return current;
|
|
3245
345
|
}
|
|
3246
|
-
function
|
|
346
|
+
function hasTemplates(text) {
|
|
3247
347
|
return /\{\{.+?\}\}/.test(text);
|
|
3248
348
|
}
|
|
3249
349
|
function nodeToWebflow(node, ctx, instanceProps) {
|
|
3250
350
|
if (node === null || node === void 0) return [];
|
|
3251
351
|
if (typeof node === "string") {
|
|
3252
|
-
const text = instanceProps ?
|
|
352
|
+
const text = instanceProps ? resolveTemplate(node, instanceProps) : node;
|
|
3253
353
|
return [{ tag: "span", textContent: text }];
|
|
3254
354
|
}
|
|
3255
355
|
if (typeof node === "number") {
|
|
@@ -3268,15 +368,15 @@ function nodeToWebflow(node, ctx, instanceProps) {
|
|
|
3268
368
|
}
|
|
3269
369
|
switch (node.type) {
|
|
3270
370
|
case NODE_TYPE.NODE:
|
|
3271
|
-
return [
|
|
371
|
+
return [emitHtmlNode(node, ctx, instanceProps)];
|
|
3272
372
|
case NODE_TYPE.COMPONENT:
|
|
3273
|
-
return
|
|
373
|
+
return emitComponentInstance(node, ctx, instanceProps);
|
|
3274
374
|
case NODE_TYPE.SLOT:
|
|
3275
|
-
return
|
|
375
|
+
return emitSlotMarker(node, ctx, instanceProps);
|
|
3276
376
|
case NODE_TYPE.EMBED:
|
|
3277
|
-
return [
|
|
377
|
+
return [emitEmbedNode(node, ctx, instanceProps)];
|
|
3278
378
|
case NODE_TYPE.LINK:
|
|
3279
|
-
return [
|
|
379
|
+
return [emitLinkNode(node, ctx, instanceProps)];
|
|
3280
380
|
case NODE_TYPE.LIST:
|
|
3281
381
|
case "cms-list":
|
|
3282
382
|
case NODE_TYPE.LOCALE_LIST:
|
|
@@ -3285,15 +385,15 @@ function nodeToWebflow(node, ctx, instanceProps) {
|
|
|
3285
385
|
return [];
|
|
3286
386
|
}
|
|
3287
387
|
}
|
|
3288
|
-
function
|
|
3289
|
-
const tag =
|
|
388
|
+
function emitHtmlNode(node, ctx, instanceProps) {
|
|
389
|
+
const tag = hasTemplates(node.tag) && instanceProps ? resolveTemplate(node.tag, instanceProps) : node.tag;
|
|
3290
390
|
const style = node.style;
|
|
3291
391
|
const interactiveStyles = node.interactiveStyles;
|
|
3292
392
|
const needsClass = style || interactiveStyles && interactiveStyles.length > 0 || node.generateElementClass;
|
|
3293
393
|
let className;
|
|
3294
394
|
let comboClassNames;
|
|
3295
395
|
if (needsClass) {
|
|
3296
|
-
const elementClass =
|
|
396
|
+
const elementClass = buildElementClass(ctx, node.label);
|
|
3297
397
|
const { primaryClass, comboClasses } = mapStylesToWebflow(
|
|
3298
398
|
elementClass,
|
|
3299
399
|
style,
|
|
@@ -3313,8 +413,8 @@ function emitHtmlNode2(node, ctx, instanceProps) {
|
|
|
3313
413
|
const attributes = {};
|
|
3314
414
|
if (node.attributes) {
|
|
3315
415
|
for (const [key, value] of Object.entries(node.attributes)) {
|
|
3316
|
-
if (instanceProps && typeof value === "string" &&
|
|
3317
|
-
attributes[key] =
|
|
416
|
+
if (instanceProps && typeof value === "string" && hasTemplates(value)) {
|
|
417
|
+
attributes[key] = resolveTemplate(value, instanceProps);
|
|
3318
418
|
} else {
|
|
3319
419
|
attributes[key] = value;
|
|
3320
420
|
}
|
|
@@ -3324,10 +424,10 @@ function emitHtmlNode2(node, ctx, instanceProps) {
|
|
|
3324
424
|
let textContent;
|
|
3325
425
|
if (!isVoidElement(tag) && node.children) {
|
|
3326
426
|
if (typeof node.children === "string") {
|
|
3327
|
-
textContent = instanceProps ?
|
|
427
|
+
textContent = instanceProps ? resolveTemplate(node.children, instanceProps) : node.children;
|
|
3328
428
|
} else if (Array.isArray(node.children) && node.children.length === 1 && typeof node.children[0] === "string") {
|
|
3329
429
|
const text = node.children[0];
|
|
3330
|
-
textContent = instanceProps ?
|
|
430
|
+
textContent = instanceProps ? resolveTemplate(text, instanceProps) : text;
|
|
3331
431
|
} else {
|
|
3332
432
|
const innerCtx = { ...ctx, elementPath: [...ctx.elementPath] };
|
|
3333
433
|
children = convertChildren(node.children, innerCtx, instanceProps);
|
|
@@ -3353,7 +453,7 @@ function emitHtmlNode2(node, ctx, instanceProps) {
|
|
|
3353
453
|
if (conditional) element.conditional = conditional;
|
|
3354
454
|
return element;
|
|
3355
455
|
}
|
|
3356
|
-
function
|
|
456
|
+
function emitComponentInstance(node, ctx, parentProps) {
|
|
3357
457
|
const compDef = ctx.globalComponents[node.component];
|
|
3358
458
|
if (!compDef) {
|
|
3359
459
|
return [{ tag: "div", attributes: { "data-component": node.component } }];
|
|
@@ -3368,8 +468,8 @@ function emitComponentInstance2(node, ctx, parentProps) {
|
|
|
3368
468
|
if (node.props) {
|
|
3369
469
|
for (const [key, value] of Object.entries(node.props)) {
|
|
3370
470
|
if (key === "children") continue;
|
|
3371
|
-
if (typeof value === "string" &&
|
|
3372
|
-
resolvedProps[key] =
|
|
471
|
+
if (typeof value === "string" && hasTemplates(value) && parentProps) {
|
|
472
|
+
resolvedProps[key] = resolveTemplate(value, parentProps);
|
|
3373
473
|
} else {
|
|
3374
474
|
resolvedProps[key] = value;
|
|
3375
475
|
}
|
|
@@ -3386,7 +486,7 @@ function emitComponentInstance2(node, ctx, parentProps) {
|
|
|
3386
486
|
};
|
|
3387
487
|
return nodeToWebflow(body, compCtx, resolvedProps);
|
|
3388
488
|
}
|
|
3389
|
-
function
|
|
489
|
+
function emitSlotMarker(node, ctx, instanceProps) {
|
|
3390
490
|
if (ctx.slotChildren) {
|
|
3391
491
|
const parentCtx = {
|
|
3392
492
|
...ctx,
|
|
@@ -3400,12 +500,12 @@ function emitSlotMarker2(node, ctx, instanceProps) {
|
|
|
3400
500
|
}
|
|
3401
501
|
return [];
|
|
3402
502
|
}
|
|
3403
|
-
function
|
|
503
|
+
function emitEmbedNode(node, ctx, instanceProps) {
|
|
3404
504
|
const style = node.style;
|
|
3405
505
|
const interactiveStyles = node.interactiveStyles;
|
|
3406
506
|
let className;
|
|
3407
507
|
if (style || interactiveStyles && interactiveStyles.length > 0) {
|
|
3408
|
-
const elementClass =
|
|
508
|
+
const elementClass = buildElementClass(ctx, node.label);
|
|
3409
509
|
const { primaryClass } = mapStylesToWebflow(
|
|
3410
510
|
elementClass,
|
|
3411
511
|
style,
|
|
@@ -3423,12 +523,12 @@ function emitEmbedNode2(node, ctx, instanceProps) {
|
|
|
3423
523
|
if (className) element.className = className;
|
|
3424
524
|
return element;
|
|
3425
525
|
}
|
|
3426
|
-
function
|
|
526
|
+
function emitLinkNode(node, ctx, instanceProps) {
|
|
3427
527
|
const style = node.style;
|
|
3428
528
|
const interactiveStyles = node.interactiveStyles;
|
|
3429
529
|
let className;
|
|
3430
530
|
if (style || interactiveStyles && interactiveStyles.length > 0) {
|
|
3431
|
-
const elementClass =
|
|
531
|
+
const elementClass = buildElementClass(ctx, node.label);
|
|
3432
532
|
const { primaryClass } = mapStylesToWebflow(
|
|
3433
533
|
elementClass,
|
|
3434
534
|
style,
|
|
@@ -3440,7 +540,7 @@ function emitLinkNode2(node, ctx, instanceProps) {
|
|
|
3440
540
|
}
|
|
3441
541
|
let href = "#";
|
|
3442
542
|
if (typeof node.href === "string") {
|
|
3443
|
-
href = instanceProps &&
|
|
543
|
+
href = instanceProps && hasTemplates(node.href) ? resolveTemplate(node.href, instanceProps) : node.href;
|
|
3444
544
|
}
|
|
3445
545
|
const attributes = { href };
|
|
3446
546
|
if (node.attributes) {
|
|
@@ -3470,20 +570,20 @@ function convertChildren(children, ctx, instanceProps) {
|
|
|
3470
570
|
}
|
|
3471
571
|
|
|
3472
572
|
// lib/server/webflow/buildWebflow.ts
|
|
3473
|
-
function
|
|
573
|
+
function scanJSONFiles(dir, prefix = "") {
|
|
3474
574
|
const results = [];
|
|
3475
|
-
if (!
|
|
3476
|
-
const entries =
|
|
575
|
+
if (!existsSync(dir)) return results;
|
|
576
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
3477
577
|
for (const entry of entries) {
|
|
3478
578
|
if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
3479
579
|
results.push(prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
3480
580
|
} else if (entry.isDirectory()) {
|
|
3481
|
-
results.push(...
|
|
581
|
+
results.push(...scanJSONFiles(join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name));
|
|
3482
582
|
}
|
|
3483
583
|
}
|
|
3484
584
|
return results;
|
|
3485
585
|
}
|
|
3486
|
-
function
|
|
586
|
+
function isCMSPage(pageData) {
|
|
3487
587
|
return pageData.meta?.source === "cms" && !!pageData.meta?.cms;
|
|
3488
588
|
}
|
|
3489
589
|
function buildCMSItemPath(urlPattern, item, slugField, locale, i18nConfig) {
|
|
@@ -3502,9 +602,9 @@ function scanAssets(projectRoot) {
|
|
|
3502
602
|
{ dir: "assets", type: "file" }
|
|
3503
603
|
];
|
|
3504
604
|
for (const { dir, type } of assetDirs) {
|
|
3505
|
-
const fullDir =
|
|
3506
|
-
if (!
|
|
3507
|
-
const files =
|
|
605
|
+
const fullDir = join(projectRoot, dir);
|
|
606
|
+
if (!existsSync(fullDir)) continue;
|
|
607
|
+
const files = scanJSONFiles(fullDir).map((f) => f.replace(".json", ""));
|
|
3508
608
|
const allFiles = scanAllFiles(fullDir);
|
|
3509
609
|
for (const file of allFiles) {
|
|
3510
610
|
assets.push({
|
|
@@ -3518,14 +618,14 @@ function scanAssets(projectRoot) {
|
|
|
3518
618
|
}
|
|
3519
619
|
function scanAllFiles(dir, prefix = "") {
|
|
3520
620
|
const results = [];
|
|
3521
|
-
if (!
|
|
3522
|
-
const entries =
|
|
621
|
+
if (!existsSync(dir)) return results;
|
|
622
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
3523
623
|
for (const entry of entries) {
|
|
3524
624
|
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
3525
625
|
if (entry.isFile()) {
|
|
3526
626
|
results.push(relativePath);
|
|
3527
627
|
} else if (entry.isDirectory()) {
|
|
3528
|
-
results.push(...scanAllFiles(
|
|
628
|
+
results.push(...scanAllFiles(join(dir, entry.name), relativePath));
|
|
3529
629
|
}
|
|
3530
630
|
}
|
|
3531
631
|
return results;
|
|
@@ -3561,10 +661,10 @@ async function buildWebflowPayload(projectRoot) {
|
|
|
3561
661
|
const responsiveScales = await loadResponsiveScalesConfig();
|
|
3562
662
|
await configService.load();
|
|
3563
663
|
const pagesDir = projectPaths.pages();
|
|
3564
|
-
if (!
|
|
664
|
+
if (!existsSync(pagesDir)) {
|
|
3565
665
|
return emptyPayload();
|
|
3566
666
|
}
|
|
3567
|
-
const pageFiles =
|
|
667
|
+
const pageFiles = scanJSONFiles(pagesDir);
|
|
3568
668
|
if (pageFiles.length === 0) {
|
|
3569
669
|
return emptyPayload();
|
|
3570
670
|
}
|
|
@@ -3572,7 +672,7 @@ async function buildWebflowPayload(projectRoot) {
|
|
|
3572
672
|
for (const file of pageFiles) {
|
|
3573
673
|
const pageName = file.replace(".json", "");
|
|
3574
674
|
const basePath = mapPageNameToPath(pageName);
|
|
3575
|
-
const pageContent = await loadJSONFile(
|
|
675
|
+
const pageContent = await loadJSONFile(join(pagesDir, file));
|
|
3576
676
|
if (!pageContent) continue;
|
|
3577
677
|
try {
|
|
3578
678
|
const pageData = parseJSON(pageContent);
|
|
@@ -3588,7 +688,7 @@ async function buildWebflowPayload(projectRoot) {
|
|
|
3588
688
|
for (const file of pageFiles) {
|
|
3589
689
|
const pageName = file.replace(".json", "");
|
|
3590
690
|
const basePath = mapPageNameToPath(pageName);
|
|
3591
|
-
const pageContent = await loadJSONFile(
|
|
691
|
+
const pageContent = await loadJSONFile(join(pagesDir, file));
|
|
3592
692
|
if (!pageContent) continue;
|
|
3593
693
|
try {
|
|
3594
694
|
const pageData = parseJSON(pageContent);
|
|
@@ -3642,15 +742,15 @@ async function buildWebflowPayload(projectRoot) {
|
|
|
3642
742
|
}
|
|
3643
743
|
const templatesDir = projectPaths.templates();
|
|
3644
744
|
const cmsCollections = [];
|
|
3645
|
-
if (
|
|
3646
|
-
const templateFiles =
|
|
745
|
+
if (existsSync(templatesDir)) {
|
|
746
|
+
const templateFiles = readdirSync(templatesDir).filter((f) => f.endsWith(".json"));
|
|
3647
747
|
for (const file of templateFiles) {
|
|
3648
|
-
const templateContent = await loadJSONFile(
|
|
748
|
+
const templateContent = await loadJSONFile(join(templatesDir, file));
|
|
3649
749
|
if (!templateContent) continue;
|
|
3650
750
|
try {
|
|
3651
751
|
const pageData = parseJSON(templateContent);
|
|
3652
752
|
if (pageData.meta?.draft === true) continue;
|
|
3653
|
-
if (!
|
|
753
|
+
if (!isCMSPage(pageData)) continue;
|
|
3654
754
|
const cmsSchema = pageData.meta.cms;
|
|
3655
755
|
const items = await cmsService.queryItems({ collection: cmsSchema.id });
|
|
3656
756
|
const fields = [];
|
|
@@ -3773,7 +873,6 @@ export {
|
|
|
3773
873
|
SERVE_PORT,
|
|
3774
874
|
VariableService,
|
|
3775
875
|
WebSocketManager,
|
|
3776
|
-
buildAstroProject,
|
|
3777
876
|
buildAttributes,
|
|
3778
877
|
buildComponentHTML,
|
|
3779
878
|
buildImageMetadataMap,
|
|
@@ -3798,8 +897,12 @@ export {
|
|
|
3798
897
|
extractPageMeta,
|
|
3799
898
|
fileExists,
|
|
3800
899
|
generateBuildErrorPage,
|
|
900
|
+
generateFontCSS,
|
|
901
|
+
generateFontPreloadTags,
|
|
3801
902
|
generateMetaTags,
|
|
3802
903
|
generateSSRHTML,
|
|
904
|
+
generateThemeColorVariablesCSS,
|
|
905
|
+
generateVariablesCSS,
|
|
3803
906
|
getFileSize,
|
|
3804
907
|
getJSValidationErrors,
|
|
3805
908
|
getMimeType,
|
|
@@ -3818,13 +921,20 @@ export {
|
|
|
3818
921
|
isBun,
|
|
3819
922
|
jsonResponse,
|
|
3820
923
|
lineMapToObject,
|
|
924
|
+
loadBreakpointConfig,
|
|
925
|
+
loadComponentDirectory,
|
|
926
|
+
loadI18nConfig,
|
|
927
|
+
loadJSONFile,
|
|
3821
928
|
loadProjectConfig,
|
|
929
|
+
loadResponsiveScalesConfig,
|
|
3822
930
|
logError,
|
|
3823
931
|
logRequest,
|
|
3824
932
|
logResponseTime,
|
|
933
|
+
mapPageNameToPath,
|
|
3825
934
|
migrateTemplatesDirectory,
|
|
3826
935
|
minifyJS,
|
|
3827
936
|
packagePaths,
|
|
937
|
+
parseJSON,
|
|
3828
938
|
processCMSPropsTemplate,
|
|
3829
939
|
processCMSTemplate,
|
|
3830
940
|
projectPaths,
|