meno-core 1.0.39 → 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 +172 -69
- 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-WK5XLASY.js → chunk-EQOSDQS2.js} +4 -4
- package/dist/chunks/{chunk-AIXKUVNG.js → chunk-IBR2F4IL.js} +4 -5
- package/dist/chunks/{chunk-AIXKUVNG.js.map → chunk-IBR2F4IL.js.map} +2 -2
- package/dist/chunks/{chunk-NV25WXCA.js → chunk-IGVQF5GY.js} +11 -7
- package/dist/chunks/chunk-IGVQF5GY.js.map +7 -0
- package/dist/chunks/{chunk-KULPBDC7.js → chunk-LBWIHPN7.js} +9 -3
- package/dist/chunks/chunk-LBWIHPN7.js.map +7 -0
- package/dist/chunks/{chunk-A6KWUEA6.js → chunk-MKB2J6AD.js} +9 -1
- package/dist/chunks/chunk-MKB2J6AD.js.map +7 -0
- package/dist/chunks/{chunk-P3FX5HJM.js → chunk-S2HXJTAF.js} +1 -1
- package/dist/chunks/chunk-S2HXJTAF.js.map +7 -0
- package/dist/chunks/{chunk-W6HDII4T.js → chunk-SK3TLNUP.js} +140 -114
- package/dist/chunks/chunk-SK3TLNUP.js.map +7 -0
- package/dist/chunks/{chunk-HNAS6BSS.js → chunk-SNUROC7E.js} +56 -6
- package/dist/chunks/{chunk-HNAS6BSS.js.map → chunk-SNUROC7E.js.map} +3 -3
- package/dist/chunks/{configService-TXBNUBBL.js → configService-MICL4S2L.js} +2 -2
- package/dist/chunks/{constants-5CRJRQNR.js → constants-ZEU4TZCA.js} +2 -2
- package/dist/entries/server-router.js +7 -7
- package/dist/lib/client/index.js +11 -6
- package/dist/lib/client/index.js.map +2 -2
- package/dist/lib/server/index.js +507 -1587
- 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/core/builders/embedBuilder.ts +2 -2
- 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 +420 -0
- package/lib/server/astro/componentEmitter.ts +150 -17
- package/lib/server/astro/nodeToAstro.test.ts +1101 -0
- package/lib/server/astro/nodeToAstro.ts +869 -37
- package/lib/server/astro/pageEmitter.ts +43 -3
- package/lib/server/astro/tailwindMapper.ts +69 -8
- package/lib/server/astro/templateTransformer.ts +107 -0
- package/lib/server/index.ts +26 -3
- package/lib/server/routes/api/components.ts +62 -0
- package/lib/server/routes/api/core-routes.ts +8 -0
- 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 +78 -29
- package/lib/server/webflow/buildWebflow.ts +415 -0
- package/lib/server/webflow/index.ts +22 -0
- package/lib/server/webflow/nodeToWebflow.ts +423 -0
- package/lib/server/webflow/styleMapper.ts +241 -0
- package/lib/server/webflow/types.ts +196 -0
- package/lib/shared/constants.ts +4 -0
- package/lib/shared/types/components.ts +9 -4
- package/lib/shared/validation/propValidator.ts +2 -1
- package/lib/shared/validation/schemas.ts +4 -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-KULPBDC7.js.map +0 -7
- package/dist/chunks/chunk-NV25WXCA.js.map +0 -7
- package/dist/chunks/chunk-P3FX5HJM.js.map +0 -7
- package/dist/chunks/chunk-W6HDII4T.js.map +0 -7
- /package/dist/chunks/{chunk-WK5XLASY.js.map → chunk-EQOSDQS2.js.map} +0 -0
- /package/dist/chunks/{configService-TXBNUBBL.js.map → configService-MICL4S2L.js.map} +0 -0
- /package/dist/chunks/{constants-5CRJRQNR.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,
|
|
@@ -46,15 +46,12 @@ import {
|
|
|
46
46
|
clearJSValidationCache,
|
|
47
47
|
collectComponentCSS,
|
|
48
48
|
collectComponentJavaScript,
|
|
49
|
-
collectComponentLibraries,
|
|
50
49
|
colorService,
|
|
51
50
|
createI18nResolver,
|
|
52
51
|
escapeHtml,
|
|
53
52
|
extractPageMeta,
|
|
54
|
-
filterLibrariesByContext,
|
|
55
53
|
generateFontCSS,
|
|
56
54
|
generateFontPreloadTags,
|
|
57
|
-
generateLibraryTags,
|
|
58
55
|
generateMetaTags,
|
|
59
56
|
generateSSRHTML,
|
|
60
57
|
generateThemeColorVariablesCSS,
|
|
@@ -67,7 +64,6 @@ import {
|
|
|
67
64
|
loadProjectConfig,
|
|
68
65
|
loadResponsiveScalesConfig,
|
|
69
66
|
mapPageNameToPath,
|
|
70
|
-
mergeLibraries,
|
|
71
67
|
migrateTemplatesDirectory,
|
|
72
68
|
parseJSON,
|
|
73
69
|
processCMSPropsTemplate,
|
|
@@ -76,11 +72,11 @@ import {
|
|
|
76
72
|
resetFontConfig,
|
|
77
73
|
styleToString,
|
|
78
74
|
variableService
|
|
79
|
-
} from "../../chunks/chunk-
|
|
75
|
+
} from "../../chunks/chunk-SK3TLNUP.js";
|
|
80
76
|
import {
|
|
81
77
|
ConfigService,
|
|
82
78
|
configService
|
|
83
|
-
} from "../../chunks/chunk-
|
|
79
|
+
} from "../../chunks/chunk-MKB2J6AD.js";
|
|
84
80
|
import {
|
|
85
81
|
bundleFile,
|
|
86
82
|
createRuntimeServer,
|
|
@@ -110,18 +106,14 @@ import {
|
|
|
110
106
|
writeFile
|
|
111
107
|
} from "../../chunks/chunk-WQFG7PAH.js";
|
|
112
108
|
import "../../chunks/chunk-LIHJ6OUH.js";
|
|
113
|
-
import "../../chunks/chunk-
|
|
114
|
-
import "../../chunks/chunk-
|
|
109
|
+
import "../../chunks/chunk-S2HXJTAF.js";
|
|
110
|
+
import "../../chunks/chunk-IBR2F4IL.js";
|
|
115
111
|
import {
|
|
116
|
-
extractInteractiveStyleMappings,
|
|
117
|
-
generateAllInteractiveCSS,
|
|
118
112
|
generateElementClassName,
|
|
119
|
-
hasInteractiveStyleMappings,
|
|
120
113
|
isItemDraftForLocale,
|
|
121
114
|
isVoidElement
|
|
122
|
-
} from "../../chunks/chunk-
|
|
115
|
+
} from "../../chunks/chunk-IGVQF5GY.js";
|
|
123
116
|
import {
|
|
124
|
-
DEFAULT_BREAKPOINTS,
|
|
125
117
|
isI18nValue,
|
|
126
118
|
resolveI18nValue
|
|
127
119
|
} from "../../chunks/chunk-PGH3ATYI.js";
|
|
@@ -133,603 +125,189 @@ import {
|
|
|
133
125
|
SERVER_PORT,
|
|
134
126
|
SERVE_PORT,
|
|
135
127
|
init_constants
|
|
136
|
-
} from "../../chunks/chunk-
|
|
128
|
+
} from "../../chunks/chunk-LBWIHPN7.js";
|
|
137
129
|
import "../../chunks/chunk-KSBZ2L7C.js";
|
|
138
130
|
|
|
139
|
-
//
|
|
140
|
-
import { existsSync, readdirSync
|
|
141
|
-
import { writeFile as writeFile2, readFile } from "fs/promises";
|
|
131
|
+
// lib/server/webflow/buildWebflow.ts
|
|
132
|
+
import { existsSync, readdirSync } from "fs";
|
|
142
133
|
import { join } from "path";
|
|
143
|
-
import { createHash } from "crypto";
|
|
144
134
|
|
|
145
|
-
// lib/server/
|
|
135
|
+
// lib/server/webflow/types.ts
|
|
136
|
+
function mapCMSFieldType(menoType) {
|
|
137
|
+
switch (menoType) {
|
|
138
|
+
case "string":
|
|
139
|
+
return "PlainText";
|
|
140
|
+
case "text":
|
|
141
|
+
case "rich-text":
|
|
142
|
+
return "RichText";
|
|
143
|
+
case "number":
|
|
144
|
+
return "Number";
|
|
145
|
+
case "boolean":
|
|
146
|
+
return "Switch";
|
|
147
|
+
case "image":
|
|
148
|
+
return "Image";
|
|
149
|
+
case "date":
|
|
150
|
+
return "Date";
|
|
151
|
+
case "select":
|
|
152
|
+
return "Option";
|
|
153
|
+
case "file":
|
|
154
|
+
return "File";
|
|
155
|
+
case "reference":
|
|
156
|
+
return "Reference";
|
|
157
|
+
default:
|
|
158
|
+
return "PlainText";
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// lib/server/webflow/nodeToWebflow.ts
|
|
163
|
+
init_constants();
|
|
164
|
+
|
|
165
|
+
// lib/server/webflow/styleMapper.ts
|
|
166
|
+
var UNITLESS_PROPERTIES = /* @__PURE__ */ new Set([
|
|
167
|
+
"opacity",
|
|
168
|
+
"z-index",
|
|
169
|
+
"flex-grow",
|
|
170
|
+
"flex-shrink",
|
|
171
|
+
"flex",
|
|
172
|
+
"order",
|
|
173
|
+
"orphans",
|
|
174
|
+
"widows",
|
|
175
|
+
"column-count",
|
|
176
|
+
"font-weight",
|
|
177
|
+
"tab-size"
|
|
178
|
+
]);
|
|
146
179
|
function isStyleMapping(value) {
|
|
147
180
|
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
148
181
|
}
|
|
149
|
-
function hasTemplateExpression(value) {
|
|
150
|
-
return /\{\{.+?\}\}/.test(value);
|
|
151
|
-
}
|
|
152
182
|
function isResponsiveStyle(style) {
|
|
153
183
|
return "base" in style || "tablet" in style || "mobile" in style;
|
|
154
184
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
flex: "flex",
|
|
158
|
-
grid: "grid",
|
|
159
|
-
block: "block",
|
|
160
|
-
none: "hidden",
|
|
161
|
-
inline: "inline",
|
|
162
|
-
"inline-block": "inline-block",
|
|
163
|
-
"inline-flex": "inline-flex",
|
|
164
|
-
"inline-grid": "inline-grid"
|
|
165
|
-
},
|
|
166
|
-
flexDirection: {
|
|
167
|
-
column: "flex-col",
|
|
168
|
-
row: "flex-row",
|
|
169
|
-
"column-reverse": "flex-col-reverse",
|
|
170
|
-
"row-reverse": "flex-row-reverse"
|
|
171
|
-
},
|
|
172
|
-
justifyContent: {
|
|
173
|
-
center: "justify-center",
|
|
174
|
-
"flex-start": "justify-start",
|
|
175
|
-
"flex-end": "justify-end",
|
|
176
|
-
"space-between": "justify-between",
|
|
177
|
-
"space-around": "justify-around",
|
|
178
|
-
"space-evenly": "justify-evenly",
|
|
179
|
-
// camelCase aliases (component data uses camelCase)
|
|
180
|
-
spaceBetween: "justify-between",
|
|
181
|
-
spaceAround: "justify-around",
|
|
182
|
-
spaceEvenly: "justify-evenly",
|
|
183
|
-
flexStart: "justify-start",
|
|
184
|
-
flexEnd: "justify-end"
|
|
185
|
-
},
|
|
186
|
-
alignItems: {
|
|
187
|
-
center: "items-center",
|
|
188
|
-
"flex-start": "items-start",
|
|
189
|
-
"flex-end": "items-end",
|
|
190
|
-
stretch: "items-stretch",
|
|
191
|
-
baseline: "items-baseline",
|
|
192
|
-
// camelCase aliases
|
|
193
|
-
flexStart: "items-start",
|
|
194
|
-
flexEnd: "items-end"
|
|
195
|
-
},
|
|
196
|
-
alignContent: {
|
|
197
|
-
center: "content-center",
|
|
198
|
-
"flex-start": "content-start",
|
|
199
|
-
"flex-end": "content-end",
|
|
200
|
-
"space-between": "content-between",
|
|
201
|
-
"space-around": "content-around",
|
|
202
|
-
stretch: "content-stretch"
|
|
203
|
-
},
|
|
204
|
-
alignSelf: {
|
|
205
|
-
auto: "self-auto",
|
|
206
|
-
center: "self-center",
|
|
207
|
-
"flex-start": "self-start",
|
|
208
|
-
"flex-end": "self-end",
|
|
209
|
-
stretch: "self-stretch"
|
|
210
|
-
},
|
|
211
|
-
position: {
|
|
212
|
-
relative: "relative",
|
|
213
|
-
absolute: "absolute",
|
|
214
|
-
fixed: "fixed",
|
|
215
|
-
sticky: "sticky",
|
|
216
|
-
static: "static"
|
|
217
|
-
},
|
|
218
|
-
overflow: {
|
|
219
|
-
hidden: "overflow-hidden",
|
|
220
|
-
auto: "overflow-auto",
|
|
221
|
-
scroll: "overflow-scroll",
|
|
222
|
-
visible: "overflow-visible"
|
|
223
|
-
},
|
|
224
|
-
overflowX: {
|
|
225
|
-
hidden: "overflow-x-hidden",
|
|
226
|
-
auto: "overflow-x-auto",
|
|
227
|
-
scroll: "overflow-x-scroll",
|
|
228
|
-
visible: "overflow-x-visible"
|
|
229
|
-
},
|
|
230
|
-
overflowY: {
|
|
231
|
-
hidden: "overflow-y-hidden",
|
|
232
|
-
auto: "overflow-y-auto",
|
|
233
|
-
scroll: "overflow-y-scroll",
|
|
234
|
-
visible: "overflow-y-visible"
|
|
235
|
-
},
|
|
236
|
-
cursor: {
|
|
237
|
-
pointer: "cursor-pointer",
|
|
238
|
-
default: "cursor-default",
|
|
239
|
-
"not-allowed": "cursor-not-allowed",
|
|
240
|
-
grab: "cursor-grab",
|
|
241
|
-
grabbing: "cursor-grabbing",
|
|
242
|
-
text: "cursor-text",
|
|
243
|
-
move: "cursor-move",
|
|
244
|
-
wait: "cursor-wait"
|
|
245
|
-
},
|
|
246
|
-
textAlign: {
|
|
247
|
-
center: "text-center",
|
|
248
|
-
left: "text-left",
|
|
249
|
-
right: "text-right",
|
|
250
|
-
justify: "text-justify"
|
|
251
|
-
},
|
|
252
|
-
textDecoration: {
|
|
253
|
-
none: "no-underline",
|
|
254
|
-
underline: "underline",
|
|
255
|
-
"line-through": "line-through",
|
|
256
|
-
overline: "overline"
|
|
257
|
-
},
|
|
258
|
-
textTransform: {
|
|
259
|
-
uppercase: "uppercase",
|
|
260
|
-
lowercase: "lowercase",
|
|
261
|
-
capitalize: "capitalize",
|
|
262
|
-
none: "normal-case"
|
|
263
|
-
},
|
|
264
|
-
objectFit: {
|
|
265
|
-
cover: "object-cover",
|
|
266
|
-
contain: "object-contain",
|
|
267
|
-
fill: "object-fill",
|
|
268
|
-
none: "object-none",
|
|
269
|
-
"scale-down": "object-scale-down"
|
|
270
|
-
},
|
|
271
|
-
objectPosition: {
|
|
272
|
-
center: "object-center",
|
|
273
|
-
top: "object-top",
|
|
274
|
-
bottom: "object-bottom",
|
|
275
|
-
left: "object-left",
|
|
276
|
-
right: "object-right"
|
|
277
|
-
},
|
|
278
|
-
flexWrap: {
|
|
279
|
-
wrap: "flex-wrap",
|
|
280
|
-
nowrap: "flex-nowrap",
|
|
281
|
-
"wrap-reverse": "flex-wrap-reverse"
|
|
282
|
-
},
|
|
283
|
-
pointerEvents: {
|
|
284
|
-
none: "pointer-events-none",
|
|
285
|
-
auto: "pointer-events-auto"
|
|
286
|
-
},
|
|
287
|
-
userSelect: {
|
|
288
|
-
none: "select-none",
|
|
289
|
-
auto: "select-auto",
|
|
290
|
-
text: "select-text",
|
|
291
|
-
all: "select-all"
|
|
292
|
-
},
|
|
293
|
-
visibility: {
|
|
294
|
-
hidden: "invisible",
|
|
295
|
-
visible: "visible"
|
|
296
|
-
},
|
|
297
|
-
whiteSpace: {
|
|
298
|
-
normal: "whitespace-normal",
|
|
299
|
-
nowrap: "whitespace-nowrap",
|
|
300
|
-
pre: "whitespace-pre",
|
|
301
|
-
"pre-wrap": "whitespace-pre-wrap",
|
|
302
|
-
"pre-line": "whitespace-pre-line"
|
|
303
|
-
},
|
|
304
|
-
wordBreak: {
|
|
305
|
-
"break-all": "break-all",
|
|
306
|
-
"break-word": "break-words",
|
|
307
|
-
normal: "break-normal"
|
|
308
|
-
},
|
|
309
|
-
listStyleType: {
|
|
310
|
-
none: "list-none",
|
|
311
|
-
disc: "list-disc",
|
|
312
|
-
decimal: "list-decimal"
|
|
313
|
-
},
|
|
314
|
-
listStylePosition: {
|
|
315
|
-
inside: "list-inside",
|
|
316
|
-
outside: "list-outside"
|
|
317
|
-
},
|
|
318
|
-
boxSizing: {
|
|
319
|
-
"border-box": "box-border",
|
|
320
|
-
"content-box": "box-content"
|
|
321
|
-
},
|
|
322
|
-
gridAutoFlow: {
|
|
323
|
-
row: "grid-flow-row",
|
|
324
|
-
column: "grid-flow-col",
|
|
325
|
-
dense: "grid-flow-dense",
|
|
326
|
-
"row dense": "grid-flow-row-dense",
|
|
327
|
-
"column dense": "grid-flow-col-dense"
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
var singleValueMatches = {
|
|
331
|
-
// width/height 100%
|
|
332
|
-
"width:100%": "w-full",
|
|
333
|
-
"height:100%": "h-full",
|
|
334
|
-
"width:100vw": "w-screen",
|
|
335
|
-
"height:100vh": "h-screen",
|
|
336
|
-
"width:auto": "w-auto",
|
|
337
|
-
"height:auto": "h-auto",
|
|
338
|
-
"width:fit-content": "w-fit",
|
|
339
|
-
"height:fit-content": "h-fit",
|
|
340
|
-
"width:min-content": "w-min",
|
|
341
|
-
"height:min-content": "h-min",
|
|
342
|
-
"width:max-content": "w-max",
|
|
343
|
-
"height:max-content": "h-max",
|
|
344
|
-
"maxWidth:100%": "max-w-full",
|
|
345
|
-
"maxWidth:none": "max-w-none",
|
|
346
|
-
"maxHeight:100%": "max-h-full",
|
|
347
|
-
"maxHeight:none": "max-h-none",
|
|
348
|
-
"minWidth:0": "min-w-0",
|
|
349
|
-
"minHeight:0": "min-h-0",
|
|
350
|
-
"margin:auto": "m-auto",
|
|
351
|
-
"margin:0 auto": "mx-auto",
|
|
352
|
-
"marginLeft:auto": "ml-auto",
|
|
353
|
-
"marginRight:auto": "mr-auto",
|
|
354
|
-
"marginInline:auto": "mx-auto",
|
|
355
|
-
"borderRadius:50%": "rounded-full",
|
|
356
|
-
"borderRadius:9999px": "rounded-full",
|
|
357
|
-
"borderRadius:0": "rounded-none",
|
|
358
|
-
"flex:1": "flex-1",
|
|
359
|
-
"flex:none": "flex-none",
|
|
360
|
-
"flex:auto": "flex-auto",
|
|
361
|
-
"flexGrow:0": "grow-0",
|
|
362
|
-
"flexGrow:1": "grow",
|
|
363
|
-
"flexShrink:0": "shrink-0",
|
|
364
|
-
"flexShrink:1": "shrink",
|
|
365
|
-
"opacity:0": "opacity-0",
|
|
366
|
-
"opacity:1": "opacity-100",
|
|
367
|
-
"zIndex:0": "z-0",
|
|
368
|
-
"zIndex:10": "z-10",
|
|
369
|
-
"zIndex:20": "z-20",
|
|
370
|
-
"zIndex:30": "z-30",
|
|
371
|
-
"zIndex:40": "z-40",
|
|
372
|
-
"zIndex:50": "z-50",
|
|
373
|
-
"inset:0": "inset-0",
|
|
374
|
-
"top:0": "top-0",
|
|
375
|
-
"right:0": "right-0",
|
|
376
|
-
"bottom:0": "bottom-0",
|
|
377
|
-
"left:0": "left-0"
|
|
378
|
-
};
|
|
379
|
-
var arbitraryPrefixMap = {
|
|
380
|
-
// Spacing
|
|
381
|
-
padding: "p",
|
|
382
|
-
paddingTop: "pt",
|
|
383
|
-
paddingRight: "pr",
|
|
384
|
-
paddingBottom: "pb",
|
|
385
|
-
paddingLeft: "pl",
|
|
386
|
-
paddingInline: "px",
|
|
387
|
-
paddingBlock: "py",
|
|
388
|
-
margin: "m",
|
|
389
|
-
marginTop: "mt",
|
|
390
|
-
marginRight: "mr",
|
|
391
|
-
marginBottom: "mb",
|
|
392
|
-
marginLeft: "ml",
|
|
393
|
-
marginInline: "mx",
|
|
394
|
-
marginBlock: "my",
|
|
395
|
-
gap: "gap",
|
|
396
|
-
rowGap: "gap-y",
|
|
397
|
-
columnGap: "gap-x",
|
|
398
|
-
// Sizing
|
|
399
|
-
width: "w",
|
|
400
|
-
height: "h",
|
|
401
|
-
maxWidth: "max-w",
|
|
402
|
-
maxHeight: "max-h",
|
|
403
|
-
minWidth: "min-w",
|
|
404
|
-
minHeight: "min-h",
|
|
405
|
-
// Typography
|
|
406
|
-
fontSize: "text",
|
|
407
|
-
fontWeight: "font",
|
|
408
|
-
fontFamily: "font",
|
|
409
|
-
lineHeight: "leading",
|
|
410
|
-
letterSpacing: "tracking",
|
|
411
|
-
// Borders
|
|
412
|
-
borderRadius: "rounded",
|
|
413
|
-
borderTopLeftRadius: "rounded-tl",
|
|
414
|
-
borderTopRightRadius: "rounded-tr",
|
|
415
|
-
borderBottomLeftRadius: "rounded-bl",
|
|
416
|
-
borderBottomRightRadius: "rounded-br",
|
|
417
|
-
border: "border",
|
|
418
|
-
borderTop: "border-t",
|
|
419
|
-
borderRight: "border-r",
|
|
420
|
-
borderBottom: "border-b",
|
|
421
|
-
borderLeft: "border-l",
|
|
422
|
-
borderColor: "border",
|
|
423
|
-
// Colors
|
|
424
|
-
color: "text",
|
|
425
|
-
backgroundColor: "bg",
|
|
426
|
-
background: "bg",
|
|
427
|
-
backgroundImage: "bg",
|
|
428
|
-
// Effects
|
|
429
|
-
opacity: "opacity",
|
|
430
|
-
boxShadow: "shadow",
|
|
431
|
-
textShadow: "[text-shadow]",
|
|
432
|
-
filter: "[filter]",
|
|
433
|
-
backdropFilter: "backdrop",
|
|
434
|
-
transform: "[transform]",
|
|
435
|
-
transformOrigin: "origin",
|
|
436
|
-
transition: "transition",
|
|
437
|
-
mixBlendMode: "mix-blend",
|
|
438
|
-
clipPath: "[clip-path]",
|
|
439
|
-
// Positioning
|
|
440
|
-
top: "top",
|
|
441
|
-
right: "right",
|
|
442
|
-
bottom: "bottom",
|
|
443
|
-
left: "left",
|
|
444
|
-
inset: "inset",
|
|
445
|
-
zIndex: "z",
|
|
446
|
-
// Grid
|
|
447
|
-
gridTemplateColumns: "grid-cols",
|
|
448
|
-
gridTemplateRows: "grid-rows",
|
|
449
|
-
gridColumn: "col",
|
|
450
|
-
gridRow: "row",
|
|
451
|
-
gridAutoRows: "auto-rows",
|
|
452
|
-
gridAutoColumns: "auto-cols",
|
|
453
|
-
// Flexbox extras
|
|
454
|
-
flexGrow: "grow",
|
|
455
|
-
flexShrink: "shrink",
|
|
456
|
-
flexBasis: "basis",
|
|
457
|
-
order: "order",
|
|
458
|
-
flex: "flex",
|
|
459
|
-
// Aspect ratio
|
|
460
|
-
aspectRatio: "aspect",
|
|
461
|
-
// Outline
|
|
462
|
-
outline: "outline",
|
|
463
|
-
outlineWidth: "outline",
|
|
464
|
-
outlineOffset: "outline-offset",
|
|
465
|
-
outlineColor: "outline",
|
|
466
|
-
// Other
|
|
467
|
-
accentColor: "accent",
|
|
468
|
-
textIndent: "[text-indent]",
|
|
469
|
-
verticalAlign: "align",
|
|
470
|
-
overflowWrap: "[overflow-wrap]",
|
|
471
|
-
scrollBehavior: "scroll",
|
|
472
|
-
resize: "resize"
|
|
473
|
-
};
|
|
474
|
-
function propertyToTailwind(property, value) {
|
|
475
|
-
const strValue = String(value);
|
|
476
|
-
if (strValue === "") return null;
|
|
477
|
-
if (hasTemplateExpression(strValue)) return null;
|
|
478
|
-
const singleKey = `${property}:${strValue}`;
|
|
479
|
-
if (singleValueMatches[singleKey]) {
|
|
480
|
-
return singleValueMatches[singleKey];
|
|
481
|
-
}
|
|
482
|
-
if (exactMatches[property]?.[strValue]) {
|
|
483
|
-
return exactMatches[property][strValue];
|
|
484
|
-
}
|
|
485
|
-
if (property === "color" || property === "backgroundColor" || property === "borderColor") {
|
|
486
|
-
const prefix = property === "color" ? "text" : property === "backgroundColor" ? "bg" : "border";
|
|
487
|
-
if (strValue.includes("var(")) {
|
|
488
|
-
return `${prefix}-[${strValue}]`;
|
|
489
|
-
}
|
|
490
|
-
if (!strValue.match(/^[#\d]/) && !strValue.includes("rgb") && !strValue.includes("hsl")) {
|
|
491
|
-
return `${prefix}-[var(--${strValue})]`;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
const twPrefix = arbitraryPrefixMap[property];
|
|
495
|
-
if (!twPrefix) {
|
|
496
|
-
const cssProp = property.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
497
|
-
const sanitized2 = strValue.replace(/\s+/g, "_");
|
|
498
|
-
return `[${cssProp}:${sanitized2}]`;
|
|
499
|
-
}
|
|
500
|
-
if (twPrefix.startsWith("[")) {
|
|
501
|
-
const sanitized2 = strValue.replace(/\s+/g, "_");
|
|
502
|
-
return `${twPrefix.slice(0, -1)}:${sanitized2}]`;
|
|
503
|
-
}
|
|
504
|
-
const sanitized = strValue.replace(/\s+/g, "_");
|
|
505
|
-
if (property === "fontFamily" && !sanitized.includes(",") && !sanitized.startsWith("'")) {
|
|
506
|
-
return `${twPrefix}-['${sanitized}']`;
|
|
507
|
-
}
|
|
508
|
-
return `${twPrefix}-[${sanitized}]`;
|
|
185
|
+
function toKebabCase(prop) {
|
|
186
|
+
return prop.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
509
187
|
}
|
|
510
|
-
function
|
|
511
|
-
const
|
|
512
|
-
const dynamicStyles = {};
|
|
188
|
+
function styleObjectToCSS(style) {
|
|
189
|
+
const css = {};
|
|
513
190
|
for (const [prop, value] of Object.entries(style)) {
|
|
514
191
|
if (isStyleMapping(value)) continue;
|
|
515
|
-
|
|
516
|
-
if (
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
continue;
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
classes.push(twClass);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return { classes, dynamicStyles };
|
|
527
|
-
}
|
|
528
|
-
function responsiveStylesToTailwind(style, breakpoints) {
|
|
529
|
-
if (!style) return { classes: [], dynamicStyles: {} };
|
|
530
|
-
const allClasses = [];
|
|
531
|
-
const allDynamicStyles = {};
|
|
532
|
-
if (isResponsiveStyle(style)) {
|
|
533
|
-
const responsive = style;
|
|
534
|
-
if (responsive.base) {
|
|
535
|
-
const { classes, dynamicStyles } = stylesToTailwind(responsive.base);
|
|
536
|
-
allClasses.push(...classes);
|
|
537
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
538
|
-
}
|
|
539
|
-
if (responsive.tablet) {
|
|
540
|
-
const bpValue = breakpoints.tablet?.breakpoint ?? 1024;
|
|
541
|
-
const prefix = `max-[${bpValue}px]:`;
|
|
542
|
-
const { classes, dynamicStyles } = stylesToTailwind(responsive.tablet);
|
|
543
|
-
allClasses.push(...classes.map((cls) => `${prefix}${cls}`));
|
|
544
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
545
|
-
}
|
|
546
|
-
if (responsive.mobile) {
|
|
547
|
-
const bpValue = breakpoints.mobile?.breakpoint ?? 540;
|
|
548
|
-
const prefix = `max-[${bpValue}px]:`;
|
|
549
|
-
const { classes, dynamicStyles } = stylesToTailwind(responsive.mobile);
|
|
550
|
-
allClasses.push(...classes.map((cls) => `${prefix}${cls}`));
|
|
551
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
552
|
-
}
|
|
553
|
-
for (const [bpName, bpStyle] of Object.entries(responsive)) {
|
|
554
|
-
if (bpName === "base" || bpName === "tablet" || bpName === "mobile" || !bpStyle) continue;
|
|
555
|
-
const bpValue = breakpoints[bpName]?.breakpoint;
|
|
556
|
-
if (!bpValue) continue;
|
|
557
|
-
const prefix = `max-[${bpValue}px]:`;
|
|
558
|
-
const { classes, dynamicStyles } = stylesToTailwind(bpStyle);
|
|
559
|
-
allClasses.push(...classes.map((cls) => `${prefix}${cls}`));
|
|
560
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
192
|
+
if (value === "" || value === void 0 || value === null) continue;
|
|
193
|
+
if (typeof value === "boolean" || typeof value === "object") continue;
|
|
194
|
+
const cssProp = toKebabCase(prop);
|
|
195
|
+
if (typeof value === "number") {
|
|
196
|
+
if (isNaN(value)) continue;
|
|
197
|
+
css[cssProp] = UNITLESS_PROPERTIES.has(cssProp) ? String(value) : `${value}px`;
|
|
198
|
+
} else {
|
|
199
|
+
css[cssProp] = String(value);
|
|
561
200
|
}
|
|
562
|
-
} else {
|
|
563
|
-
const { classes, dynamicStyles } = stylesToTailwind(style);
|
|
564
|
-
allClasses.push(...classes);
|
|
565
|
-
Object.assign(allDynamicStyles, dynamicStyles);
|
|
566
201
|
}
|
|
567
|
-
return
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// lib/server/astro/nodeToAstro.ts
|
|
571
|
-
init_constants();
|
|
572
|
-
function ind(ctx) {
|
|
573
|
-
return " ".repeat(ctx.indent);
|
|
574
|
-
}
|
|
575
|
-
function isStyleMapping2(value) {
|
|
576
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
577
|
-
}
|
|
578
|
-
function isLinkMapping(value) {
|
|
579
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
580
|
-
}
|
|
581
|
-
function isHtmlMapping(value) {
|
|
582
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
583
|
-
}
|
|
584
|
-
function isResponsiveStyle2(style) {
|
|
585
|
-
return "base" in style || "tablet" in style || "mobile" in style;
|
|
586
|
-
}
|
|
587
|
-
function escapeJSX(s) {
|
|
588
|
-
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
589
|
-
}
|
|
590
|
-
function escapeTemplateLiteral(s) {
|
|
591
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
202
|
+
return css;
|
|
592
203
|
}
|
|
593
204
|
function collectStyleMappings(style) {
|
|
594
205
|
if (!style) return [];
|
|
595
206
|
const result = [];
|
|
596
|
-
if (
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
result.push({ property: prop, mapping: value, breakpoint: bp });
|
|
207
|
+
if (isResponsiveStyle(style)) {
|
|
208
|
+
const base = style.base;
|
|
209
|
+
if (base) {
|
|
210
|
+
for (const [prop, value] of Object.entries(base)) {
|
|
211
|
+
if (isStyleMapping(value)) {
|
|
212
|
+
result.push({ property: prop, mapping: value });
|
|
603
213
|
}
|
|
604
214
|
}
|
|
605
215
|
}
|
|
606
216
|
} else {
|
|
607
217
|
for (const [prop, value] of Object.entries(style)) {
|
|
608
|
-
if (
|
|
218
|
+
if (isStyleMapping(value)) {
|
|
609
219
|
result.push({ property: prop, mapping: value });
|
|
610
220
|
}
|
|
611
221
|
}
|
|
612
222
|
}
|
|
613
223
|
return result;
|
|
614
224
|
}
|
|
615
|
-
function
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
if (
|
|
619
|
-
|
|
620
|
-
if (
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
225
|
+
function postfixToPseudoState(postfix) {
|
|
226
|
+
if (postfix.includes(":hover")) return "hover";
|
|
227
|
+
if (postfix.includes(":focus-visible")) return "focus-visible";
|
|
228
|
+
if (postfix.includes(":focus")) return "focus";
|
|
229
|
+
if (postfix.includes(":active")) return "active";
|
|
230
|
+
if (postfix.includes(":visited")) return "visited";
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
function mapStylesToWebflow(className, style, interactiveStyles, breakpoints) {
|
|
234
|
+
const webflowClassName = className.replace(/_/g, "-");
|
|
235
|
+
const primaryClass = {
|
|
236
|
+
name: webflowClassName,
|
|
237
|
+
base: {}
|
|
238
|
+
};
|
|
239
|
+
if (style) {
|
|
240
|
+
if (isResponsiveStyle(style)) {
|
|
241
|
+
const responsive = style;
|
|
242
|
+
if (responsive.base) {
|
|
243
|
+
primaryClass.base = styleObjectToCSS(responsive.base);
|
|
632
244
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
637
|
-
function coerceValue(val) {
|
|
638
|
-
if (val === "true") return true;
|
|
639
|
-
if (val === "false") return false;
|
|
640
|
-
return val;
|
|
641
|
-
}
|
|
642
|
-
function getClassForValue(property, value, breakpointPrefix) {
|
|
643
|
-
const twClass = propertyToTailwind(property, value);
|
|
644
|
-
if (!twClass) return null;
|
|
645
|
-
return breakpointPrefix ? `${breakpointPrefix}${twClass}` : twClass;
|
|
646
|
-
}
|
|
647
|
-
function buildClassAndStyleExpression(style, interactiveStyles, elementClass, ctx) {
|
|
648
|
-
const result = style ? responsiveStylesToTailwind(style, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
649
|
-
const staticClasses = result.classes;
|
|
650
|
-
const dynamicStyles = result.dynamicStyles;
|
|
651
|
-
if (elementClass) {
|
|
652
|
-
staticClasses.unshift(elementClass);
|
|
653
|
-
}
|
|
654
|
-
const conditionals = [];
|
|
655
|
-
const mappings = collectStyleMappings(style);
|
|
656
|
-
for (const { property, mapping, breakpoint } of mappings) {
|
|
657
|
-
const bpValue = breakpoint === "tablet" ? ctx.breakpoints.tablet?.breakpoint ?? 1024 : breakpoint === "mobile" ? ctx.breakpoints.mobile?.breakpoint ?? 540 : 0;
|
|
658
|
-
const prefix = bpValue ? `max-[${bpValue}px]:` : "";
|
|
659
|
-
const entries = mappingToClassListEntries(mapping, property, prefix, ctx);
|
|
660
|
-
conditionals.push(...entries);
|
|
661
|
-
}
|
|
662
|
-
let styleAttr = "";
|
|
663
|
-
if (Object.keys(dynamicStyles).length > 0 && ctx.isComponentDef) {
|
|
664
|
-
const styleParts = [];
|
|
665
|
-
for (const [cssProp, value] of Object.entries(dynamicStyles)) {
|
|
666
|
-
const resolved = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => `\${${expr.trim()}}`);
|
|
667
|
-
styleParts.push(`${cssProp}: \${${resolved.includes("${") ? resolved.replace(/\$\{(.+?)\}/g, "$1") : `'${resolved}'`}}`);
|
|
668
|
-
}
|
|
669
|
-
const entries = [];
|
|
670
|
-
for (const [cssProp, value] of Object.entries(dynamicStyles)) {
|
|
671
|
-
const resolved = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => `\${${expr.trim()}}`);
|
|
672
|
-
entries.push(`${cssProp}: ${resolved}`);
|
|
673
|
-
}
|
|
674
|
-
styleAttr = ` style={\`${entries.join("; ")}\`}`;
|
|
675
|
-
}
|
|
676
|
-
if (interactiveStyles && interactiveStyles.length > 0 && ctx.isComponentDef && hasInteractiveStyleMappings(interactiveStyles)) {
|
|
677
|
-
const { mappings: mappings2 } = extractInteractiveStyleMappings(interactiveStyles);
|
|
678
|
-
if (mappings2.length > 0) {
|
|
679
|
-
const varParts = [];
|
|
680
|
-
for (const extracted of mappings2) {
|
|
681
|
-
const { mapping, variableIndex } = extracted;
|
|
682
|
-
const varName = `--is-${variableIndex}`;
|
|
683
|
-
const entries = Object.entries(mapping.values);
|
|
684
|
-
if (entries.length === 2) {
|
|
685
|
-
const [[val1, css1], [val2, css2]] = entries;
|
|
686
|
-
varParts.push(`'${varName}': ${mapping.prop} === ${JSON.stringify(coerceValue(val1))} ? '${css1}' : '${css2}'`);
|
|
687
|
-
} else {
|
|
688
|
-
const lookupEntries = entries.filter(([, v]) => v !== "").map(([k, v]) => `${JSON.stringify(coerceValue(k))}: '${v}'`).join(", ");
|
|
689
|
-
varParts.push(`'${varName}': ({${lookupEntries}})[${mapping.prop}] || ''`);
|
|
690
|
-
}
|
|
245
|
+
if (responsive.tablet) {
|
|
246
|
+
if (!primaryClass.breakpoints) primaryClass.breakpoints = {};
|
|
247
|
+
primaryClass.breakpoints.Tablet = styleObjectToCSS(responsive.tablet);
|
|
691
248
|
}
|
|
692
|
-
if (
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
249
|
+
if (responsive.mobile) {
|
|
250
|
+
if (!primaryClass.breakpoints) primaryClass.breakpoints = {};
|
|
251
|
+
primaryClass.breakpoints.MobilePortrait = styleObjectToCSS(responsive.mobile);
|
|
252
|
+
}
|
|
253
|
+
for (const [bpName, bpStyle] of Object.entries(responsive)) {
|
|
254
|
+
if (!bpStyle || bpName === "base" || bpName === "tablet" || bpName === "mobile") continue;
|
|
255
|
+
if (!primaryClass.breakpoints) primaryClass.breakpoints = {};
|
|
256
|
+
primaryClass.breakpoints.Tablet = {
|
|
257
|
+
...primaryClass.breakpoints.Tablet,
|
|
258
|
+
...styleObjectToCSS(bpStyle)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
primaryClass.base = styleObjectToCSS(style);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (interactiveStyles && interactiveStyles.length > 0) {
|
|
266
|
+
for (const rule of interactiveStyles) {
|
|
267
|
+
if (!rule.postfix) continue;
|
|
268
|
+
const pseudoState = postfixToPseudoState(rule.postfix);
|
|
269
|
+
if (!pseudoState) continue;
|
|
270
|
+
const ruleStyle = rule.style;
|
|
271
|
+
if (!primaryClass.pseudoStates) primaryClass.pseudoStates = {};
|
|
272
|
+
if (isResponsiveStyle(ruleStyle)) {
|
|
273
|
+
const responsive = ruleStyle;
|
|
274
|
+
if (responsive.base) {
|
|
275
|
+
primaryClass.pseudoStates[pseudoState] = {
|
|
276
|
+
...primaryClass.pseudoStates[pseudoState],
|
|
277
|
+
...styleObjectToCSS(responsive.base)
|
|
278
|
+
};
|
|
699
279
|
}
|
|
280
|
+
} else {
|
|
281
|
+
primaryClass.pseudoStates[pseudoState] = {
|
|
282
|
+
...primaryClass.pseudoStates[pseudoState],
|
|
283
|
+
...styleObjectToCSS(ruleStyle)
|
|
284
|
+
};
|
|
700
285
|
}
|
|
701
286
|
}
|
|
702
287
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
288
|
+
const comboClasses = [];
|
|
289
|
+
const mappings = collectStyleMappings(style);
|
|
290
|
+
for (const { property, mapping } of mappings) {
|
|
291
|
+
for (const [value, cssValue] of Object.entries(mapping.values)) {
|
|
292
|
+
if (cssValue === "" || cssValue === void 0) continue;
|
|
293
|
+
const comboName = `is-${sanitizeClassName(mapping.prop)}-${sanitizeClassName(String(value))}`;
|
|
294
|
+
const comboClass = {
|
|
295
|
+
name: comboName,
|
|
296
|
+
base: {
|
|
297
|
+
[toKebabCase(property)]: typeof cssValue === "number" ? UNITLESS_PROPERTIES.has(toKebabCase(property)) ? String(cssValue) : `${cssValue}px` : String(cssValue)
|
|
298
|
+
},
|
|
299
|
+
comboParent: webflowClassName
|
|
300
|
+
};
|
|
301
|
+
comboClasses.push(comboClass);
|
|
714
302
|
}
|
|
715
|
-
parts.push(...conditionals);
|
|
716
|
-
classExpr = ` class:list={[${parts.join(", ")}]}`;
|
|
717
|
-
}
|
|
718
|
-
return { classExpr, styleAttr };
|
|
719
|
-
}
|
|
720
|
-
function resolveTemplate(text, ctx) {
|
|
721
|
-
if (!ctx.isComponentDef) {
|
|
722
|
-
return text;
|
|
723
|
-
}
|
|
724
|
-
const fullMatch = text.match(/^\{\{(.+)\}\}$/);
|
|
725
|
-
if (fullMatch) {
|
|
726
|
-
return `{${fullMatch[1].trim()}}`;
|
|
727
303
|
}
|
|
728
|
-
return
|
|
304
|
+
return { primaryClass, comboClasses };
|
|
729
305
|
}
|
|
730
|
-
function
|
|
731
|
-
return
|
|
306
|
+
function sanitizeClassName(name) {
|
|
307
|
+
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
732
308
|
}
|
|
309
|
+
|
|
310
|
+
// lib/server/webflow/nodeToWebflow.ts
|
|
733
311
|
function buildElementClass(ctx, label) {
|
|
734
312
|
return generateElementClassName({
|
|
735
313
|
fileType: ctx.fileType,
|
|
@@ -738,621 +316,272 @@ function buildElementClass(ctx, label) {
|
|
|
738
316
|
path: ctx.elementPath
|
|
739
317
|
});
|
|
740
318
|
}
|
|
741
|
-
function
|
|
742
|
-
if (!
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
319
|
+
function resolveTemplate(text, props) {
|
|
320
|
+
if (!props) return text;
|
|
321
|
+
return text.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
|
|
322
|
+
const trimmed = expr.trim();
|
|
323
|
+
const orMatch = trimmed.match(/^(.+?)\s*\|\|\s*['"](.+?)['"]$/);
|
|
324
|
+
if (orMatch) {
|
|
325
|
+
const value2 = resolveNestedProp(props, orMatch[1].trim());
|
|
326
|
+
return value2 !== void 0 && value2 !== "" && value2 !== null ? String(value2) : orMatch[2];
|
|
327
|
+
}
|
|
328
|
+
const ternaryMatch = trimmed.match(/^(.+?)\s*\?\s*['"](.+?)['"]\s*:\s*['"](.+?)['"]$/);
|
|
329
|
+
if (ternaryMatch) {
|
|
330
|
+
const value2 = resolveNestedProp(props, ternaryMatch[1].trim());
|
|
331
|
+
return value2 ? ternaryMatch[2] : ternaryMatch[3];
|
|
332
|
+
}
|
|
333
|
+
const value = resolveNestedProp(props, trimmed);
|
|
334
|
+
return value !== void 0 ? String(value) : "";
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function resolveNestedProp(obj, path) {
|
|
338
|
+
const parts = path.split(".");
|
|
339
|
+
let current = obj;
|
|
340
|
+
for (const part of parts) {
|
|
341
|
+
if (current === null || current === void 0 || typeof current !== "object") return void 0;
|
|
342
|
+
current = current[part];
|
|
761
343
|
}
|
|
762
|
-
return
|
|
344
|
+
return current;
|
|
763
345
|
}
|
|
764
|
-
function
|
|
765
|
-
|
|
766
|
-
if (typeof value === "number") return `{${value}}`;
|
|
767
|
-
if (typeof value === "boolean") return `{${value}}`;
|
|
768
|
-
if (value === null || value === void 0) return `{undefined}`;
|
|
769
|
-
return `{${JSON.stringify(value)}}`;
|
|
346
|
+
function hasTemplates(text) {
|
|
347
|
+
return /\{\{.+?\}\}/.test(text);
|
|
770
348
|
}
|
|
771
|
-
function
|
|
772
|
-
if (node === null || node === void 0) return
|
|
349
|
+
function nodeToWebflow(node, ctx, instanceProps) {
|
|
350
|
+
if (node === null || node === void 0) return [];
|
|
773
351
|
if (typeof node === "string") {
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
`;
|
|
777
|
-
}
|
|
778
|
-
return `${ind(ctx)}${escapeJSX(node)}
|
|
779
|
-
`;
|
|
352
|
+
const text = instanceProps ? resolveTemplate(node, instanceProps) : node;
|
|
353
|
+
return [{ tag: "span", textContent: text }];
|
|
780
354
|
}
|
|
781
355
|
if (typeof node === "number") {
|
|
782
|
-
return
|
|
783
|
-
`;
|
|
356
|
+
return [{ tag: "span", textContent: String(node) }];
|
|
784
357
|
}
|
|
785
358
|
if (Array.isArray(node)) {
|
|
786
|
-
|
|
359
|
+
const results = [];
|
|
787
360
|
for (let i = 0; i < node.length; i++) {
|
|
788
361
|
const child = node[i];
|
|
789
362
|
const savedPath = [...ctx.elementPath];
|
|
790
363
|
ctx.elementPath = [...ctx.elementPath, i];
|
|
791
|
-
|
|
364
|
+
results.push(...nodeToWebflow(child, ctx, instanceProps));
|
|
792
365
|
ctx.elementPath = savedPath;
|
|
793
366
|
}
|
|
794
|
-
return
|
|
367
|
+
return results;
|
|
795
368
|
}
|
|
796
369
|
switch (node.type) {
|
|
797
370
|
case NODE_TYPE.NODE:
|
|
798
|
-
return emitHtmlNode(node, ctx);
|
|
371
|
+
return [emitHtmlNode(node, ctx, instanceProps)];
|
|
799
372
|
case NODE_TYPE.COMPONENT:
|
|
800
|
-
return emitComponentInstance(node, ctx);
|
|
373
|
+
return emitComponentInstance(node, ctx, instanceProps);
|
|
801
374
|
case NODE_TYPE.SLOT:
|
|
802
|
-
return emitSlotMarker(node, ctx);
|
|
375
|
+
return emitSlotMarker(node, ctx, instanceProps);
|
|
803
376
|
case NODE_TYPE.EMBED:
|
|
804
|
-
return emitEmbedNode(node, ctx);
|
|
377
|
+
return [emitEmbedNode(node, ctx, instanceProps)];
|
|
805
378
|
case NODE_TYPE.LINK:
|
|
806
|
-
return emitLinkNode(node, ctx);
|
|
807
|
-
case NODE_TYPE.LOCALE_LIST:
|
|
808
|
-
return emitFallback(ctx);
|
|
379
|
+
return [emitLinkNode(node, ctx, instanceProps)];
|
|
809
380
|
case NODE_TYPE.LIST:
|
|
810
381
|
case "cms-list":
|
|
811
|
-
|
|
382
|
+
case NODE_TYPE.LOCALE_LIST:
|
|
383
|
+
return [{ tag: "div", attributes: { "data-meno-type": node.type } }];
|
|
812
384
|
default:
|
|
813
|
-
return
|
|
385
|
+
return [];
|
|
814
386
|
}
|
|
815
387
|
}
|
|
816
|
-
function emitHtmlNode(node, ctx) {
|
|
817
|
-
|
|
818
|
-
const label = node.label;
|
|
388
|
+
function emitHtmlNode(node, ctx, instanceProps) {
|
|
389
|
+
const tag = hasTemplates(node.tag) && instanceProps ? resolveTemplate(node.tag, instanceProps) : node.tag;
|
|
819
390
|
const style = node.style;
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
const
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
return `${ifExpr}${ind(ctx)}<${tag}${classExpr}${styleAttr}${attrs} />
|
|
840
|
-
${emitIfClose(node, ctx)}`;
|
|
841
|
-
}
|
|
842
|
-
const children = emitChildren(node.children, ctx);
|
|
843
|
-
if (!children.trim() && !isDynamic) {
|
|
844
|
-
return `${ifExpr}${ind(ctx)}<${tag}${classExpr}${styleAttr}${attrs} />
|
|
845
|
-
${emitIfClose(node, ctx)}`;
|
|
846
|
-
}
|
|
847
|
-
return `${ifExpr}${ind(ctx)}<${openClose}${classExpr}${styleAttr}${attrs}>
|
|
848
|
-
` + children + `${ind(ctx)}</${openClose}>
|
|
849
|
-
${emitIfClose(node, ctx)}`;
|
|
850
|
-
}
|
|
851
|
-
function emitComponentInstance(node, ctx) {
|
|
852
|
-
const name = node.component;
|
|
853
|
-
ctx.imports.add(name);
|
|
854
|
-
const ifExpr = emitIfOpen(node, ctx);
|
|
855
|
-
const propParts = [];
|
|
856
|
-
if (node.props) {
|
|
857
|
-
for (const [key, value] of Object.entries(node.props)) {
|
|
858
|
-
if (key === "children") continue;
|
|
859
|
-
if (typeof value === "string" && hasTemplates(value) && ctx.isComponentDef) {
|
|
860
|
-
const fullMatch = value.match(/^\{\{(.+)\}\}$/);
|
|
861
|
-
if (fullMatch) {
|
|
862
|
-
propParts.push(`${key}={${fullMatch[1].trim()}}`);
|
|
863
|
-
} else {
|
|
864
|
-
const resolved = value.replace(/\{\{(.+?)\}\}/g, (_, expr) => `\${${expr.trim()}}`);
|
|
865
|
-
propParts.push(`${key}={\`${resolved}\`}`);
|
|
866
|
-
}
|
|
867
|
-
} else {
|
|
868
|
-
propParts.push(`${key}=${formatPropValue(value)}`);
|
|
391
|
+
const interactiveStyles = node.interactiveStyles;
|
|
392
|
+
const needsClass = style || interactiveStyles && interactiveStyles.length > 0 || node.generateElementClass;
|
|
393
|
+
let className;
|
|
394
|
+
let comboClassNames;
|
|
395
|
+
if (needsClass) {
|
|
396
|
+
const elementClass = buildElementClass(ctx, node.label);
|
|
397
|
+
const { primaryClass, comboClasses } = mapStylesToWebflow(
|
|
398
|
+
elementClass,
|
|
399
|
+
style,
|
|
400
|
+
interactiveStyles,
|
|
401
|
+
ctx.breakpoints
|
|
402
|
+
);
|
|
403
|
+
className = primaryClass.name;
|
|
404
|
+
ctx.styleClasses.set(primaryClass.name, primaryClass);
|
|
405
|
+
if (comboClasses.length > 0) {
|
|
406
|
+
comboClassNames = [];
|
|
407
|
+
for (const combo of comboClasses) {
|
|
408
|
+
ctx.styleClasses.set(combo.name, combo);
|
|
409
|
+
comboClassNames.push(combo.name);
|
|
869
410
|
}
|
|
870
411
|
}
|
|
871
412
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
if (!children.trim()) {
|
|
881
|
-
return `${ifExpr}${ind(ctx)}<${name}${propsStr} />
|
|
882
|
-
${emitIfClose(node, ctx)}`;
|
|
883
|
-
}
|
|
884
|
-
return `${ifExpr}${ind(ctx)}<${name}${propsStr}>
|
|
885
|
-
` + children + `${ind(ctx)}</${name}>
|
|
886
|
-
${emitIfClose(node, ctx)}`;
|
|
887
|
-
}
|
|
888
|
-
function emitSlotMarker(node, ctx) {
|
|
889
|
-
if (node.default) {
|
|
890
|
-
const defaultContent = emitChildren(node.default, ctx);
|
|
891
|
-
if (defaultContent.trim()) {
|
|
892
|
-
return `${ind(ctx)}<slot>
|
|
893
|
-
` + defaultContent + `${ind(ctx)}</slot>
|
|
894
|
-
`;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
return `${ind(ctx)}<slot />
|
|
898
|
-
`;
|
|
899
|
-
}
|
|
900
|
-
function emitEmbedNode(node, ctx) {
|
|
901
|
-
const ifExpr = emitIfOpen(node, ctx);
|
|
902
|
-
const style = node.style;
|
|
903
|
-
let elementClass = null;
|
|
904
|
-
if (node.interactiveStyles && node.interactiveStyles.length > 0 || node.generateElementClass) {
|
|
905
|
-
elementClass = buildElementClass(ctx, node.label);
|
|
906
|
-
}
|
|
907
|
-
const { classExpr, styleAttr } = buildClassAndStyleExpression(style, node.interactiveStyles, elementClass, ctx);
|
|
908
|
-
const attrs = buildAttributesString(node.attributes, ctx);
|
|
909
|
-
if (isHtmlMapping(node.html)) {
|
|
910
|
-
if (ctx.isComponentDef) {
|
|
911
|
-
const propRef = node.html.prop;
|
|
912
|
-
return `${ifExpr}${ind(ctx)}<div${classExpr.replace('"', '"oem ') || ' class="oem"'}${attrs}>
|
|
913
|
-
${ind(ctx)} <Fragment set:html={${propRef}} />
|
|
914
|
-
${ind(ctx)}</div>
|
|
915
|
-
${emitIfClose(node, ctx)}`;
|
|
413
|
+
const attributes = {};
|
|
414
|
+
if (node.attributes) {
|
|
415
|
+
for (const [key, value] of Object.entries(node.attributes)) {
|
|
416
|
+
if (instanceProps && typeof value === "string" && hasTemplates(value)) {
|
|
417
|
+
attributes[key] = resolveTemplate(value, instanceProps);
|
|
418
|
+
} else {
|
|
419
|
+
attributes[key] = value;
|
|
420
|
+
}
|
|
916
421
|
}
|
|
917
422
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
423
|
+
let children;
|
|
424
|
+
let textContent;
|
|
425
|
+
if (!isVoidElement(tag) && node.children) {
|
|
426
|
+
if (typeof node.children === "string") {
|
|
427
|
+
textContent = instanceProps ? resolveTemplate(node.children, instanceProps) : node.children;
|
|
428
|
+
} else if (Array.isArray(node.children) && node.children.length === 1 && typeof node.children[0] === "string") {
|
|
429
|
+
const text = node.children[0];
|
|
430
|
+
textContent = instanceProps ? resolveTemplate(text, instanceProps) : text;
|
|
924
431
|
} else {
|
|
925
|
-
|
|
432
|
+
const innerCtx = { ...ctx, elementPath: [...ctx.elementPath] };
|
|
433
|
+
children = convertChildren(node.children, innerCtx, instanceProps);
|
|
434
|
+
if (children.length === 0) children = void 0;
|
|
926
435
|
}
|
|
927
436
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
if (
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
437
|
+
let conditional;
|
|
438
|
+
const ifValue = node.if;
|
|
439
|
+
if (ifValue !== void 0 && ifValue !== true) {
|
|
440
|
+
if (typeof ifValue === "object" && ifValue._mapping) {
|
|
441
|
+
conditional = { prop: ifValue.prop, condition: "truthy" };
|
|
442
|
+
} else if (typeof ifValue === "string") {
|
|
443
|
+
const match = ifValue.match(/^\{\{(.+)\}\}$/);
|
|
444
|
+
conditional = { prop: match ? match[1].trim() : ifValue, condition: "truthy" };
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
const element = { tag };
|
|
448
|
+
if (className) element.className = className;
|
|
449
|
+
if (comboClassNames) element.comboClasses = comboClassNames;
|
|
450
|
+
if (textContent) element.textContent = textContent;
|
|
451
|
+
if (children) element.children = children;
|
|
452
|
+
if (Object.keys(attributes).length > 0) element.attributes = attributes;
|
|
453
|
+
if (conditional) element.conditional = conditional;
|
|
454
|
+
return element;
|
|
455
|
+
}
|
|
456
|
+
function emitComponentInstance(node, ctx, parentProps) {
|
|
457
|
+
const compDef = ctx.globalComponents[node.component];
|
|
458
|
+
if (!compDef) {
|
|
459
|
+
return [{ tag: "div", attributes: { "data-component": node.component } }];
|
|
460
|
+
}
|
|
461
|
+
const resolvedProps = {};
|
|
462
|
+
const structured = compDef.component;
|
|
463
|
+
if (structured?.interface) {
|
|
464
|
+
for (const [key, propDef] of Object.entries(structured.interface)) {
|
|
465
|
+
resolvedProps[key] = propDef.default;
|
|
947
466
|
}
|
|
948
467
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
} else {
|
|
955
|
-
hrefAttr = ' href="#"';
|
|
956
|
-
}
|
|
957
|
-
} else {
|
|
958
|
-
const href = typeof node.href === "string" ? node.href : "#";
|
|
959
|
-
if (hasTemplates(href) && ctx.isComponentDef) {
|
|
960
|
-
const fullMatch = href.match(/^\{\{(.+)\}\}$/);
|
|
961
|
-
if (fullMatch) {
|
|
962
|
-
hrefAttr = ` href={${fullMatch[1].trim()}}`;
|
|
468
|
+
if (node.props) {
|
|
469
|
+
for (const [key, value] of Object.entries(node.props)) {
|
|
470
|
+
if (key === "children") continue;
|
|
471
|
+
if (typeof value === "string" && hasTemplates(value) && parentProps) {
|
|
472
|
+
resolvedProps[key] = resolveTemplate(value, parentProps);
|
|
963
473
|
} else {
|
|
964
|
-
|
|
965
|
-
hrefAttr = ` href={\`${resolved}\`}`;
|
|
474
|
+
resolvedProps[key] = value;
|
|
966
475
|
}
|
|
967
|
-
} else {
|
|
968
|
-
hrefAttr = ` href="${escapeJSX(href)}"`;
|
|
969
476
|
}
|
|
970
477
|
}
|
|
971
|
-
const
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
${emitIfClose(node, ctx)}`;
|
|
976
|
-
}
|
|
977
|
-
return `${ifExpr}${ind(ctx)}<a${hrefAttr}${finalClassExpr}${styleAttr}${attrs}>
|
|
978
|
-
` + children + `${ind(ctx)}</a>
|
|
979
|
-
${emitIfClose(node, ctx)}`;
|
|
980
|
-
}
|
|
981
|
-
function emitFallback(ctx) {
|
|
982
|
-
const pathKey = ctx.elementPath.join(".");
|
|
983
|
-
const ssrHtml = ctx.ssrFallbacks.get(pathKey);
|
|
984
|
-
if (ssrHtml) {
|
|
985
|
-
const escaped = escapeTemplateLiteral(ssrHtml);
|
|
986
|
-
return `${ind(ctx)}<Fragment set:html={\`${escaped}\`} />
|
|
987
|
-
`;
|
|
988
|
-
}
|
|
989
|
-
return `${ind(ctx)}{/* Complex node - SSR fallback not available */}
|
|
990
|
-
`;
|
|
991
|
-
}
|
|
992
|
-
function emitIfOpen(node, ctx) {
|
|
993
|
-
const ifValue = node.if;
|
|
994
|
-
if (ifValue === void 0 || ifValue === true) return "";
|
|
995
|
-
if (typeof ifValue === "boolean") {
|
|
996
|
-
return ifValue ? "" : `${ind(ctx)}{/* hidden */}
|
|
997
|
-
`;
|
|
998
|
-
}
|
|
999
|
-
if (typeof ifValue === "object" && ifValue._mapping && ctx.isComponentDef) {
|
|
1000
|
-
return `${ind(ctx)}{${ifValue.prop} && (
|
|
1001
|
-
`;
|
|
1002
|
-
}
|
|
1003
|
-
if (typeof ifValue === "string" && ctx.isComponentDef) {
|
|
1004
|
-
const fullMatch = ifValue.match(/^\{\{(.+)\}\}$/);
|
|
1005
|
-
const expr = fullMatch ? fullMatch[1].trim() : ifValue.replace(/\{\{(.+?)\}\}/g, "$1");
|
|
1006
|
-
return `${ind(ctx)}{${expr} && (
|
|
1007
|
-
`;
|
|
1008
|
-
}
|
|
1009
|
-
return "";
|
|
1010
|
-
}
|
|
1011
|
-
function emitIfClose(node, ctx) {
|
|
1012
|
-
const ifValue = node.if;
|
|
1013
|
-
if (ifValue === void 0 || ifValue === true) return "";
|
|
1014
|
-
if (typeof ifValue === "boolean") return "";
|
|
1015
|
-
if (typeof ifValue === "object" && ifValue._mapping && ctx.isComponentDef || typeof ifValue === "string" && ctx.isComponentDef) {
|
|
1016
|
-
return `${ind(ctx)})}
|
|
1017
|
-
`;
|
|
1018
|
-
}
|
|
1019
|
-
return "";
|
|
1020
|
-
}
|
|
1021
|
-
function emitChildren(children, ctx) {
|
|
1022
|
-
if (!children) return "";
|
|
1023
|
-
const innerCtx = { ...ctx, indent: ctx.indent + 1, elementPath: [...ctx.elementPath] };
|
|
1024
|
-
if (typeof children === "string") {
|
|
1025
|
-
return nodeToAstro(children, innerCtx);
|
|
1026
|
-
}
|
|
1027
|
-
if (Array.isArray(children)) {
|
|
1028
|
-
return nodeToAstro(children, innerCtx);
|
|
1029
|
-
}
|
|
1030
|
-
return nodeToAstro(children, innerCtx);
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
// lib/server/astro/componentEmitter.ts
|
|
1034
|
-
function propDefToTSType(def) {
|
|
1035
|
-
switch (def.type) {
|
|
1036
|
-
case "string":
|
|
1037
|
-
case "rich-text":
|
|
1038
|
-
case "file":
|
|
1039
|
-
return "string";
|
|
1040
|
-
case "number":
|
|
1041
|
-
return "number";
|
|
1042
|
-
case "boolean":
|
|
1043
|
-
return "boolean";
|
|
1044
|
-
case "select":
|
|
1045
|
-
if ("options" in def && def.options && def.options.length > 0) {
|
|
1046
|
-
return def.options.map((o) => `'${o}'`).join(" | ");
|
|
1047
|
-
}
|
|
1048
|
-
return "string";
|
|
1049
|
-
case "link":
|
|
1050
|
-
return "{ href: string; target?: string }";
|
|
1051
|
-
case "list":
|
|
1052
|
-
return "any[]";
|
|
1053
|
-
default:
|
|
1054
|
-
return "any";
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
function formatDefault(def) {
|
|
1058
|
-
if (!("default" in def) || def.default === void 0) return null;
|
|
1059
|
-
const val = def.default;
|
|
1060
|
-
if (typeof val === "string") return JSON.stringify(val);
|
|
1061
|
-
if (typeof val === "number" || typeof val === "boolean") return String(val);
|
|
1062
|
-
if (typeof val === "object" && val !== null && "_i18n" in val) {
|
|
1063
|
-
for (const [key, v] of Object.entries(val)) {
|
|
1064
|
-
if (key !== "_i18n" && typeof v === "string") return JSON.stringify(v);
|
|
1065
|
-
}
|
|
1066
|
-
return null;
|
|
1067
|
-
}
|
|
1068
|
-
if (typeof val === "object" && val !== null && "href" in val) {
|
|
1069
|
-
return JSON.stringify(val);
|
|
1070
|
-
}
|
|
1071
|
-
if (Array.isArray(val)) {
|
|
1072
|
-
return JSON.stringify(val);
|
|
1073
|
-
}
|
|
1074
|
-
return JSON.stringify(val);
|
|
1075
|
-
}
|
|
1076
|
-
function emitAstroComponent(name, def, allComponents, breakpoints = DEFAULT_BREAKPOINTS) {
|
|
1077
|
-
const comp = def.component;
|
|
1078
|
-
const propDefs = comp.interface || {};
|
|
1079
|
-
const structure = comp.structure;
|
|
1080
|
-
if (!structure) {
|
|
1081
|
-
return buildNoStructureComponent(name, comp);
|
|
1082
|
-
}
|
|
1083
|
-
const ctx = {
|
|
1084
|
-
imports: /* @__PURE__ */ new Set(),
|
|
1085
|
-
isComponentDef: true,
|
|
1086
|
-
componentProps: propDefs,
|
|
1087
|
-
globalComponents: allComponents,
|
|
1088
|
-
indent: 0,
|
|
1089
|
-
ssrFallbacks: /* @__PURE__ */ new Map(),
|
|
1090
|
-
elementPath: [0],
|
|
478
|
+
const body = structured?.structure || compDef.node;
|
|
479
|
+
if (!body) return [];
|
|
480
|
+
const compCtx = {
|
|
481
|
+
...ctx,
|
|
1091
482
|
fileType: "component",
|
|
1092
|
-
fileName:
|
|
1093
|
-
|
|
483
|
+
fileName: node.component,
|
|
484
|
+
elementPath: [0],
|
|
485
|
+
slotChildren: node.children
|
|
1094
486
|
};
|
|
1095
|
-
|
|
1096
|
-
const frontmatter = buildFrontmatter(name, propDefs, ctx.imports, ctx.dynamicTags);
|
|
1097
|
-
const styleSection = comp.css ? `
|
|
1098
|
-
<style>
|
|
1099
|
-
${comp.css}
|
|
1100
|
-
</style>
|
|
1101
|
-
` : "";
|
|
1102
|
-
const scriptSection = comp.javascript ? `
|
|
1103
|
-
<script>
|
|
1104
|
-
${comp.javascript}
|
|
1105
|
-
</script>
|
|
1106
|
-
` : "";
|
|
1107
|
-
return `---
|
|
1108
|
-
${frontmatter}---
|
|
1109
|
-
${templateBody}${styleSection}${scriptSection}`;
|
|
487
|
+
return nodeToWebflow(body, compCtx, resolvedProps);
|
|
1110
488
|
}
|
|
1111
|
-
function
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
lines.push("interface Props {");
|
|
1120
|
-
for (const [propName, propDef] of propEntries) {
|
|
1121
|
-
if (propName === "children") continue;
|
|
1122
|
-
const tsType = propDefToTSType(propDef);
|
|
1123
|
-
const optional = "default" in propDef && propDef.default !== void 0;
|
|
1124
|
-
lines.push(` ${propName}${optional ? "?" : ""}: ${tsType};`);
|
|
1125
|
-
}
|
|
1126
|
-
lines.push("}");
|
|
1127
|
-
lines.push("");
|
|
1128
|
-
const destructParts = [];
|
|
1129
|
-
for (const [propName, propDef] of propEntries) {
|
|
1130
|
-
if (propName === "children") continue;
|
|
1131
|
-
const defaultVal = formatDefault(propDef);
|
|
1132
|
-
if (defaultVal !== null) {
|
|
1133
|
-
destructParts.push(`${propName} = ${defaultVal}`);
|
|
1134
|
-
} else {
|
|
1135
|
-
destructParts.push(propName);
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
if (destructParts.length > 0) {
|
|
1139
|
-
if (destructParts.length <= 3 && destructParts.join(", ").length < 80) {
|
|
1140
|
-
lines.push(`const { ${destructParts.join(", ")} } = Astro.props;`);
|
|
1141
|
-
} else {
|
|
1142
|
-
lines.push("const {");
|
|
1143
|
-
for (const part of destructParts) {
|
|
1144
|
-
lines.push(` ${part},`);
|
|
1145
|
-
}
|
|
1146
|
-
lines.push("} = Astro.props;");
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
489
|
+
function emitSlotMarker(node, ctx, instanceProps) {
|
|
490
|
+
if (ctx.slotChildren) {
|
|
491
|
+
const parentCtx = {
|
|
492
|
+
...ctx,
|
|
493
|
+
slotChildren: void 0
|
|
494
|
+
// prevent infinite slot nesting
|
|
495
|
+
};
|
|
496
|
+
return convertChildren(ctx.slotChildren, parentCtx, instanceProps);
|
|
1149
497
|
}
|
|
1150
|
-
if (
|
|
1151
|
-
|
|
1152
|
-
for (const [varName, templateExpr] of dynamicTags) {
|
|
1153
|
-
lines.push(`const ${varName} = \`${templateExpr}\`;`);
|
|
1154
|
-
}
|
|
498
|
+
if (node.default) {
|
|
499
|
+
return convertChildren(node.default, ctx, instanceProps);
|
|
1155
500
|
}
|
|
1156
|
-
|
|
1157
|
-
return lines.join("\n");
|
|
1158
|
-
}
|
|
1159
|
-
function buildNoStructureComponent(name, comp) {
|
|
1160
|
-
let content = "---\n---\n<slot />\n";
|
|
1161
|
-
if (comp.css) content += `
|
|
1162
|
-
<style>
|
|
1163
|
-
${comp.css}
|
|
1164
|
-
</style>
|
|
1165
|
-
`;
|
|
1166
|
-
if (comp.javascript) content += `
|
|
1167
|
-
<script>
|
|
1168
|
-
${comp.javascript}
|
|
1169
|
-
</script>
|
|
1170
|
-
`;
|
|
1171
|
-
return content;
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
// lib/server/astro/pageEmitter.ts
|
|
1175
|
-
function escapeTemplateLiteral2(s) {
|
|
1176
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
501
|
+
return [];
|
|
1177
502
|
}
|
|
1178
|
-
function
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
theme,
|
|
1193
|
-
fontPreloads,
|
|
1194
|
-
libraryTags,
|
|
1195
|
-
scriptPaths,
|
|
1196
|
-
layoutImportPath: layoutImportPath2,
|
|
1197
|
-
fileDepth,
|
|
1198
|
-
ssrFallbacks,
|
|
1199
|
-
pageName,
|
|
1200
|
-
breakpoints: breakpointsOpt
|
|
1201
|
-
} = options;
|
|
1202
|
-
const breakpoints = breakpointsOpt ?? DEFAULT_BREAKPOINTS;
|
|
1203
|
-
const root = pageData.root;
|
|
1204
|
-
if (!root) {
|
|
1205
|
-
return buildEmptyPage(layoutImportPath2, title, meta, locale, theme, fontPreloads, libraryTags, scriptPaths);
|
|
503
|
+
function emitEmbedNode(node, ctx, instanceProps) {
|
|
504
|
+
const style = node.style;
|
|
505
|
+
const interactiveStyles = node.interactiveStyles;
|
|
506
|
+
let className;
|
|
507
|
+
if (style || interactiveStyles && interactiveStyles.length > 0) {
|
|
508
|
+
const elementClass = buildElementClass(ctx, node.label);
|
|
509
|
+
const { primaryClass } = mapStylesToWebflow(
|
|
510
|
+
elementClass,
|
|
511
|
+
style,
|
|
512
|
+
interactiveStyles,
|
|
513
|
+
ctx.breakpoints
|
|
514
|
+
);
|
|
515
|
+
className = primaryClass.name;
|
|
516
|
+
ctx.styleClasses.set(primaryClass.name, primaryClass);
|
|
1206
517
|
}
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
globalComponents,
|
|
1212
|
-
indent: 1,
|
|
1213
|
-
// inside BaseLayout
|
|
1214
|
-
ssrFallbacks,
|
|
1215
|
-
elementPath: [0],
|
|
1216
|
-
fileType: "page",
|
|
1217
|
-
fileName: pageName,
|
|
1218
|
-
breakpoints
|
|
518
|
+
const htmlStr = typeof node.html === "string" ? node.html : "";
|
|
519
|
+
const element = {
|
|
520
|
+
tag: "div",
|
|
521
|
+
rawHtml: htmlStr
|
|
1219
522
|
};
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
importLines.push(`import BaseLayout from '${layoutImportPath2}';`);
|
|
1223
|
-
const componentImports = Array.from(ctx.imports).sort();
|
|
1224
|
-
for (const comp of componentImports) {
|
|
1225
|
-
const path = componentImportPath(fileDepth, comp);
|
|
1226
|
-
importLines.push(`import ${comp} from '${path}';`);
|
|
1227
|
-
}
|
|
1228
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
1229
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral2(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral2(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral2(libraryTags.bodyEndJS || "")}\` }`;
|
|
1230
|
-
const escapedMeta = escapeTemplateLiteral2(meta);
|
|
1231
|
-
const escapedFontPreloads = escapeTemplateLiteral2(fontPreloads);
|
|
1232
|
-
return `---
|
|
1233
|
-
${importLines.join("\n")}
|
|
1234
|
-
---
|
|
1235
|
-
<BaseLayout
|
|
1236
|
-
title="${escapeJSX2(title)}"
|
|
1237
|
-
meta={\`${escapedMeta}\`}
|
|
1238
|
-
scripts={${scriptsArrayLiteral}}
|
|
1239
|
-
locale="${locale}"
|
|
1240
|
-
theme="${theme}"
|
|
1241
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
1242
|
-
libraryTags={${libraryTagsLiteral}}
|
|
1243
|
-
>
|
|
1244
|
-
${templateBody}</BaseLayout>
|
|
1245
|
-
`;
|
|
1246
|
-
}
|
|
1247
|
-
function buildEmptyPage(layoutImport, title, meta, locale, theme, fontPreloads, libraryTags, scriptPaths) {
|
|
1248
|
-
const escapedMeta = escapeTemplateLiteral2(meta);
|
|
1249
|
-
const escapedFontPreloads = escapeTemplateLiteral2(fontPreloads);
|
|
1250
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
1251
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral2(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral2(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral2(libraryTags.bodyEndJS || "")}\` }`;
|
|
1252
|
-
return `---
|
|
1253
|
-
import BaseLayout from '${layoutImport}';
|
|
1254
|
-
---
|
|
1255
|
-
<BaseLayout
|
|
1256
|
-
title="${escapeJSX2(title)}"
|
|
1257
|
-
meta={\`${escapedMeta}\`}
|
|
1258
|
-
scripts={${scriptsArrayLiteral}}
|
|
1259
|
-
locale="${locale}"
|
|
1260
|
-
theme="${theme}"
|
|
1261
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
1262
|
-
libraryTags={${libraryTagsLiteral}}
|
|
1263
|
-
>
|
|
1264
|
-
</BaseLayout>
|
|
1265
|
-
`;
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
// lib/server/astro/cssCollector.ts
|
|
1269
|
-
function isStyleMapping3(value) {
|
|
1270
|
-
return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
|
|
523
|
+
if (className) element.className = className;
|
|
524
|
+
return element;
|
|
1271
525
|
}
|
|
1272
|
-
function
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
if (
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
return;
|
|
1311
|
-
}
|
|
1312
|
-
if ("style" in node && node.style) {
|
|
1313
|
-
collectFromStyle(node.style, classes, breakpoints);
|
|
1314
|
-
}
|
|
1315
|
-
if ("interactiveStyles" in node && Array.isArray(node.interactiveStyles)) {
|
|
1316
|
-
for (const rule of node.interactiveStyles) {
|
|
1317
|
-
if (rule.style) {
|
|
1318
|
-
collectFromStyle(rule.style, classes, breakpoints);
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
if ("children" in node && node.children) {
|
|
1323
|
-
if (Array.isArray(node.children)) {
|
|
1324
|
-
for (const child of node.children) {
|
|
1325
|
-
walkNode(child, classes, breakpoints);
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
526
|
+
function emitLinkNode(node, ctx, instanceProps) {
|
|
527
|
+
const style = node.style;
|
|
528
|
+
const interactiveStyles = node.interactiveStyles;
|
|
529
|
+
let className;
|
|
530
|
+
if (style || interactiveStyles && interactiveStyles.length > 0) {
|
|
531
|
+
const elementClass = buildElementClass(ctx, node.label);
|
|
532
|
+
const { primaryClass } = mapStylesToWebflow(
|
|
533
|
+
elementClass,
|
|
534
|
+
style,
|
|
535
|
+
interactiveStyles,
|
|
536
|
+
ctx.breakpoints
|
|
537
|
+
);
|
|
538
|
+
className = primaryClass.name;
|
|
539
|
+
ctx.styleClasses.set(primaryClass.name, primaryClass);
|
|
540
|
+
}
|
|
541
|
+
let href = "#";
|
|
542
|
+
if (typeof node.href === "string") {
|
|
543
|
+
href = instanceProps && hasTemplates(node.href) ? resolveTemplate(node.href, instanceProps) : node.href;
|
|
544
|
+
}
|
|
545
|
+
const attributes = { href };
|
|
546
|
+
if (node.attributes) {
|
|
547
|
+
for (const [key, value] of Object.entries(node.attributes)) {
|
|
548
|
+
attributes[key] = value;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
let children;
|
|
552
|
+
if (node.children) {
|
|
553
|
+
children = convertChildren(node.children, ctx, instanceProps);
|
|
554
|
+
if (children.length === 0) children = void 0;
|
|
555
|
+
}
|
|
556
|
+
const element = { tag: "a", attributes };
|
|
557
|
+
if (className) element.className = className;
|
|
558
|
+
if (children) element.children = children;
|
|
559
|
+
return element;
|
|
560
|
+
}
|
|
561
|
+
function convertChildren(children, ctx, instanceProps) {
|
|
562
|
+
if (!children) return [];
|
|
563
|
+
if (typeof children === "string") {
|
|
564
|
+
return nodeToWebflow(children, ctx, instanceProps);
|
|
1328
565
|
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
const classes = /* @__PURE__ */ new Set();
|
|
1332
|
-
for (const def of Object.values(componentDefs)) {
|
|
1333
|
-
const structure = def.component?.structure;
|
|
1334
|
-
if (structure) {
|
|
1335
|
-
walkNode(structure, classes, breakpoints);
|
|
1336
|
-
}
|
|
566
|
+
if (Array.isArray(children)) {
|
|
567
|
+
return nodeToWebflow(children, ctx, instanceProps);
|
|
1337
568
|
}
|
|
1338
|
-
return
|
|
569
|
+
return nodeToWebflow(children, ctx, instanceProps);
|
|
1339
570
|
}
|
|
1340
571
|
|
|
1341
|
-
//
|
|
1342
|
-
function
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
const stat = statSync(srcPath);
|
|
1353
|
-
if (stat.isDirectory()) copyDirectory(srcPath, destPath);
|
|
1354
|
-
else copyFileSync(srcPath, destPath);
|
|
572
|
+
// lib/server/webflow/buildWebflow.ts
|
|
573
|
+
function scanJSONFiles(dir, prefix = "") {
|
|
574
|
+
const results = [];
|
|
575
|
+
if (!existsSync(dir)) return results;
|
|
576
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
577
|
+
for (const entry of entries) {
|
|
578
|
+
if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
579
|
+
results.push(prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
580
|
+
} else if (entry.isDirectory()) {
|
|
581
|
+
results.push(...scanJSONFiles(join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name));
|
|
582
|
+
}
|
|
1355
583
|
}
|
|
584
|
+
return results;
|
|
1356
585
|
}
|
|
1357
586
|
function isCMSPage(pageData) {
|
|
1358
587
|
return pageData.meta?.source === "cms" && !!pageData.meta?.cms;
|
|
@@ -1364,132 +593,81 @@ function buildCMSItemPath(urlPattern, item, slugField, locale, i18nConfig) {
|
|
|
1364
593
|
}
|
|
1365
594
|
return urlPattern.replace("{{slug}}", String(slug));
|
|
1366
595
|
}
|
|
1367
|
-
function
|
|
596
|
+
function scanAssets(projectRoot) {
|
|
597
|
+
const assets = [];
|
|
598
|
+
const assetDirs = [
|
|
599
|
+
{ dir: "images", type: "image" },
|
|
600
|
+
{ dir: "fonts", type: "font" },
|
|
601
|
+
{ dir: "videos", type: "video" },
|
|
602
|
+
{ dir: "assets", type: "file" }
|
|
603
|
+
];
|
|
604
|
+
for (const { dir, type } of assetDirs) {
|
|
605
|
+
const fullDir = join(projectRoot, dir);
|
|
606
|
+
if (!existsSync(fullDir)) continue;
|
|
607
|
+
const files = scanJSONFiles(fullDir).map((f) => f.replace(".json", ""));
|
|
608
|
+
const allFiles = scanAllFiles(fullDir);
|
|
609
|
+
for (const file of allFiles) {
|
|
610
|
+
assets.push({
|
|
611
|
+
localPath: `${dir}/${file}`,
|
|
612
|
+
type,
|
|
613
|
+
fileName: file.split("/").pop()
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return assets;
|
|
618
|
+
}
|
|
619
|
+
function scanAllFiles(dir, prefix = "") {
|
|
1368
620
|
const results = [];
|
|
1369
621
|
if (!existsSync(dir)) return results;
|
|
1370
622
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
1371
623
|
for (const entry of entries) {
|
|
1372
|
-
|
|
1373
|
-
|
|
624
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
625
|
+
if (entry.isFile()) {
|
|
626
|
+
results.push(relativePath);
|
|
1374
627
|
} else if (entry.isDirectory()) {
|
|
1375
|
-
results.push(...
|
|
628
|
+
results.push(...scanAllFiles(join(dir, entry.name), relativePath));
|
|
1376
629
|
}
|
|
1377
630
|
}
|
|
1378
631
|
return results;
|
|
1379
632
|
}
|
|
1380
|
-
function
|
|
1381
|
-
const
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
switch (field.type) {
|
|
1389
|
-
case "string":
|
|
1390
|
-
case "text":
|
|
1391
|
-
case "rich-text":
|
|
1392
|
-
return "z.string()";
|
|
1393
|
-
case "number":
|
|
1394
|
-
return "z.number()";
|
|
1395
|
-
case "boolean":
|
|
1396
|
-
return "z.boolean()";
|
|
1397
|
-
case "date":
|
|
1398
|
-
return "z.coerce.date()";
|
|
1399
|
-
case "select":
|
|
1400
|
-
if (field.options && field.options.length > 0) {
|
|
1401
|
-
const opts = field.options.map((o) => `'${o.replace(/'/g, "\\'")}'`).join(", ");
|
|
1402
|
-
return `z.enum([${opts}])`;
|
|
1403
|
-
}
|
|
1404
|
-
return "z.string()";
|
|
1405
|
-
case "image":
|
|
1406
|
-
case "file":
|
|
1407
|
-
return "z.string()";
|
|
1408
|
-
case "reference":
|
|
1409
|
-
return "z.string()";
|
|
1410
|
-
default:
|
|
1411
|
-
return "z.string()";
|
|
633
|
+
function extractCSSVariables(themeColorCSS, variablesCSS) {
|
|
634
|
+
const vars = {};
|
|
635
|
+
const regex = /--([\w-]+)\s*:\s*([^;]+)/g;
|
|
636
|
+
for (const css of [themeColorCSS, variablesCSS]) {
|
|
637
|
+
let match;
|
|
638
|
+
while ((match = regex.exec(css)) !== null) {
|
|
639
|
+
vars[`--${match[1]}`] = match[2].trim();
|
|
640
|
+
}
|
|
1412
641
|
}
|
|
642
|
+
return vars;
|
|
1413
643
|
}
|
|
1414
|
-
function
|
|
1415
|
-
const escapedMeta = escapeTemplateLiteral3(result.meta);
|
|
1416
|
-
const escapedHTML = escapeTemplateLiteral3(result.html);
|
|
1417
|
-
const escapedFontPreloads = escapeTemplateLiteral3(fontPreloads);
|
|
1418
|
-
const scriptsArrayLiteral = scriptPaths.length > 0 ? `[${scriptPaths.map((s) => `"${s}"`).join(", ")}]` : "[]";
|
|
1419
|
-
const libraryTagsLiteral = `{ headCSS: \`${escapeTemplateLiteral3(libraryTags.headCSS || "")}\`, headJS: \`${escapeTemplateLiteral3(libraryTags.headJS || "")}\`, bodyEndJS: \`${escapeTemplateLiteral3(libraryTags.bodyEndJS || "")}\` }`;
|
|
1420
|
-
return `---
|
|
1421
|
-
import BaseLayout from '${importPath}';
|
|
1422
|
-
---
|
|
1423
|
-
<BaseLayout
|
|
1424
|
-
title="${result.title.replace(/"/g, """)}"
|
|
1425
|
-
meta={\`${escapedMeta}\`}
|
|
1426
|
-
scripts={${scriptsArrayLiteral}}
|
|
1427
|
-
locale="${result.locale}"
|
|
1428
|
-
theme="${defaultTheme}"
|
|
1429
|
-
fontPreloads={\`${escapedFontPreloads}\`}
|
|
1430
|
-
libraryTags={${libraryTagsLiteral}}
|
|
1431
|
-
>
|
|
1432
|
-
<Fragment set:html={\`<div id="root">${escapedHTML}</div>\`} />
|
|
1433
|
-
</BaseLayout>
|
|
1434
|
-
`;
|
|
1435
|
-
}
|
|
1436
|
-
async function buildAstroProject(projectRoot, outputDir) {
|
|
1437
|
-
const startTime = Date.now();
|
|
1438
|
-
console.log("\u{1F3D7}\uFE0F Building Astro export...\n");
|
|
644
|
+
async function buildWebflowPayload(projectRoot) {
|
|
1439
645
|
configService.reset();
|
|
1440
646
|
const projectConfig = await loadProjectConfig();
|
|
1441
647
|
const siteUrl = projectConfig.siteUrl?.replace(/\/$/, "") || "";
|
|
1442
648
|
const i18nConfig = await loadI18nConfig();
|
|
1443
|
-
console.log(`\u{1F310} Locales: ${i18nConfig.locales.map((l) => l.code).join(", ")} (default: ${i18nConfig.defaultLocale})
|
|
1444
|
-
`);
|
|
1445
649
|
await migrateTemplatesDirectory();
|
|
1446
|
-
const { components
|
|
650
|
+
const { components } = await loadComponentDirectory(projectPaths.components());
|
|
1447
651
|
const globalComponents = {};
|
|
1448
652
|
components.forEach((value, key) => {
|
|
1449
653
|
globalComponents[key] = value;
|
|
1450
654
|
});
|
|
1451
|
-
for (const w of warnings) console.warn(` Warning: ${w}`);
|
|
1452
|
-
for (const e of compErrors) console.error(` Error: ${e}`);
|
|
1453
|
-
console.log(`Loaded ${components.size} global component(s)
|
|
1454
|
-
`);
|
|
1455
655
|
const cmsProvider = new FileSystemCMSProvider(projectPaths.templates(), projectPaths.cms());
|
|
1456
656
|
const cmsService = new CMSService(cmsProvider);
|
|
1457
657
|
await cmsService.initialize();
|
|
1458
|
-
console.log("CMS service initialized\n");
|
|
1459
658
|
const themeConfig = await colorService.loadThemeConfig();
|
|
1460
659
|
const variablesConfig = await variableService.loadConfig();
|
|
1461
660
|
const breakpoints = await loadBreakpointConfig();
|
|
1462
661
|
const responsiveScales = await loadResponsiveScalesConfig();
|
|
1463
662
|
await configService.load();
|
|
1464
|
-
const globalLibraries = configService.getLibraries();
|
|
1465
|
-
const componentLibraries = collectComponentLibraries(globalComponents);
|
|
1466
|
-
const outDir = outputDir || join(projectPaths.project, "astro-export");
|
|
1467
|
-
if (existsSync(outDir)) {
|
|
1468
|
-
rmSync(outDir, { recursive: true, force: true });
|
|
1469
|
-
}
|
|
1470
|
-
mkdirSync(outDir, { recursive: true });
|
|
1471
|
-
const srcDir = join(outDir, "src");
|
|
1472
|
-
const pagesOutDir = join(srcDir, "pages");
|
|
1473
|
-
const layoutsDir = join(srcDir, "layouts");
|
|
1474
|
-
const stylesDir = join(srcDir, "styles");
|
|
1475
|
-
const componentsOutDir = join(srcDir, "components");
|
|
1476
|
-
const publicDir = join(outDir, "public");
|
|
1477
|
-
const scriptsDir = join(publicDir, "_scripts");
|
|
1478
|
-
for (const d of [srcDir, pagesOutDir, layoutsDir, stylesDir, componentsOutDir, publicDir]) {
|
|
1479
|
-
mkdirSync(d, { recursive: true });
|
|
1480
|
-
}
|
|
1481
663
|
const pagesDir = projectPaths.pages();
|
|
1482
664
|
if (!existsSync(pagesDir)) {
|
|
1483
|
-
|
|
1484
|
-
return { pages: 0, cmsPages: 0, collections: 0, errors: 1 };
|
|
665
|
+
return emptyPayload();
|
|
1485
666
|
}
|
|
1486
667
|
const pageFiles = scanJSONFiles(pagesDir);
|
|
1487
668
|
if (pageFiles.length === 0) {
|
|
1488
|
-
|
|
1489
|
-
return { pages: 0, cmsPages: 0, collections: 0, errors: 0 };
|
|
669
|
+
return emptyPayload();
|
|
1490
670
|
}
|
|
1491
|
-
console.log(`Found ${pageFiles.length} page(s) to process
|
|
1492
|
-
`);
|
|
1493
671
|
const slugMappings = [];
|
|
1494
672
|
for (const file of pageFiles) {
|
|
1495
673
|
const pageName = file.replace(".json", "");
|
|
@@ -1505,61 +683,16 @@ async function buildAstroProject(projectRoot, outputDir) {
|
|
|
1505
683
|
} catch {
|
|
1506
684
|
}
|
|
1507
685
|
}
|
|
1508
|
-
const
|
|
1509
|
-
const
|
|
1510
|
-
const allComponentCSS = /* @__PURE__ */ new Set();
|
|
1511
|
-
const jsContents = /* @__PURE__ */ new Map();
|
|
1512
|
-
let errorCount = 0;
|
|
1513
|
-
function mergeInteractiveStyles(source) {
|
|
1514
|
-
for (const [key, value] of source) {
|
|
1515
|
-
if (!allInteractiveStyles.has(key)) {
|
|
1516
|
-
allInteractiveStyles.set(key, value);
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
function processRenderResult(result, urlPath, astroFilePath, fileDepth, pageData, pageName, isCMSPage2) {
|
|
1521
|
-
mergeInteractiveStyles(result.interactiveStylesMap);
|
|
1522
|
-
if (result.componentCSS) {
|
|
1523
|
-
allComponentCSS.add(result.componentCSS);
|
|
1524
|
-
}
|
|
1525
|
-
if (result.javascript) {
|
|
1526
|
-
const hash = hashContent2(result.javascript);
|
|
1527
|
-
if (!jsContents.has(hash)) {
|
|
1528
|
-
jsContents.set(hash, result.javascript);
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
allResults.push({
|
|
1532
|
-
html: result.html,
|
|
1533
|
-
meta: result.meta,
|
|
1534
|
-
title: result.title,
|
|
1535
|
-
javascript: result.javascript,
|
|
1536
|
-
componentCSS: result.componentCSS,
|
|
1537
|
-
locale: result.locale,
|
|
1538
|
-
interactiveStylesMap: result.interactiveStylesMap,
|
|
1539
|
-
urlPath,
|
|
1540
|
-
fileDepth,
|
|
1541
|
-
astroFilePath,
|
|
1542
|
-
pageData,
|
|
1543
|
-
pageName,
|
|
1544
|
-
isCMSPage: isCMSPage2
|
|
1545
|
-
});
|
|
1546
|
-
}
|
|
686
|
+
const allPages = [];
|
|
687
|
+
const allStyleClasses = /* @__PURE__ */ new Map();
|
|
1547
688
|
for (const file of pageFiles) {
|
|
1548
689
|
const pageName = file.replace(".json", "");
|
|
1549
690
|
const basePath = mapPageNameToPath(pageName);
|
|
1550
691
|
const pageContent = await loadJSONFile(join(pagesDir, file));
|
|
1551
|
-
if (!pageContent)
|
|
1552
|
-
console.warn(` Skipping ${basePath} (empty file)`);
|
|
1553
|
-
errorCount++;
|
|
1554
|
-
continue;
|
|
1555
|
-
}
|
|
692
|
+
if (!pageContent) continue;
|
|
1556
693
|
try {
|
|
1557
694
|
const pageData = parseJSON(pageContent);
|
|
1558
|
-
|
|
1559
|
-
if (pageData.meta?.draft === true && !isDevBuild) {
|
|
1560
|
-
console.log(` Skipping draft: ${basePath}`);
|
|
1561
|
-
continue;
|
|
1562
|
-
}
|
|
695
|
+
if (pageData.meta?.draft === true) continue;
|
|
1563
696
|
const slugs = pageData.meta?.slugs;
|
|
1564
697
|
for (const localeConfig of i18nConfig.locales) {
|
|
1565
698
|
const locale = localeConfig.code;
|
|
@@ -1573,9 +706,6 @@ async function buildAstroProject(projectRoot, outputDir) {
|
|
|
1573
706
|
slug = basePath.substring(1);
|
|
1574
707
|
}
|
|
1575
708
|
const urlPath = isDefault ? slug === "" ? "/" : `/${slug}` : slug === "" ? `/${locale}` : `/${locale}/${slug}`;
|
|
1576
|
-
const astroFileName = slug === "" ? "index.astro" : `${slug}.astro`;
|
|
1577
|
-
const astroFilePath = isDefault ? astroFileName : `${locale}/${astroFileName}`;
|
|
1578
|
-
const fileDepth = astroFilePath.split("/").length - 1;
|
|
1579
709
|
const result = await renderPageSSR(
|
|
1580
710
|
pageData,
|
|
1581
711
|
globalComponents,
|
|
@@ -1585,60 +715,79 @@ async function buildAstroProject(projectRoot, outputDir) {
|
|
|
1585
715
|
i18nConfig,
|
|
1586
716
|
slugMappings,
|
|
1587
717
|
void 0,
|
|
1588
|
-
// cmsContext
|
|
1589
718
|
cmsService,
|
|
1590
719
|
true
|
|
1591
|
-
// isProductionBuild
|
|
1592
720
|
);
|
|
1593
|
-
|
|
1594
|
-
|
|
721
|
+
const ctx = {
|
|
722
|
+
globalComponents,
|
|
723
|
+
elementPath: [0],
|
|
724
|
+
fileType: "page",
|
|
725
|
+
fileName: pageName,
|
|
726
|
+
breakpoints,
|
|
727
|
+
styleClasses: allStyleClasses
|
|
728
|
+
};
|
|
729
|
+
const body = pageData.root || pageData.node;
|
|
730
|
+
const elements = body ? nodeToWebflow(body, ctx) : [];
|
|
731
|
+
allPages.push({
|
|
732
|
+
title: result.title,
|
|
733
|
+
slug: slug || "index",
|
|
734
|
+
metaDescription: typeof pageData.meta?.description === "string" ? pageData.meta.description : void 0,
|
|
735
|
+
elements,
|
|
736
|
+
locale
|
|
737
|
+
});
|
|
1595
738
|
}
|
|
1596
739
|
} catch (error) {
|
|
1597
|
-
console.error(`
|
|
1598
|
-
errorCount++;
|
|
740
|
+
console.error(`Error processing ${basePath}:`, error?.message);
|
|
1599
741
|
}
|
|
1600
742
|
}
|
|
1601
743
|
const templatesDir = projectPaths.templates();
|
|
1602
|
-
const
|
|
1603
|
-
let cmsPageCount = 0;
|
|
744
|
+
const cmsCollections = [];
|
|
1604
745
|
if (existsSync(templatesDir)) {
|
|
1605
746
|
const templateFiles = readdirSync(templatesDir).filter((f) => f.endsWith(".json"));
|
|
1606
|
-
if (templateFiles.length > 0) {
|
|
1607
|
-
console.log(`
|
|
1608
|
-
Processing ${templateFiles.length} CMS template(s)...
|
|
1609
|
-
`);
|
|
1610
|
-
}
|
|
1611
747
|
for (const file of templateFiles) {
|
|
1612
748
|
const templateContent = await loadJSONFile(join(templatesDir, file));
|
|
1613
749
|
if (!templateContent) continue;
|
|
1614
750
|
try {
|
|
1615
751
|
const pageData = parseJSON(templateContent);
|
|
1616
|
-
|
|
1617
|
-
if (pageData
|
|
1618
|
-
console.log(` Skipping draft template: ${file}`);
|
|
1619
|
-
continue;
|
|
1620
|
-
}
|
|
1621
|
-
if (!isCMSPage(pageData)) {
|
|
1622
|
-
console.warn(` ${file} is in templates/ but missing meta.source: "cms"`);
|
|
1623
|
-
continue;
|
|
1624
|
-
}
|
|
752
|
+
if (pageData.meta?.draft === true) continue;
|
|
753
|
+
if (!isCMSPage(pageData)) continue;
|
|
1625
754
|
const cmsSchema = pageData.meta.cms;
|
|
1626
|
-
templateSchemas.push(cmsSchema);
|
|
1627
|
-
console.log(` CMS Collection: ${cmsSchema.id}`);
|
|
1628
755
|
const items = await cmsService.queryItems({ collection: cmsSchema.id });
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
756
|
+
const fields = [];
|
|
757
|
+
if (cmsSchema.fields) {
|
|
758
|
+
for (const [fieldName, fieldDef] of Object.entries(cmsSchema.fields)) {
|
|
759
|
+
fields.push({
|
|
760
|
+
name: fieldDef.label || fieldName,
|
|
761
|
+
slug: fieldName,
|
|
762
|
+
type: mapCMSFieldType(fieldDef.type),
|
|
763
|
+
required: fieldDef.required,
|
|
764
|
+
options: fieldDef.options
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
const resolvedItems = [];
|
|
769
|
+
for (const item of items) {
|
|
770
|
+
const resolved = {};
|
|
771
|
+
for (const [key, value] of Object.entries(item)) {
|
|
772
|
+
if (isI18nValue(value)) {
|
|
773
|
+
resolved[key] = resolveI18nValue(value, i18nConfig.defaultLocale, i18nConfig);
|
|
774
|
+
} else {
|
|
775
|
+
resolved[key] = value;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
resolvedItems.push(resolved);
|
|
1632
779
|
}
|
|
1633
|
-
|
|
780
|
+
cmsCollections.push({
|
|
781
|
+
name: cmsSchema.id,
|
|
782
|
+
slug: cmsSchema.id,
|
|
783
|
+
urlPattern: cmsSchema.urlPattern,
|
|
784
|
+
fields,
|
|
785
|
+
items: resolvedItems
|
|
786
|
+
});
|
|
1634
787
|
for (const item of items) {
|
|
1635
788
|
for (const localeConfig of i18nConfig.locales) {
|
|
1636
789
|
const locale = localeConfig.code;
|
|
1637
|
-
|
|
1638
|
-
const isDevBuild2 = process.env.MENO_DEV_BUILD === "true";
|
|
1639
|
-
if (!isDevBuild2 && isItemDraftForLocale(item, locale)) {
|
|
1640
|
-
continue;
|
|
1641
|
-
}
|
|
790
|
+
if (isItemDraftForLocale(item, locale)) continue;
|
|
1642
791
|
const itemPath = buildCMSItemPath(cmsSchema.urlPattern, item, cmsSchema.slugField, locale, i18nConfig);
|
|
1643
792
|
const itemWithUrl = { ...item, _url: itemPath };
|
|
1644
793
|
const result = await renderPageSSR(
|
|
@@ -1653,293 +802,53 @@ Processing ${templateFiles.length} CMS template(s)...
|
|
|
1653
802
|
cmsService,
|
|
1654
803
|
true
|
|
1655
804
|
);
|
|
1656
|
-
const
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
805
|
+
const ctx = {
|
|
806
|
+
globalComponents,
|
|
807
|
+
elementPath: [0],
|
|
808
|
+
fileType: "page",
|
|
809
|
+
fileName: file.replace(".json", ""),
|
|
810
|
+
breakpoints,
|
|
811
|
+
styleClasses: allStyleClasses
|
|
812
|
+
};
|
|
813
|
+
const body = pageData.root || pageData.node;
|
|
814
|
+
const cmsProps = { cms: itemWithUrl };
|
|
815
|
+
const elements = body ? nodeToWebflow(body, ctx, cmsProps) : [];
|
|
816
|
+
const slug = itemPath.startsWith("/") ? itemPath.substring(1) : itemPath;
|
|
817
|
+
allPages.push({
|
|
818
|
+
title: result.title,
|
|
819
|
+
slug,
|
|
820
|
+
elements,
|
|
821
|
+
locale
|
|
822
|
+
});
|
|
1663
823
|
}
|
|
1664
824
|
}
|
|
1665
825
|
} catch (error) {
|
|
1666
|
-
console.error(`
|
|
1667
|
-
errorCount++;
|
|
826
|
+
console.error(`Error processing template ${file}:`, error?.message);
|
|
1668
827
|
}
|
|
1669
828
|
}
|
|
1670
829
|
}
|
|
1671
|
-
const mappingClasses = collectAllMappingClasses(globalComponents, breakpoints);
|
|
1672
|
-
const fontCSS = generateFontCSS();
|
|
1673
830
|
const themeColorCSS = generateThemeColorVariablesCSS(themeConfig);
|
|
1674
831
|
const variablesCSS = generateVariablesCSS(variablesConfig, breakpoints, responsiveScales);
|
|
1675
|
-
const
|
|
1676
|
-
const
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
}`;
|
|
1686
|
-
const tailwindDirectives = `@tailwind base;
|
|
1687
|
-
@tailwind components;
|
|
1688
|
-
@tailwind utilities;`;
|
|
1689
|
-
const globalCSS = [tailwindDirectives, fontCSS, themeColorCSS, variablesCSS, baseCSS, componentCSSCombined, interactiveCSS].filter(Boolean).join("\n\n");
|
|
1690
|
-
await writeFile2(join(stylesDir, "global.css"), globalCSS, "utf-8");
|
|
1691
|
-
console.log(`
|
|
1692
|
-
Generated global.css (${(globalCSS.length / 1024).toFixed(1)} KB)`);
|
|
1693
|
-
const fontPreloads = generateFontPreloadTags();
|
|
1694
|
-
const mergedLibraries = mergeLibraries(globalLibraries, componentLibraries);
|
|
1695
|
-
const buildLibraries = filterLibrariesByContext(mergedLibraries, "build");
|
|
1696
|
-
const libraryTags = generateLibraryTags(buildLibraries);
|
|
1697
|
-
const baseLayoutContent = `---
|
|
1698
|
-
import '../styles/global.css';
|
|
1699
|
-
|
|
1700
|
-
interface Props {
|
|
1701
|
-
title: string;
|
|
1702
|
-
meta?: string;
|
|
1703
|
-
scripts?: string[];
|
|
1704
|
-
locale?: string;
|
|
1705
|
-
theme?: string;
|
|
1706
|
-
fontPreloads?: string;
|
|
1707
|
-
libraryTags?: { headCSS?: string; headJS?: string; bodyEndJS?: string };
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.default || "light"}', fontPreloads = '', libraryTags = {} } = Astro.props;
|
|
1711
|
-
---
|
|
1712
|
-
<!DOCTYPE html>
|
|
1713
|
-
<html lang={locale} data-theme={theme}>
|
|
1714
|
-
<head>
|
|
1715
|
-
<meta charset="UTF-8">
|
|
1716
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1717
|
-
<Fragment set:html={fontPreloads} />
|
|
1718
|
-
<Fragment set:html={libraryTags.headCSS || ''} />
|
|
1719
|
-
<Fragment set:html={libraryTags.headJS || ''} />
|
|
1720
|
-
<Fragment set:html={meta} />
|
|
1721
|
-
<title>{title}</title>
|
|
1722
|
-
</head>
|
|
1723
|
-
<body>
|
|
1724
|
-
<slot />
|
|
1725
|
-
{scripts.map((s) => <script src={s} />)}
|
|
1726
|
-
<Fragment set:html={libraryTags.bodyEndJS || ''} />
|
|
1727
|
-
</body>
|
|
1728
|
-
</html>
|
|
1729
|
-
`;
|
|
1730
|
-
await writeFile2(join(layoutsDir, "BaseLayout.astro"), baseLayoutContent, "utf-8");
|
|
1731
|
-
console.log("Generated BaseLayout.astro");
|
|
1732
|
-
let componentFileCount = 0;
|
|
1733
|
-
for (const [compName, compDef] of Object.entries(globalComponents)) {
|
|
1734
|
-
try {
|
|
1735
|
-
const astroContent = emitAstroComponent(compName, compDef, globalComponents, breakpoints);
|
|
1736
|
-
await writeFile2(join(componentsOutDir, `${compName}.astro`), astroContent, "utf-8");
|
|
1737
|
-
componentFileCount++;
|
|
1738
|
-
} catch (error) {
|
|
1739
|
-
console.warn(` Warning: could not generate component ${compName}: ${error?.message}`);
|
|
1740
|
-
}
|
|
1741
|
-
}
|
|
1742
|
-
console.log(`Generated ${componentFileCount} component .astro file(s)`);
|
|
1743
|
-
const defaultTheme = themeConfig.default || "light";
|
|
1744
|
-
for (const result of allResults) {
|
|
1745
|
-
const importPath = layoutImportPath(result.fileDepth);
|
|
1746
|
-
const scriptPaths = [];
|
|
1747
|
-
if (result.javascript) {
|
|
1748
|
-
const hash = hashContent2(result.javascript);
|
|
1749
|
-
const scriptFile = `${hash}.js`;
|
|
1750
|
-
const scriptPublicPath = `/_scripts/${scriptFile}`;
|
|
1751
|
-
if (!existsSync(scriptsDir)) {
|
|
1752
|
-
mkdirSync(scriptsDir, { recursive: true });
|
|
1753
|
-
}
|
|
1754
|
-
const fullScriptPath = join(scriptsDir, scriptFile);
|
|
1755
|
-
if (!existsSync(fullScriptPath)) {
|
|
1756
|
-
await writeFile2(fullScriptPath, result.javascript, "utf-8");
|
|
1757
|
-
}
|
|
1758
|
-
scriptPaths.push(scriptPublicPath);
|
|
1759
|
-
}
|
|
1760
|
-
let astroContent;
|
|
1761
|
-
if (result.pageData && !result.isCMSPage) {
|
|
1762
|
-
try {
|
|
1763
|
-
astroContent = emitAstroPage({
|
|
1764
|
-
pageData: result.pageData,
|
|
1765
|
-
globalComponents,
|
|
1766
|
-
title: result.title,
|
|
1767
|
-
meta: result.meta,
|
|
1768
|
-
locale: result.locale,
|
|
1769
|
-
theme: defaultTheme,
|
|
1770
|
-
fontPreloads,
|
|
1771
|
-
libraryTags,
|
|
1772
|
-
scriptPaths,
|
|
1773
|
-
layoutImportPath: importPath,
|
|
1774
|
-
fileDepth: result.fileDepth,
|
|
1775
|
-
ssrFallbacks: /* @__PURE__ */ new Map(),
|
|
1776
|
-
// SSR fallbacks for complex nodes
|
|
1777
|
-
pageName: result.pageName || "index",
|
|
1778
|
-
breakpoints
|
|
1779
|
-
});
|
|
1780
|
-
} catch (error) {
|
|
1781
|
-
console.warn(` Warning: component emission failed for ${result.urlPath}, using SSR fallback: ${error?.message}`);
|
|
1782
|
-
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
1783
|
-
}
|
|
1784
|
-
} else {
|
|
1785
|
-
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
1786
|
-
}
|
|
1787
|
-
const astroFileFull = join(pagesOutDir, result.astroFilePath);
|
|
1788
|
-
const astroFileDir = astroFileFull.substring(0, astroFileFull.lastIndexOf("/"));
|
|
1789
|
-
if (!existsSync(astroFileDir)) {
|
|
1790
|
-
mkdirSync(astroFileDir, { recursive: true });
|
|
1791
|
-
}
|
|
1792
|
-
await writeFile2(astroFileFull, astroContent, "utf-8");
|
|
1793
|
-
}
|
|
1794
|
-
console.log(`Generated ${allResults.length} .astro page file(s)`);
|
|
1795
|
-
let collectionCount = 0;
|
|
1796
|
-
if (templateSchemas.length > 0) {
|
|
1797
|
-
const contentDir = join(srcDir, "content");
|
|
1798
|
-
mkdirSync(contentDir, { recursive: true });
|
|
1799
|
-
const collectionDefs = [];
|
|
1800
|
-
for (const schema of templateSchemas) {
|
|
1801
|
-
const collectionDir = join(contentDir, schema.id);
|
|
1802
|
-
mkdirSync(collectionDir, { recursive: true });
|
|
1803
|
-
const cmsItemsDir = join(projectPaths.cms(), schema.id);
|
|
1804
|
-
if (existsSync(cmsItemsDir)) {
|
|
1805
|
-
const itemFiles = readdirSync(cmsItemsDir).filter((f) => f.endsWith(".json"));
|
|
1806
|
-
for (const itemFile of itemFiles) {
|
|
1807
|
-
try {
|
|
1808
|
-
const rawContent = await readFile(join(cmsItemsDir, itemFile), "utf-8");
|
|
1809
|
-
const item = JSON.parse(rawContent);
|
|
1810
|
-
const resolved = {};
|
|
1811
|
-
for (const [key, value] of Object.entries(item)) {
|
|
1812
|
-
if (isI18nValue(value)) {
|
|
1813
|
-
resolved[key] = resolveI18nValue(value, i18nConfig.defaultLocale, i18nConfig);
|
|
1814
|
-
} else {
|
|
1815
|
-
resolved[key] = value;
|
|
1816
|
-
}
|
|
1817
|
-
}
|
|
1818
|
-
await writeFile2(
|
|
1819
|
-
join(collectionDir, itemFile),
|
|
1820
|
-
JSON.stringify(resolved, null, 2),
|
|
1821
|
-
"utf-8"
|
|
1822
|
-
);
|
|
1823
|
-
} catch (err) {
|
|
1824
|
-
console.warn(` Warning: could not process CMS item ${itemFile}: ${err?.message}`);
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
}
|
|
1828
|
-
const fieldDefs = [];
|
|
1829
|
-
if (schema.fields) {
|
|
1830
|
-
for (const [fieldName, fieldDef] of Object.entries(schema.fields)) {
|
|
1831
|
-
const zodType = cmsFieldToZod(fieldDef);
|
|
1832
|
-
const optional = fieldDef.required ? "" : ".optional()";
|
|
1833
|
-
fieldDefs.push(` ${fieldName}: ${zodType}${optional}`);
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
collectionDefs.push(` '${schema.id}': defineCollection({
|
|
1837
|
-
type: 'data',
|
|
1838
|
-
schema: z.object({
|
|
1839
|
-
${fieldDefs.join(",\n")}
|
|
1840
|
-
})
|
|
1841
|
-
})`);
|
|
1842
|
-
collectionCount++;
|
|
1843
|
-
}
|
|
1844
|
-
const configContent = `import { z, defineCollection } from 'astro:content';
|
|
1845
|
-
|
|
1846
|
-
const collections = {
|
|
1847
|
-
${collectionDefs.join(",\n")}
|
|
1848
|
-
};
|
|
1849
|
-
|
|
1850
|
-
export { collections };
|
|
1851
|
-
`;
|
|
1852
|
-
await writeFile2(join(contentDir, "config.ts"), configContent, "utf-8");
|
|
1853
|
-
console.log(`Generated ${collectionCount} content collection(s) with config.ts`);
|
|
1854
|
-
}
|
|
1855
|
-
const assetDirs = ["fonts", "images", "icons", "videos", "assets"];
|
|
1856
|
-
let copiedAssets = 0;
|
|
1857
|
-
for (const dir of assetDirs) {
|
|
1858
|
-
const srcAssetDir = join(projectPaths.project, dir);
|
|
1859
|
-
if (existsSync(srcAssetDir)) {
|
|
1860
|
-
copyDirectory(srcAssetDir, join(publicDir, dir));
|
|
1861
|
-
copiedAssets++;
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
const librariesDir = join(projectPaths.project, "libraries");
|
|
1865
|
-
if (existsSync(librariesDir)) {
|
|
1866
|
-
copyDirectory(librariesDir, join(publicDir, "libraries"));
|
|
1867
|
-
copiedAssets++;
|
|
1868
|
-
}
|
|
1869
|
-
if (copiedAssets > 0) {
|
|
1870
|
-
console.log(`Copied ${copiedAssets} asset director${copiedAssets === 1 ? "y" : "ies"} to public/`);
|
|
1871
|
-
}
|
|
1872
|
-
const packageJson = {
|
|
1873
|
-
name: "astro-export",
|
|
1874
|
-
type: "module",
|
|
1875
|
-
version: "0.0.1",
|
|
1876
|
-
private: true,
|
|
1877
|
-
scripts: {
|
|
1878
|
-
dev: "astro dev",
|
|
1879
|
-
start: "astro dev",
|
|
1880
|
-
build: "astro build",
|
|
1881
|
-
preview: "astro preview"
|
|
1882
|
-
},
|
|
1883
|
-
dependencies: {
|
|
1884
|
-
"astro": "^4.0.0",
|
|
1885
|
-
"@astrojs/sitemap": "^3.0.0",
|
|
1886
|
-
"@astrojs/tailwind": "^5.0.0",
|
|
1887
|
-
"tailwindcss": "^3.4.0"
|
|
1888
|
-
}
|
|
1889
|
-
};
|
|
1890
|
-
await writeFile2(join(outDir, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8");
|
|
1891
|
-
const astroConfig = `import { defineConfig } from 'astro/config';
|
|
1892
|
-
import sitemap from '@astrojs/sitemap';
|
|
1893
|
-
import tailwind from '@astrojs/tailwind';
|
|
1894
|
-
|
|
1895
|
-
export default defineConfig({${siteUrl ? `
|
|
1896
|
-
site: '${siteUrl}',` : ""}
|
|
1897
|
-
integrations: [sitemap(), tailwind({ applyBaseStyles: false })],
|
|
1898
|
-
});
|
|
1899
|
-
`;
|
|
1900
|
-
const safelistArray = Array.from(mappingClasses);
|
|
1901
|
-
const safelistLiteral = safelistArray.length > 0 ? `
|
|
1902
|
-
safelist: [
|
|
1903
|
-
${safelistArray.map((c) => ` '${c}'`).join(",\n")}
|
|
1904
|
-
],` : "";
|
|
1905
|
-
const tailwindConfig = `/** @type {import('tailwindcss').Config} */
|
|
1906
|
-
export default {
|
|
1907
|
-
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],${safelistLiteral}
|
|
1908
|
-
theme: {
|
|
1909
|
-
extend: {},
|
|
1910
|
-
},
|
|
1911
|
-
plugins: [],
|
|
1912
|
-
};
|
|
1913
|
-
`;
|
|
1914
|
-
await writeFile2(join(outDir, "tailwind.config.mjs"), tailwindConfig, "utf-8");
|
|
1915
|
-
await writeFile2(join(outDir, "astro.config.mjs"), astroConfig, "utf-8");
|
|
1916
|
-
const tsConfig = {
|
|
1917
|
-
extends: "astro/tsconfigs/strict"
|
|
832
|
+
const cssVariables = extractCSSVariables(themeColorCSS, variablesCSS);
|
|
833
|
+
const assets = scanAssets(projectPaths.project);
|
|
834
|
+
return {
|
|
835
|
+
version: 1,
|
|
836
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
837
|
+
pages: allPages,
|
|
838
|
+
styles: Array.from(allStyleClasses.values()),
|
|
839
|
+
cms: cmsCollections,
|
|
840
|
+
assets,
|
|
841
|
+
cssVariables: Object.keys(cssVariables).length > 0 ? cssVariables : void 0
|
|
1918
842
|
};
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
1922
|
-
const totalPages = allResults.length;
|
|
1923
|
-
console.log("\n" + "=".repeat(50));
|
|
1924
|
-
console.log("Astro export complete!");
|
|
1925
|
-
console.log(` Pages: ${totalPages - cmsPageCount}`);
|
|
1926
|
-
if (cmsPageCount > 0) {
|
|
1927
|
-
console.log(` CMS pages: ${cmsPageCount}`);
|
|
1928
|
-
}
|
|
1929
|
-
if (collectionCount > 0) {
|
|
1930
|
-
console.log(` Content collections: ${collectionCount}`);
|
|
1931
|
-
}
|
|
1932
|
-
if (errorCount > 0) {
|
|
1933
|
-
console.log(` Errors: ${errorCount}`);
|
|
1934
|
-
}
|
|
1935
|
-
console.log(` Time: ${elapsed}s`);
|
|
1936
|
-
console.log(` Output: ${outDir}`);
|
|
1937
|
-
console.log("");
|
|
843
|
+
}
|
|
844
|
+
function emptyPayload() {
|
|
1938
845
|
return {
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
846
|
+
version: 1,
|
|
847
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
848
|
+
pages: [],
|
|
849
|
+
styles: [],
|
|
850
|
+
cms: [],
|
|
851
|
+
assets: []
|
|
1943
852
|
};
|
|
1944
853
|
}
|
|
1945
854
|
|
|
@@ -1964,12 +873,12 @@ export {
|
|
|
1964
873
|
SERVE_PORT,
|
|
1965
874
|
VariableService,
|
|
1966
875
|
WebSocketManager,
|
|
1967
|
-
buildAstroProject,
|
|
1968
876
|
buildAttributes,
|
|
1969
877
|
buildComponentHTML,
|
|
1970
878
|
buildImageMetadataMap,
|
|
1971
879
|
buildLineMap,
|
|
1972
880
|
buildStaticPages,
|
|
881
|
+
buildWebflowPayload,
|
|
1973
882
|
bundleFile,
|
|
1974
883
|
clearJSValidationCache,
|
|
1975
884
|
collectComponentCSS,
|
|
@@ -1988,8 +897,12 @@ export {
|
|
|
1988
897
|
extractPageMeta,
|
|
1989
898
|
fileExists,
|
|
1990
899
|
generateBuildErrorPage,
|
|
900
|
+
generateFontCSS,
|
|
901
|
+
generateFontPreloadTags,
|
|
1991
902
|
generateMetaTags,
|
|
1992
903
|
generateSSRHTML,
|
|
904
|
+
generateThemeColorVariablesCSS,
|
|
905
|
+
generateVariablesCSS,
|
|
1993
906
|
getFileSize,
|
|
1994
907
|
getJSValidationErrors,
|
|
1995
908
|
getMimeType,
|
|
@@ -2008,13 +921,20 @@ export {
|
|
|
2008
921
|
isBun,
|
|
2009
922
|
jsonResponse,
|
|
2010
923
|
lineMapToObject,
|
|
924
|
+
loadBreakpointConfig,
|
|
925
|
+
loadComponentDirectory,
|
|
926
|
+
loadI18nConfig,
|
|
927
|
+
loadJSONFile,
|
|
2011
928
|
loadProjectConfig,
|
|
929
|
+
loadResponsiveScalesConfig,
|
|
2012
930
|
logError,
|
|
2013
931
|
logRequest,
|
|
2014
932
|
logResponseTime,
|
|
933
|
+
mapPageNameToPath,
|
|
2015
934
|
migrateTemplatesDirectory,
|
|
2016
935
|
minifyJS,
|
|
2017
936
|
packagePaths,
|
|
937
|
+
parseJSON,
|
|
2018
938
|
processCMSPropsTemplate,
|
|
2019
939
|
processCMSTemplate,
|
|
2020
940
|
projectPaths,
|