meno-core 1.0.45 → 1.0.46
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/build-astro.ts +214 -63
- package/dist/bin/cli.js +2 -2
- package/dist/build-static.js +7 -7
- package/dist/chunks/{chunk-NZTSJS5C.js → chunk-2QK6U5UK.js} +3 -2
- package/dist/chunks/{chunk-NZTSJS5C.js.map → chunk-2QK6U5UK.js.map} +2 -2
- package/dist/chunks/{chunk-BZQKEJQY.js → chunk-77ZB6353.js} +29 -18
- package/dist/chunks/chunk-77ZB6353.js.map +7 -0
- package/dist/chunks/{chunk-TVH3TC2T.js → chunk-C6U5T5S5.js} +6 -6
- package/dist/chunks/{chunk-5ZASE4IG.js → chunk-FED5MME6.js} +234 -11
- package/dist/chunks/{chunk-5ZASE4IG.js.map → chunk-FED5MME6.js.map} +3 -3
- package/dist/chunks/{chunk-5Z5VQRTJ.js → chunk-I7YIGZXT.js} +4 -4
- package/dist/chunks/{chunk-5Z5VQRTJ.js.map → chunk-I7YIGZXT.js.map} +2 -2
- package/dist/chunks/{chunk-OUNJ76QM.js → chunk-ORN7S4AP.js} +5 -5
- package/dist/chunks/{chunk-GYF3ABI3.js → chunk-UUA5LEWF.js} +3 -3
- package/dist/chunks/{chunk-GYF3ABI3.js.map → chunk-UUA5LEWF.js.map} +2 -2
- package/dist/chunks/{chunk-WQSG5WHC.js → chunk-ZTKHJQ2Z.js} +2 -2
- package/dist/chunks/{chunk-F7MA62WG.js → chunk-ZWYDT3QJ.js} +3 -3
- package/dist/chunks/{configService-6KTT6GRT.js → configService-DYCUEURL.js} +3 -3
- package/dist/chunks/{constants-L5IKLB6U.js → constants-GWBAD66U.js} +2 -2
- package/dist/entries/server-router.js +7 -7
- package/dist/lib/client/index.js +4 -4
- package/dist/lib/server/index.js +586 -142
- package/dist/lib/server/index.js.map +3 -3
- package/dist/lib/shared/index.js +7 -3
- package/dist/lib/shared/index.js.map +2 -2
- package/dist/lib/test-utils/index.js +1 -1
- package/lib/client/templateEngine.test.ts +64 -0
- package/lib/server/astro/astroEmitHelpers.ts +18 -0
- package/lib/server/astro/cmsPageEmitter.ts +31 -1
- package/lib/server/astro/componentEmitter.test.ts +59 -0
- package/lib/server/astro/componentEmitter.ts +43 -10
- package/lib/server/astro/cssCollector.ts +58 -11
- package/lib/server/astro/nodeToAstro.test.ts +397 -5
- package/lib/server/astro/nodeToAstro.ts +478 -63
- package/lib/server/astro/pageEmitter.ts +31 -1
- package/lib/server/astro/tailwindMapper.test.ts +119 -0
- package/lib/server/astro/tailwindMapper.ts +67 -1
- package/lib/server/runtime/httpServer.ts +12 -4
- package/lib/server/ssr/htmlGenerator.ts +1 -1
- package/lib/server/ssr/jsCollector.ts +2 -2
- package/lib/server/ssr/ssrRenderer.test.ts +32 -0
- package/lib/server/ssr/ssrRenderer.ts +26 -11
- package/lib/shared/constants.ts +1 -0
- package/lib/shared/cssGeneration.test.ts +109 -3
- package/lib/shared/cssGeneration.ts +98 -13
- package/lib/shared/cssNamedColors.ts +47 -0
- package/lib/shared/cssProperties.ts +2 -2
- package/lib/shared/index.ts +1 -0
- package/package.json +1 -1
- package/dist/chunks/chunk-BZQKEJQY.js.map +0 -7
- /package/dist/chunks/{chunk-TVH3TC2T.js.map → chunk-C6U5T5S5.js.map} +0 -0
- /package/dist/chunks/{chunk-OUNJ76QM.js.map → chunk-ORN7S4AP.js.map} +0 -0
- /package/dist/chunks/{chunk-WQSG5WHC.js.map → chunk-ZTKHJQ2Z.js.map} +0 -0
- /package/dist/chunks/{chunk-F7MA62WG.js.map → chunk-ZWYDT3QJ.js.map} +0 -0
- /package/dist/chunks/{configService-6KTT6GRT.js.map → configService-DYCUEURL.js.map} +0 -0
- /package/dist/chunks/{constants-L5IKLB6U.js.map → constants-GWBAD66U.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-ORN7S4AP.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-C6U5T5S5.js";
|
|
36
36
|
import {
|
|
37
37
|
CMSService,
|
|
38
38
|
ColorService,
|
|
@@ -65,6 +65,7 @@ import {
|
|
|
65
65
|
loadBreakpointConfig,
|
|
66
66
|
loadComponentDirectory,
|
|
67
67
|
loadI18nConfig,
|
|
68
|
+
loadIconsConfig,
|
|
68
69
|
loadJSONFile,
|
|
69
70
|
loadProjectConfig,
|
|
70
71
|
loadResponsiveScalesConfig,
|
|
@@ -82,11 +83,11 @@ import {
|
|
|
82
83
|
styleToString,
|
|
83
84
|
translatePath,
|
|
84
85
|
variableService
|
|
85
|
-
} from "../../chunks/chunk-
|
|
86
|
+
} from "../../chunks/chunk-77ZB6353.js";
|
|
86
87
|
import {
|
|
87
88
|
ConfigService,
|
|
88
89
|
configService
|
|
89
|
-
} from "../../chunks/chunk-
|
|
90
|
+
} from "../../chunks/chunk-ZTKHJQ2Z.js";
|
|
90
91
|
import {
|
|
91
92
|
bundleFile,
|
|
92
93
|
createRuntimeServer,
|
|
@@ -100,7 +101,7 @@ import {
|
|
|
100
101
|
resolveProjectPath,
|
|
101
102
|
setProjectRoot,
|
|
102
103
|
validateJS
|
|
103
|
-
} from "../../chunks/chunk-
|
|
104
|
+
} from "../../chunks/chunk-I7YIGZXT.js";
|
|
104
105
|
import {
|
|
105
106
|
ensureDir,
|
|
106
107
|
fileExists,
|
|
@@ -117,7 +118,7 @@ import {
|
|
|
117
118
|
} from "../../chunks/chunk-WQFG7PAH.js";
|
|
118
119
|
import "../../chunks/chunk-IF3RATBY.js";
|
|
119
120
|
import "../../chunks/chunk-KITQJYZV.js";
|
|
120
|
-
import "../../chunks/chunk-
|
|
121
|
+
import "../../chunks/chunk-ZWYDT3QJ.js";
|
|
121
122
|
import {
|
|
122
123
|
extractInteractiveStyleMappings,
|
|
123
124
|
generateAllInteractiveCSS,
|
|
@@ -127,13 +128,15 @@ import {
|
|
|
127
128
|
isItemDraftForLocale,
|
|
128
129
|
isVoidElement,
|
|
129
130
|
singularize
|
|
130
|
-
} from "../../chunks/chunk-
|
|
131
|
+
} from "../../chunks/chunk-FED5MME6.js";
|
|
131
132
|
import {
|
|
132
133
|
DEFAULT_BREAKPOINTS,
|
|
133
134
|
DEFAULT_I18N_CONFIG,
|
|
134
135
|
buildLocalizedPath,
|
|
136
|
+
getScaleMultiplier,
|
|
135
137
|
isI18nValue,
|
|
136
|
-
resolveI18nValue
|
|
138
|
+
resolveI18nValue,
|
|
139
|
+
scalePropertyValue
|
|
137
140
|
} from "../../chunks/chunk-XSWR3QLI.js";
|
|
138
141
|
import "../../chunks/chunk-UB44F4Z2.js";
|
|
139
142
|
import {
|
|
@@ -144,11 +147,11 @@ import {
|
|
|
144
147
|
SERVER_PORT,
|
|
145
148
|
SERVE_PORT,
|
|
146
149
|
init_constants
|
|
147
|
-
} from "../../chunks/chunk-
|
|
150
|
+
} from "../../chunks/chunk-2QK6U5UK.js";
|
|
148
151
|
import "../../chunks/chunk-KSBZ2L7C.js";
|
|
149
152
|
|
|
150
153
|
// build-astro.ts
|
|
151
|
-
import { existsSync, readdirSync, mkdirSync, rmSync, statSync, copyFileSync } from "fs";
|
|
154
|
+
import { existsSync, readdirSync, mkdirSync, rmSync, statSync, copyFileSync, writeFileSync } from "fs";
|
|
152
155
|
import { writeFile as writeFile2, readFile } from "fs/promises";
|
|
153
156
|
import { join } from "path";
|
|
154
157
|
import { createHash } from "crypto";
|
|
@@ -582,7 +585,7 @@ function stylesToTailwind(style) {
|
|
|
582
585
|
}
|
|
583
586
|
return { classes, dynamicStyles };
|
|
584
587
|
}
|
|
585
|
-
function responsiveStylesToTailwind(style, breakpoints) {
|
|
588
|
+
function responsiveStylesToTailwind(style, breakpoints, responsiveScales) {
|
|
586
589
|
if (!style) return { classes: [], dynamicStyles: {} };
|
|
587
590
|
const allClasses = [];
|
|
588
591
|
const allDynamicStyles = {};
|
|
@@ -616,6 +619,9 @@ function responsiveStylesToTailwind(style, breakpoints) {
|
|
|
616
619
|
allClasses.push(...classes.map((cls) => `${prefix}${cls}`));
|
|
617
620
|
Object.assign(allDynamicStyles, dynamicStyles);
|
|
618
621
|
}
|
|
622
|
+
if (responsiveScales?.enabled === true && responsive.base) {
|
|
623
|
+
appendAutoScaledClasses(responsive, breakpoints, responsiveScales, allClasses);
|
|
624
|
+
}
|
|
619
625
|
} else {
|
|
620
626
|
const { classes, dynamicStyles } = stylesToTailwind(style);
|
|
621
627
|
allClasses.push(...classes);
|
|
@@ -623,6 +629,35 @@ function responsiveStylesToTailwind(style, breakpoints) {
|
|
|
623
629
|
}
|
|
624
630
|
return { classes: allClasses, dynamicStyles: allDynamicStyles };
|
|
625
631
|
}
|
|
632
|
+
function appendAutoScaledClasses(responsive, breakpoints, responsiveScales, out) {
|
|
633
|
+
const base = responsive.base;
|
|
634
|
+
if (!base) return;
|
|
635
|
+
const baseRef = responsiveScales.baseReference ?? 16;
|
|
636
|
+
const sortedBps = Object.entries(breakpoints).map(([name, cfg]) => ({ name, value: cfg?.breakpoint })).filter(
|
|
637
|
+
(bp) => typeof bp.value === "number" && bp.value > 0
|
|
638
|
+
).sort((a, b) => b.value - a.value);
|
|
639
|
+
for (const [property, value] of Object.entries(base)) {
|
|
640
|
+
if (isStyleMapping(value)) continue;
|
|
641
|
+
if (value == null) continue;
|
|
642
|
+
const strValue = String(value);
|
|
643
|
+
if (strValue === "" || hasTemplateExpression(strValue)) continue;
|
|
644
|
+
for (const { name: bpName, value: bpPixels } of sortedBps) {
|
|
645
|
+
const bpBranch = responsive[bpName];
|
|
646
|
+
if (bpBranch && property in bpBranch) continue;
|
|
647
|
+
const scale = getScaleMultiplier(
|
|
648
|
+
responsiveScales,
|
|
649
|
+
property,
|
|
650
|
+
bpName
|
|
651
|
+
);
|
|
652
|
+
if (scale == null) continue;
|
|
653
|
+
const scaledValue = scalePropertyValue(strValue, baseRef, scale);
|
|
654
|
+
if (scaledValue == null || scaledValue === strValue) continue;
|
|
655
|
+
const scaledClass = propertyToTailwind(property, scaledValue);
|
|
656
|
+
if (!scaledClass) continue;
|
|
657
|
+
out.push(`max-[${bpPixels}px]:${scaledClass}`);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
626
661
|
|
|
627
662
|
// lib/server/astro/nodeToAstro.ts
|
|
628
663
|
init_constants();
|
|
@@ -687,6 +722,25 @@ function transformItemTemplate(text, itemVar = "item", indexVar, sourceVar) {
|
|
|
687
722
|
return text;
|
|
688
723
|
}
|
|
689
724
|
|
|
725
|
+
// lib/server/astro/astroEmitHelpers.ts
|
|
726
|
+
init_constants();
|
|
727
|
+
function stripRawHtmlPrefixDeep(value) {
|
|
728
|
+
if (typeof value === "string") {
|
|
729
|
+
return value.startsWith(RAW_HTML_PREFIX) ? value.slice(RAW_HTML_PREFIX.length) : value;
|
|
730
|
+
}
|
|
731
|
+
if (Array.isArray(value)) {
|
|
732
|
+
return value.map((item) => stripRawHtmlPrefixDeep(item));
|
|
733
|
+
}
|
|
734
|
+
if (value !== null && typeof value === "object") {
|
|
735
|
+
const out = {};
|
|
736
|
+
for (const [k, v] of Object.entries(value)) {
|
|
737
|
+
out[k] = stripRawHtmlPrefixDeep(v);
|
|
738
|
+
}
|
|
739
|
+
return out;
|
|
740
|
+
}
|
|
741
|
+
return value;
|
|
742
|
+
}
|
|
743
|
+
|
|
690
744
|
// lib/server/astro/nodeToAstro.ts
|
|
691
745
|
function ind(ctx) {
|
|
692
746
|
return " ".repeat(ctx.indent);
|
|
@@ -751,7 +805,7 @@ function escapeJSX(s) {
|
|
|
751
805
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
752
806
|
}
|
|
753
807
|
function escapeTemplateLiteral(s) {
|
|
754
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
808
|
+
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
755
809
|
}
|
|
756
810
|
function collectStyleMappings(style) {
|
|
757
811
|
if (!style) return [];
|
|
@@ -808,7 +862,7 @@ function getClassForValue(property, value, breakpointPrefix) {
|
|
|
808
862
|
return breakpointPrefix ? `${breakpointPrefix}${twClass}` : twClass;
|
|
809
863
|
}
|
|
810
864
|
function buildClassAndStyleExpression(style, interactiveStyles, elementClass, ctx) {
|
|
811
|
-
const result = style ? responsiveStylesToTailwind(style, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
865
|
+
const result = style ? responsiveStylesToTailwind(style, ctx.breakpoints, ctx.responsiveScales) : { classes: [], dynamicStyles: {} };
|
|
812
866
|
const staticClasses = result.classes;
|
|
813
867
|
const dynamicStyles = result.dynamicStyles;
|
|
814
868
|
if (elementClass) {
|
|
@@ -899,7 +953,7 @@ function resolveTemplate(text, ctx) {
|
|
|
899
953
|
let propName = fullMatch[1].trim();
|
|
900
954
|
if (ctx.listItemBinding) propName = rewriteItemVar(propName, ctx.listItemBinding);
|
|
901
955
|
if (ctx.listIndexVar) propName = replaceItemMetaVars(propName, ctx.listIndexVar, ctx.listSourceVar);
|
|
902
|
-
if (ctx.componentProps[propName]?.type === "rich-text") {
|
|
956
|
+
if (ctx.componentProps[propName]?.type === "rich-text" || ctx.componentProps[propName]?.type === "embed") {
|
|
903
957
|
return `<Fragment set:html={${propName}} />`;
|
|
904
958
|
}
|
|
905
959
|
return `{${propName}}`;
|
|
@@ -988,6 +1042,7 @@ function buildAttributesString(attributes, ctx) {
|
|
|
988
1042
|
return parts.length > 0 ? " " + parts.join(" ") : "";
|
|
989
1043
|
}
|
|
990
1044
|
function formatPropValue(value) {
|
|
1045
|
+
value = stripRawHtmlPrefixDeep(value);
|
|
991
1046
|
if (typeof value === "string") return `"${escapeJSX(value)}"`;
|
|
992
1047
|
if (typeof value === "number") return `{${value}}`;
|
|
993
1048
|
if (typeof value === "boolean") return `{${value}}`;
|
|
@@ -1005,12 +1060,11 @@ function nodeToAstro(node, ctx) {
|
|
|
1005
1060
|
if (typeof node === "object" && !Array.isArray(node) && isI18nValue(node)) {
|
|
1006
1061
|
const resolved = resolveI18n(node, ctx);
|
|
1007
1062
|
if (typeof resolved === "string") {
|
|
1008
|
-
return
|
|
1009
|
-
`;
|
|
1063
|
+
return nodeToAstro(resolved, ctx);
|
|
1010
1064
|
}
|
|
1011
1065
|
if (ctx.isComponentDef && isI18nValue(resolved)) {
|
|
1012
1066
|
ctx.needsI18nResolver = true;
|
|
1013
|
-
return `${ind(ctx)}{r(${JSON.stringify(resolved)})}
|
|
1067
|
+
return `${ind(ctx)}{r(${JSON.stringify(stripRawHtmlPrefixDeep(resolved))})}
|
|
1014
1068
|
`;
|
|
1015
1069
|
}
|
|
1016
1070
|
return `${ind(ctx)}${String(resolved ?? "")}
|
|
@@ -1032,7 +1086,8 @@ function nodeToAstro(node, ctx) {
|
|
|
1032
1086
|
`;
|
|
1033
1087
|
}
|
|
1034
1088
|
if (node.startsWith(RAW_HTML_PREFIX)) {
|
|
1035
|
-
const
|
|
1089
|
+
const rawSlice = node.slice(RAW_HTML_PREFIX.length);
|
|
1090
|
+
const rawHtml = ctx.processedRawHtml?.get(rawSlice) ?? rawSlice;
|
|
1036
1091
|
return `${ind(ctx)}<Fragment set:html={\`${escapeTemplateLiteral(rawHtml)}\`} />
|
|
1037
1092
|
`;
|
|
1038
1093
|
}
|
|
@@ -1079,6 +1134,7 @@ function nodeToAstro(node, ctx) {
|
|
|
1079
1134
|
var IMG_TAILWIND_PREFIXES = ["object-", "rounded", "border", "shadow", "[filter", "[transform", "mix-blend"];
|
|
1080
1135
|
var IMG_OPACITY_PATTERN = /^opacity-/;
|
|
1081
1136
|
var DEFAULT_SIZES2 = "100vw";
|
|
1137
|
+
var IMG_FILL_CLASSES = ["block", "w-full", "h-full"];
|
|
1082
1138
|
function splitImageClasses(allClasses) {
|
|
1083
1139
|
const imgClasses = [];
|
|
1084
1140
|
const pictureClasses = [];
|
|
@@ -1092,6 +1148,156 @@ function splitImageClasses(allClasses) {
|
|
|
1092
1148
|
}
|
|
1093
1149
|
return { pictureClasses, imgClasses };
|
|
1094
1150
|
}
|
|
1151
|
+
function extractPxWidth(val) {
|
|
1152
|
+
if (typeof val === "number" && Number.isFinite(val) && val > 0) return val;
|
|
1153
|
+
if (typeof val !== "string") return null;
|
|
1154
|
+
const match = val.trim().match(/^(\d+(?:\.\d+)?)px$/);
|
|
1155
|
+
if (!match) return null;
|
|
1156
|
+
const n = parseFloat(match[1]);
|
|
1157
|
+
return n > 0 ? n : null;
|
|
1158
|
+
}
|
|
1159
|
+
function computeSizesAttribute(style, breakpoints) {
|
|
1160
|
+
if (!style) return DEFAULT_SIZES2;
|
|
1161
|
+
const responsive = isResponsiveStyle2(style);
|
|
1162
|
+
const baseStyle = responsive ? style.base : style;
|
|
1163
|
+
const baseWidth = baseStyle ? extractPxWidth(baseStyle.width) : null;
|
|
1164
|
+
if (baseWidth == null) return DEFAULT_SIZES2;
|
|
1165
|
+
const bpEntries = Object.entries(breakpoints).sort(
|
|
1166
|
+
(a, b) => a[1].breakpoint - b[1].breakpoint
|
|
1167
|
+
);
|
|
1168
|
+
const parts = [];
|
|
1169
|
+
for (const [name, entry] of bpEntries) {
|
|
1170
|
+
let effective = null;
|
|
1171
|
+
if (responsive) {
|
|
1172
|
+
const bpStyle = style[name];
|
|
1173
|
+
effective = bpStyle ? extractPxWidth(bpStyle.width) : null;
|
|
1174
|
+
if (effective == null) {
|
|
1175
|
+
for (const [largerName, largerEntry] of bpEntries) {
|
|
1176
|
+
if (largerEntry.breakpoint <= entry.breakpoint) continue;
|
|
1177
|
+
const largerStyle = style[largerName];
|
|
1178
|
+
const larger = largerStyle ? extractPxWidth(largerStyle.width) : null;
|
|
1179
|
+
if (larger != null) {
|
|
1180
|
+
effective = larger;
|
|
1181
|
+
break;
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
if (effective == null) effective = baseWidth;
|
|
1186
|
+
} else {
|
|
1187
|
+
effective = baseWidth;
|
|
1188
|
+
}
|
|
1189
|
+
parts.push(`(max-width: ${entry.breakpoint}px) ${effective}px`);
|
|
1190
|
+
}
|
|
1191
|
+
parts.push(`${baseWidth}px`);
|
|
1192
|
+
return parts.join(", ");
|
|
1193
|
+
}
|
|
1194
|
+
function injectInlineStyle(styleAttr, extraCss) {
|
|
1195
|
+
if (!extraCss) return styleAttr;
|
|
1196
|
+
if (!styleAttr) return ` style="${extraCss}"`;
|
|
1197
|
+
return styleAttr.replace(/style="([^"]*)"/, (_, existing) => {
|
|
1198
|
+
const trimmed = existing.trimEnd();
|
|
1199
|
+
const sep = trimmed.length > 0 && !trimmed.endsWith(";") ? ";" : "";
|
|
1200
|
+
return `style="${existing}${sep}${extraCss}"`;
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
var PICTURE_WIDTHS = [500, 800, 1080, 1600, 2400];
|
|
1204
|
+
function imagePathToVarName(srcPath) {
|
|
1205
|
+
const stripped = srcPath.replace(/^\/+/, "").replace(/^images\//, "").replace(/\.[^.]+$/, "");
|
|
1206
|
+
const parts = stripped.split(/[/_\-\s.]+/).filter(Boolean);
|
|
1207
|
+
if (parts.length === 0) return "imgAsset";
|
|
1208
|
+
const camel = parts.map((p, i) => {
|
|
1209
|
+
const clean = p.replace(/[^a-zA-Z0-9]/g, "");
|
|
1210
|
+
if (!clean) return "";
|
|
1211
|
+
if (i === 0) return clean.toLowerCase();
|
|
1212
|
+
return clean[0].toUpperCase() + clean.slice(1).toLowerCase();
|
|
1213
|
+
}).join("");
|
|
1214
|
+
if (!camel) return "imgAsset";
|
|
1215
|
+
return "img" + camel[0].toUpperCase() + camel.slice(1);
|
|
1216
|
+
}
|
|
1217
|
+
function imageImportPath(srcPath, fileDepth) {
|
|
1218
|
+
const rest = srcPath.replace(/^\/+/, "").replace(/^images\//, "");
|
|
1219
|
+
const ups = "../".repeat(Math.max(0, fileDepth) + 1);
|
|
1220
|
+
return `${ups}assets/images/${rest}`;
|
|
1221
|
+
}
|
|
1222
|
+
function isStaticImageSrc(src, ctx) {
|
|
1223
|
+
if (!src) return false;
|
|
1224
|
+
if (typeof src !== "string") return false;
|
|
1225
|
+
if (hasTemplates(src)) return false;
|
|
1226
|
+
if (!src.startsWith("/images/")) return false;
|
|
1227
|
+
if (!ctx.imageMetadataMap?.has(src)) return false;
|
|
1228
|
+
return true;
|
|
1229
|
+
}
|
|
1230
|
+
function registerStaticImageImport(src, ctx) {
|
|
1231
|
+
if (!ctx.imageImports) ctx.imageImports = /* @__PURE__ */ new Map();
|
|
1232
|
+
const depth = ctx.fileDepth ?? 0;
|
|
1233
|
+
const importPath = imageImportPath(src, depth);
|
|
1234
|
+
for (const [existingName, existingPath] of ctx.imageImports) {
|
|
1235
|
+
if (existingPath === importPath) return existingName;
|
|
1236
|
+
}
|
|
1237
|
+
const base = imagePathToVarName(src);
|
|
1238
|
+
let name = base;
|
|
1239
|
+
let counter = 2;
|
|
1240
|
+
while (ctx.imageImports.has(name)) {
|
|
1241
|
+
name = `${base}${counter++}`;
|
|
1242
|
+
}
|
|
1243
|
+
ctx.imageImports.set(name, importPath);
|
|
1244
|
+
return name;
|
|
1245
|
+
}
|
|
1246
|
+
function splitStaticClassExpr(classExpr) {
|
|
1247
|
+
if (classExpr.includes("class:list=")) return null;
|
|
1248
|
+
const classMatch = classExpr.match(/class="([^"]*)"/);
|
|
1249
|
+
if (!classMatch) return { outerClasses: [], innerClasses: [] };
|
|
1250
|
+
const all = classMatch[1].split(/\s+/).filter(Boolean);
|
|
1251
|
+
const { pictureClasses, imgClasses } = splitImageClasses(all);
|
|
1252
|
+
return { outerClasses: pictureClasses, innerClasses: imgClasses };
|
|
1253
|
+
}
|
|
1254
|
+
function formatPictureAttributesProp(classValue, styleAttr) {
|
|
1255
|
+
const styleMatch = styleAttr.match(/style="([^"]*)"/);
|
|
1256
|
+
const parts = [];
|
|
1257
|
+
if (classValue) parts.push(`class: ${JSON.stringify(classValue)}`);
|
|
1258
|
+
if (styleMatch) parts.push(`style: ${JSON.stringify(styleMatch[1])}`);
|
|
1259
|
+
if (parts.length === 0) return "";
|
|
1260
|
+
return ` pictureAttributes={{${parts.join(", ")}}}`;
|
|
1261
|
+
}
|
|
1262
|
+
function emitStaticPictureImage(src, alt, loading, fetchpriority, sizesValue, classExpr, styleAttr, ifExpr, ifClose, blurHash, ctx) {
|
|
1263
|
+
const varName = registerStaticImageImport(src, ctx);
|
|
1264
|
+
const widthsLiteral = `[${PICTURE_WIDTHS.join(", ")}]`;
|
|
1265
|
+
const altAttr = alt !== void 0 ? ` alt="${escapeJSX(String(alt))}"` : ' alt=""';
|
|
1266
|
+
const loadingAttr = loading ? ` loading="${escapeJSX(loading)}"` : "";
|
|
1267
|
+
const fetchpriorityAttr = fetchpriority ? ` fetchpriority="${escapeJSX(fetchpriority)}"` : "";
|
|
1268
|
+
const split = splitStaticClassExpr(classExpr);
|
|
1269
|
+
if (blurHash) {
|
|
1270
|
+
const blurCss = `background-image:url(${escapeJSX(blurHash)});background-size:cover`;
|
|
1271
|
+
const blurStyleAttr = injectInlineStyle(styleAttr, blurCss);
|
|
1272
|
+
const onloadAttr = ` onload="this.parentElement.style.backgroundImage=''"`;
|
|
1273
|
+
if (split) {
|
|
1274
|
+
const outerClassValue = split.outerClasses.join(" ");
|
|
1275
|
+
const pictureAttrs = formatPictureAttributesProp(outerClassValue, blurStyleAttr);
|
|
1276
|
+
const innerClasses = [...split.innerClasses, ...IMG_FILL_CLASSES];
|
|
1277
|
+
const innerClassAttr = ` class="${innerClasses.join(" ")}"`;
|
|
1278
|
+
return `${ifExpr}${ind(ctx)}<Picture${pictureAttrs} src={${varName}}${altAttr}${innerClassAttr} formats={['avif','webp']} widths={${widthsLiteral}} sizes="${escapeJSX(sizesValue)}"${loadingAttr}${fetchpriorityAttr}${onloadAttr} />
|
|
1279
|
+
${ifClose}`;
|
|
1280
|
+
}
|
|
1281
|
+
const wrapperClassExpr = classExpr;
|
|
1282
|
+
const wrapperStyleAttr = injectInlineStyle(styleAttr, blurCss);
|
|
1283
|
+
const fillClassAttr = ` class="${IMG_FILL_CLASSES.join(" ")}"`;
|
|
1284
|
+
return `${ifExpr}${ind(ctx)}<div${wrapperClassExpr}${wrapperStyleAttr}>
|
|
1285
|
+
${ind(ctx)} <Picture pictureAttributes={{class: "${IMG_FILL_CLASSES.join(" ")}"}} src={${varName}}${altAttr}${fillClassAttr} formats={['avif','webp']} widths={${widthsLiteral}} sizes="${escapeJSX(sizesValue)}"${loadingAttr}${fetchpriorityAttr} onload="this.parentElement.parentElement.style.backgroundImage=''" />
|
|
1286
|
+
${ind(ctx)}</div>
|
|
1287
|
+
${ifClose}`;
|
|
1288
|
+
}
|
|
1289
|
+
if (split) {
|
|
1290
|
+
const outerClassValue = split.outerClasses.join(" ");
|
|
1291
|
+
const innerClassAttr = split.innerClasses.length > 0 ? ` class="${split.innerClasses.join(" ")}"` : "";
|
|
1292
|
+
const pictureAttrs = formatPictureAttributesProp(outerClassValue, styleAttr);
|
|
1293
|
+
return `${ifExpr}${ind(ctx)}<Picture${pictureAttrs} src={${varName}}${altAttr}${innerClassAttr} formats={['avif','webp']} widths={${widthsLiteral}} sizes="${escapeJSX(sizesValue)}"${loadingAttr}${fetchpriorityAttr} />
|
|
1294
|
+
${ifClose}`;
|
|
1295
|
+
}
|
|
1296
|
+
return `${ifExpr}${ind(ctx)}<div${classExpr}${styleAttr}>
|
|
1297
|
+
${ind(ctx)} <Picture src={${varName}}${altAttr} formats={['avif','webp']} widths={${widthsLiteral}} sizes="${escapeJSX(sizesValue)}"${loadingAttr}${fetchpriorityAttr} />
|
|
1298
|
+
${ind(ctx)}</div>
|
|
1299
|
+
${ifClose}`;
|
|
1300
|
+
}
|
|
1095
1301
|
function emitImageNode(node, ctx) {
|
|
1096
1302
|
const style = node.style;
|
|
1097
1303
|
let elementClass = null;
|
|
@@ -1117,7 +1323,22 @@ function emitImageNode(node, ctx) {
|
|
|
1117
1323
|
if (width === void 0 && metadata.width) width = metadata.width;
|
|
1118
1324
|
if (height === void 0 && metadata.height) height = metadata.height;
|
|
1119
1325
|
}
|
|
1120
|
-
const sizesValue = sizes ||
|
|
1326
|
+
const sizesValue = sizes || computeSizesAttribute(style, ctx.breakpoints);
|
|
1327
|
+
if (isStaticImageSrc(src, ctx)) {
|
|
1328
|
+
return emitStaticPictureImage(
|
|
1329
|
+
src,
|
|
1330
|
+
alt,
|
|
1331
|
+
loading,
|
|
1332
|
+
fetchpriority,
|
|
1333
|
+
sizesValue,
|
|
1334
|
+
classExpr,
|
|
1335
|
+
styleAttr,
|
|
1336
|
+
emitIfOpen(node, ctx),
|
|
1337
|
+
emitIfClose(node, ctx),
|
|
1338
|
+
metadata?.blurHash,
|
|
1339
|
+
ctx
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1121
1342
|
const imageSpecificKeys = /* @__PURE__ */ new Set(["src", "alt", "loading", "width", "height", "sizes", "srcset", "fetchpriority"]);
|
|
1122
1343
|
const otherAttrs = {};
|
|
1123
1344
|
if (node.attributes) {
|
|
@@ -1133,31 +1354,44 @@ function emitImageNode(node, ctx) {
|
|
|
1133
1354
|
if (loading) imgAttrs += ` loading="${escapeJSX(String(loading))}"`;
|
|
1134
1355
|
if (width !== void 0) imgAttrs += ` width="${escapeJSX(String(width))}"`;
|
|
1135
1356
|
if (height !== void 0) imgAttrs += ` height="${escapeJSX(String(height))}"`;
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
}
|
|
1357
|
+
const hasAvif = !!(metadata?.avifSrcset && ctx.imageFormat !== "webp");
|
|
1358
|
+
const hasBlur = !!metadata?.blurHash;
|
|
1359
|
+
const useWrapper = hasAvif || hasBlur;
|
|
1360
|
+
const blurWrapperCss = hasBlur ? `background-image:url(${escapeJSX(metadata.blurHash)});background-size:cover` : "";
|
|
1361
|
+
const blurOnload = hasBlur ? ` onload="this.parentElement.style.backgroundImage=''"` : "";
|
|
1140
1362
|
const ifExpr = emitIfOpen(node, ctx);
|
|
1141
1363
|
const ifClose = emitIfClose(node, ctx);
|
|
1142
|
-
if (
|
|
1143
|
-
const
|
|
1364
|
+
if (useWrapper) {
|
|
1365
|
+
const imgFillClasses = IMG_FILL_CLASSES.slice();
|
|
1144
1366
|
const classListMatch = classExpr.match(/class:list={\[(.+)\]}/);
|
|
1367
|
+
const classMatch = classExpr.match(/class="([^"]*)"/);
|
|
1368
|
+
let pictureClassExpr = "";
|
|
1369
|
+
let imgClassAttr = "";
|
|
1145
1370
|
if (classListMatch) {
|
|
1146
|
-
|
|
1371
|
+
pictureClassExpr = classExpr;
|
|
1372
|
+
imgClassAttr = ` class="${imgFillClasses.join(" ")}"`;
|
|
1373
|
+
} else {
|
|
1374
|
+
const allClasses = classMatch ? classMatch[1].split(/\s+/).filter(Boolean) : [];
|
|
1375
|
+
const { pictureClasses, imgClasses } = splitImageClasses(allClasses);
|
|
1376
|
+
const fullImgClasses = [...imgClasses, ...imgFillClasses];
|
|
1377
|
+
pictureClassExpr = pictureClasses.length > 0 ? ` class="${pictureClasses.join(" ")}"` : "";
|
|
1378
|
+
imgClassAttr = fullImgClasses.length > 0 ? ` class="${fullImgClasses.join(" ")}"` : "";
|
|
1379
|
+
}
|
|
1380
|
+
const wrapperStyleAttr = injectInlineStyle(styleAttr, blurWrapperCss);
|
|
1381
|
+
if (hasAvif) {
|
|
1382
|
+
return `${ifExpr}${ind(ctx)}<picture${pictureClassExpr}${wrapperStyleAttr}>
|
|
1147
1383
|
${ind(ctx)} <source type="image/avif" srcset="${escapeJSX(metadata.avifSrcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1148
1384
|
${ind(ctx)} <source type="image/webp" srcset="${escapeJSX(metadata.srcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1149
|
-
${ind(ctx)} <img${imgAttrs}${
|
|
1385
|
+
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${blurOnload}${otherAttrsStr} />
|
|
1150
1386
|
${ind(ctx)}</picture>
|
|
1151
1387
|
${ifClose}`;
|
|
1152
1388
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
return `${ifExpr}${ind(ctx)}<picture${
|
|
1158
|
-
${ind(ctx)} <
|
|
1159
|
-
${ind(ctx)} <source type="image/webp" srcset="${escapeJSX(metadata.srcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1160
|
-
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${blurStyle}${otherAttrsStr} />
|
|
1389
|
+
if (metadata?.srcset) {
|
|
1390
|
+
imgAttrs += ` srcset="${escapeJSX(metadata.srcset)}"`;
|
|
1391
|
+
imgAttrs += ` sizes="${escapeJSX(sizesValue)}"`;
|
|
1392
|
+
}
|
|
1393
|
+
return `${ifExpr}${ind(ctx)}<picture${pictureClassExpr}${wrapperStyleAttr}>
|
|
1394
|
+
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${blurOnload}${otherAttrsStr} />
|
|
1161
1395
|
${ind(ctx)}</picture>
|
|
1162
1396
|
${ifClose}`;
|
|
1163
1397
|
}
|
|
@@ -1165,7 +1399,7 @@ ${ifClose}`;
|
|
|
1165
1399
|
imgAttrs += ` srcset="${escapeJSX(metadata.srcset)}"`;
|
|
1166
1400
|
imgAttrs += ` sizes="${escapeJSX(sizesValue)}"`;
|
|
1167
1401
|
}
|
|
1168
|
-
return `${ifExpr}${ind(ctx)}<img${classExpr}${styleAttr}${imgAttrs}${
|
|
1402
|
+
return `${ifExpr}${ind(ctx)}<img${classExpr}${styleAttr}${imgAttrs}${otherAttrsStr} />
|
|
1169
1403
|
${ifClose}`;
|
|
1170
1404
|
}
|
|
1171
1405
|
function emitHtmlNode(node, ctx) {
|
|
@@ -1248,20 +1482,27 @@ function emitComponentInstance(node, ctx) {
|
|
|
1248
1482
|
}
|
|
1249
1483
|
} else if (ctx.isComponentDef && isI18nValue(value)) {
|
|
1250
1484
|
ctx.needsI18nResolver = true;
|
|
1251
|
-
propParts.push(`${key}={r(${JSON.stringify(value)})}`);
|
|
1485
|
+
propParts.push(`${key}={r(${JSON.stringify(stripRawHtmlPrefixDeep(value))})}`);
|
|
1252
1486
|
} else {
|
|
1253
|
-
|
|
1487
|
+
const targetInterface = ctx.globalComponents[name]?.component?.interface;
|
|
1488
|
+
const propDef = targetInterface?.[key];
|
|
1489
|
+
if (typeof value === "string" && (propDef?.type === "rich-text" || propDef?.type === "embed")) {
|
|
1490
|
+
propParts.push(`${key}={\`${escapeTemplateLiteral(stripRawHtmlPrefixDeep(value))}\`}`);
|
|
1491
|
+
} else {
|
|
1492
|
+
propParts.push(`${key}=${formatPropValue(value)}`);
|
|
1493
|
+
}
|
|
1254
1494
|
}
|
|
1255
1495
|
}
|
|
1256
1496
|
}
|
|
1257
1497
|
if (node.style) {
|
|
1258
|
-
const { classes: instanceClasses } = responsiveStylesToTailwind(node.style, ctx.breakpoints);
|
|
1498
|
+
const { classes: instanceClasses } = responsiveStylesToTailwind(node.style, ctx.breakpoints, ctx.responsiveScales);
|
|
1259
1499
|
if (instanceClasses.length > 0) {
|
|
1260
1500
|
propParts.push(`class="${instanceClasses.join(" ")}"`);
|
|
1261
1501
|
}
|
|
1262
1502
|
}
|
|
1263
1503
|
const propsStr = propParts.length > 0 ? " " + propParts.join(" ") : "";
|
|
1264
|
-
const
|
|
1504
|
+
const childCtx = { ...ctx, elementPath: [0] };
|
|
1505
|
+
const children = emitChildren(node.children, childCtx);
|
|
1265
1506
|
if (!children.trim()) {
|
|
1266
1507
|
return `${ifExpr}${ind(ctx)}<${name}${propsStr} />
|
|
1267
1508
|
${emitIfClose(node, ctx)}`;
|
|
@@ -1426,30 +1667,52 @@ function emitImageTypeNode(node, ctx) {
|
|
|
1426
1667
|
);
|
|
1427
1668
|
const src = node.src;
|
|
1428
1669
|
const alt = node.alt;
|
|
1670
|
+
if (isStaticImageSrc(src, ctx)) {
|
|
1671
|
+
const staticMeta = ctx.imageMetadataMap.get(src);
|
|
1672
|
+
return emitStaticPictureImage(
|
|
1673
|
+
src,
|
|
1674
|
+
alt,
|
|
1675
|
+
void 0,
|
|
1676
|
+
void 0,
|
|
1677
|
+
computeSizesAttribute(style, ctx.breakpoints),
|
|
1678
|
+
classExpr,
|
|
1679
|
+
styleAttr,
|
|
1680
|
+
"",
|
|
1681
|
+
"",
|
|
1682
|
+
staticMeta.blurHash,
|
|
1683
|
+
ctx
|
|
1684
|
+
);
|
|
1685
|
+
}
|
|
1429
1686
|
let imgAttrs = "";
|
|
1430
1687
|
if (src) imgAttrs += ` src="${escapeJSX(String(src))}"`;
|
|
1431
1688
|
if (alt !== void 0) imgAttrs += ` alt="${escapeJSX(String(alt))}"`;
|
|
1432
1689
|
const metadata = src ? ctx.imageMetadataMap?.get(String(src)) : void 0;
|
|
1433
|
-
if (metadata) {
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1690
|
+
if (!metadata) {
|
|
1691
|
+
return `${ind(ctx)}<img${classExpr}${styleAttr}${imgAttrs} />
|
|
1692
|
+
`;
|
|
1693
|
+
}
|
|
1694
|
+
if (metadata.width !== void 0) imgAttrs += ` width="${metadata.width}"`;
|
|
1695
|
+
if (metadata.height !== void 0) imgAttrs += ` height="${metadata.height}"`;
|
|
1696
|
+
const sizesValue = computeSizesAttribute(style, ctx.breakpoints);
|
|
1697
|
+
const hasAvif = !!(metadata.avifSrcset && ctx.imageFormat !== "webp");
|
|
1698
|
+
const hasBlur = !!metadata.blurHash;
|
|
1699
|
+
const useWrapper = hasAvif || hasBlur;
|
|
1700
|
+
const blurWrapperCss = hasBlur ? `background-image:url(${escapeJSX(metadata.blurHash)});background-size:cover` : "";
|
|
1701
|
+
const blurOnload = hasBlur ? ` onload="this.parentElement.style.backgroundImage=''"` : "";
|
|
1702
|
+
if (useWrapper) {
|
|
1703
|
+
const imgFillClasses = IMG_FILL_CLASSES.slice();
|
|
1704
|
+
const classMatch = classExpr.match(/class="([^"]*)"/);
|
|
1705
|
+
const allClasses = classMatch ? classMatch[1].split(/\s+/).filter(Boolean) : [];
|
|
1706
|
+
const { pictureClasses, imgClasses } = splitImageClasses(allClasses);
|
|
1707
|
+
const fullImgClasses = [...imgClasses, ...imgFillClasses];
|
|
1708
|
+
const pictureClassAttr = pictureClasses.length > 0 ? ` class="${pictureClasses.join(" ")}"` : "";
|
|
1709
|
+
const imgClassAttr = fullImgClasses.length > 0 ? ` class="${fullImgClasses.join(" ")}"` : "";
|
|
1710
|
+
const wrapperStyleAttr = injectInlineStyle(styleAttr, blurWrapperCss);
|
|
1711
|
+
if (hasAvif) {
|
|
1712
|
+
return `${ind(ctx)}<picture${pictureClassAttr}${wrapperStyleAttr}>
|
|
1450
1713
|
${ind(ctx)} <source type="image/avif" srcset="${escapeJSX(metadata.avifSrcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1451
1714
|
${ind(ctx)} <source type="image/webp" srcset="${escapeJSX(metadata.srcset)}" sizes="${escapeJSX(sizesValue)}" />
|
|
1452
|
-
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${
|
|
1715
|
+
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${blurOnload} />
|
|
1453
1716
|
${ind(ctx)}</picture>
|
|
1454
1717
|
`;
|
|
1455
1718
|
}
|
|
@@ -1457,6 +1720,14 @@ ${ind(ctx)}</picture>
|
|
|
1457
1720
|
imgAttrs += ` srcset="${escapeJSX(metadata.srcset)}"`;
|
|
1458
1721
|
imgAttrs += ` sizes="${escapeJSX(sizesValue)}"`;
|
|
1459
1722
|
}
|
|
1723
|
+
return `${ind(ctx)}<picture${pictureClassAttr}${wrapperStyleAttr}>
|
|
1724
|
+
${ind(ctx)} <img${imgClassAttr}${imgAttrs}${blurOnload} />
|
|
1725
|
+
${ind(ctx)}</picture>
|
|
1726
|
+
`;
|
|
1727
|
+
}
|
|
1728
|
+
if (metadata.srcset) {
|
|
1729
|
+
imgAttrs += ` srcset="${escapeJSX(metadata.srcset)}"`;
|
|
1730
|
+
imgAttrs += ` sizes="${escapeJSX(sizesValue)}"`;
|
|
1460
1731
|
}
|
|
1461
1732
|
return `${ind(ctx)}<img${classExpr}${styleAttr}${imgAttrs} />
|
|
1462
1733
|
`;
|
|
@@ -1575,13 +1846,13 @@ function emitLocaleListNode(node, ctx) {
|
|
|
1575
1846
|
ctx
|
|
1576
1847
|
);
|
|
1577
1848
|
const itemStyle = node.itemStyle;
|
|
1578
|
-
const itemResult = itemStyle ? responsiveStylesToTailwind(itemStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1849
|
+
const itemResult = itemStyle ? responsiveStylesToTailwind(itemStyle, ctx.breakpoints, ctx.responsiveScales) : { classes: [], dynamicStyles: {} };
|
|
1579
1850
|
const itemClasses = itemResult.classes;
|
|
1580
1851
|
const activeItemStyle = node.activeItemStyle;
|
|
1581
|
-
const activeResult = activeItemStyle ? responsiveStylesToTailwind(activeItemStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1852
|
+
const activeResult = activeItemStyle ? responsiveStylesToTailwind(activeItemStyle, ctx.breakpoints, ctx.responsiveScales) : { classes: [], dynamicStyles: {} };
|
|
1582
1853
|
const activeItemClasses = [...itemClasses, ...activeResult.classes];
|
|
1583
1854
|
const separatorStyle = node.separatorStyle;
|
|
1584
|
-
const sepResult = separatorStyle ? responsiveStylesToTailwind(separatorStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1855
|
+
const sepResult = separatorStyle ? responsiveStylesToTailwind(separatorStyle, ctx.breakpoints, ctx.responsiveScales) : { classes: [], dynamicStyles: {} };
|
|
1585
1856
|
const separatorClasses = sepResult.classes;
|
|
1586
1857
|
const localeIconMap = /* @__PURE__ */ new Map();
|
|
1587
1858
|
for (const localeConfig of i18nConfig.locales) {
|
|
@@ -1590,7 +1861,7 @@ function emitLocaleListNode(node, ctx) {
|
|
|
1590
1861
|
}
|
|
1591
1862
|
}
|
|
1592
1863
|
const flagStyle = node.flagStyle;
|
|
1593
|
-
const flagResult = flagStyle ? responsiveStylesToTailwind(flagStyle, ctx.breakpoints) : { classes: [], dynamicStyles: {} };
|
|
1864
|
+
const flagResult = flagStyle ? responsiveStylesToTailwind(flagStyle, ctx.breakpoints, ctx.responsiveScales) : { classes: [], dynamicStyles: {} };
|
|
1594
1865
|
const flagClasses = flagResult.classes;
|
|
1595
1866
|
const links = [];
|
|
1596
1867
|
const currentLocale = ctx.locale || i18nConfig.defaultLocale;
|
|
@@ -1776,7 +2047,7 @@ function propDefToTSType(def) {
|
|
|
1776
2047
|
}
|
|
1777
2048
|
function formatDefault(def) {
|
|
1778
2049
|
if (!("default" in def) || def.default === void 0) return null;
|
|
1779
|
-
const val = def.default;
|
|
2050
|
+
const val = stripRawHtmlPrefixDeep(def.default);
|
|
1780
2051
|
if (typeof val === "string") return JSON.stringify(val);
|
|
1781
2052
|
if (typeof val === "number" || typeof val === "boolean") return String(val);
|
|
1782
2053
|
if (typeof val === "object" && val !== null && "_i18n" in val) {
|
|
@@ -1818,7 +2089,7 @@ function mergeClassNameOntoRoot(template) {
|
|
|
1818
2089
|
}
|
|
1819
2090
|
return prefix + tagName + ` class={className}` + attrs + close + template.slice(fullMatch.length);
|
|
1820
2091
|
}
|
|
1821
|
-
function emitAstroComponent(name, def, allComponents, breakpoints = DEFAULT_BREAKPOINTS, defaultLocale = "en") {
|
|
2092
|
+
function emitAstroComponent(name, def, allComponents, breakpoints = DEFAULT_BREAKPOINTS, defaultLocale = "en", responsiveScales) {
|
|
1822
2093
|
const comp = def.component;
|
|
1823
2094
|
const propDefs = comp.interface || {};
|
|
1824
2095
|
const structure = comp.structure;
|
|
@@ -1836,11 +2107,22 @@ function emitAstroComponent(name, def, allComponents, breakpoints = DEFAULT_BREA
|
|
|
1836
2107
|
fileType: "component",
|
|
1837
2108
|
fileName: name,
|
|
1838
2109
|
breakpoints,
|
|
1839
|
-
|
|
2110
|
+
responsiveScales,
|
|
2111
|
+
defaultLocale,
|
|
2112
|
+
imageImports: /* @__PURE__ */ new Map(),
|
|
2113
|
+
fileDepth: 0
|
|
2114
|
+
// components live at src/components/
|
|
1840
2115
|
};
|
|
1841
2116
|
let templateBody = nodeToAstro(structure, ctx);
|
|
1842
2117
|
templateBody = mergeClassNameOntoRoot(templateBody);
|
|
1843
|
-
const frontmatter = buildFrontmatter(
|
|
2118
|
+
const frontmatter = buildFrontmatter(
|
|
2119
|
+
name,
|
|
2120
|
+
propDefs,
|
|
2121
|
+
ctx.imports,
|
|
2122
|
+
ctx.dynamicTags,
|
|
2123
|
+
ctx.needsI18nResolver ? defaultLocale : void 0,
|
|
2124
|
+
ctx.imageImports
|
|
2125
|
+
);
|
|
1844
2126
|
const styleSection = comp.css ? `
|
|
1845
2127
|
<style>
|
|
1846
2128
|
${comp.css}
|
|
@@ -1851,11 +2133,18 @@ ${comp.css}
|
|
|
1851
2133
|
${frontmatter}---
|
|
1852
2134
|
${templateBody}${styleSection}${scriptSection}`;
|
|
1853
2135
|
}
|
|
1854
|
-
function buildFrontmatter(componentName, propDefs, imports, dynamicTags, i18nDefaultLocale) {
|
|
2136
|
+
function buildFrontmatter(componentName, propDefs, imports, dynamicTags, i18nDefaultLocale, imageImports) {
|
|
1855
2137
|
const lines = [];
|
|
1856
2138
|
for (const imp of Array.from(imports).sort()) {
|
|
1857
2139
|
lines.push(`import ${imp} from './${imp}.astro';`);
|
|
1858
2140
|
}
|
|
2141
|
+
if (imageImports && imageImports.size > 0) {
|
|
2142
|
+
lines.push(`import { Picture } from 'astro:assets';`);
|
|
2143
|
+
const sortedImages = Array.from(imageImports.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
2144
|
+
for (const [varName, importPath] of sortedImages) {
|
|
2145
|
+
lines.push(`import ${varName} from '${importPath}';`);
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
1859
2148
|
if (lines.length > 0) lines.push("");
|
|
1860
2149
|
const propEntries = Object.entries(propDefs);
|
|
1861
2150
|
{
|
|
@@ -1948,7 +2237,13 @@ function transformDefineVarsJS(js, varNames) {
|
|
|
1948
2237
|
return result;
|
|
1949
2238
|
}
|
|
1950
2239
|
function buildScriptSection(js, comp, propDefs) {
|
|
1951
|
-
const
|
|
2240
|
+
const cleanTextNodes = `(function _w(n){var c=n.firstChild,x;while(c){x=c.nextSibling;if(c.nodeType===3){if(!c.textContent.trim())n.removeChild(c)}else if(c.nodeType===1)_w(c);c=x}})(el);`;
|
|
2241
|
+
const deferWrapper = (innerJS) => `var el = document.currentScript.previousElementSibling;
|
|
2242
|
+
function __init__() {
|
|
2243
|
+
${cleanTextNodes}
|
|
2244
|
+
${innerJS}
|
|
2245
|
+
}
|
|
2246
|
+
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', __init__); } else { __init__(); }`;
|
|
1952
2247
|
if (comp.defineVars) {
|
|
1953
2248
|
const vars = comp.defineVars === true ? Object.keys(propDefs).filter((k) => k !== "children") : comp.defineVars;
|
|
1954
2249
|
if (vars.length > 0) {
|
|
@@ -1956,23 +2251,25 @@ function buildScriptSection(js, comp, propDefs) {
|
|
|
1956
2251
|
const defineVarsObj = `{ ${vars.join(", ")} }`;
|
|
1957
2252
|
return `
|
|
1958
2253
|
<script define:vars={${defineVarsObj}}>
|
|
1959
|
-
|
|
1960
|
-
${transformedJS}
|
|
2254
|
+
(function(){
|
|
2255
|
+
${deferWrapper(transformedJS)}
|
|
2256
|
+
})();
|
|
1961
2257
|
</script>
|
|
1962
2258
|
`;
|
|
1963
2259
|
}
|
|
1964
2260
|
}
|
|
1965
2261
|
return `
|
|
1966
2262
|
<script is:inline>
|
|
1967
|
-
|
|
1968
|
-
${js}
|
|
2263
|
+
(function(){
|
|
2264
|
+
${deferWrapper(js)}
|
|
2265
|
+
})();
|
|
1969
2266
|
</script>
|
|
1970
2267
|
`;
|
|
1971
2268
|
}
|
|
1972
2269
|
|
|
1973
2270
|
// lib/server/astro/pageEmitter.ts
|
|
1974
2271
|
function escapeTemplateLiteral2(s) {
|
|
1975
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
2272
|
+
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1976
2273
|
}
|
|
1977
2274
|
function escapeJSX2(s) {
|
|
1978
2275
|
return s.replace(/&/g, "&").replace(/"/g, """);
|
|
@@ -1997,11 +2294,13 @@ function emitAstroPage(options) {
|
|
|
1997
2294
|
ssrFallbacks,
|
|
1998
2295
|
pageName,
|
|
1999
2296
|
breakpoints: breakpointsOpt,
|
|
2297
|
+
responsiveScales,
|
|
2000
2298
|
imageMetadataMap,
|
|
2001
2299
|
i18nConfig,
|
|
2002
2300
|
currentPageSlugMap,
|
|
2003
2301
|
slugMappings,
|
|
2004
|
-
imageFormat
|
|
2302
|
+
imageFormat,
|
|
2303
|
+
processedRawHtml
|
|
2005
2304
|
} = options;
|
|
2006
2305
|
const breakpoints = breakpointsOpt ?? DEFAULT_BREAKPOINTS;
|
|
2007
2306
|
const root = pageData.root;
|
|
@@ -2020,6 +2319,7 @@ function emitAstroPage(options) {
|
|
|
2020
2319
|
fileType: "page",
|
|
2021
2320
|
fileName: pageName,
|
|
2022
2321
|
breakpoints,
|
|
2322
|
+
responsiveScales,
|
|
2023
2323
|
imageMetadataMap,
|
|
2024
2324
|
locale,
|
|
2025
2325
|
i18nConfig,
|
|
@@ -2028,7 +2328,10 @@ function emitAstroPage(options) {
|
|
|
2028
2328
|
astroImports: /* @__PURE__ */ new Set(),
|
|
2029
2329
|
slugMappings,
|
|
2030
2330
|
i18nDefaultLocale: i18nConfig?.defaultLocale,
|
|
2031
|
-
imageFormat
|
|
2331
|
+
imageFormat,
|
|
2332
|
+
processedRawHtml,
|
|
2333
|
+
imageImports: /* @__PURE__ */ new Map(),
|
|
2334
|
+
fileDepth
|
|
2032
2335
|
};
|
|
2033
2336
|
const templateBody = nodeToAstro(root, ctx);
|
|
2034
2337
|
const importLines = [];
|
|
@@ -2037,6 +2340,13 @@ function emitAstroPage(options) {
|
|
|
2037
2340
|
importLines.push(`import { ${astroImports.join(", ")} } from 'astro:content';`);
|
|
2038
2341
|
}
|
|
2039
2342
|
importLines.push(`import BaseLayout from '${layoutImportPath2}';`);
|
|
2343
|
+
if (ctx.imageImports && ctx.imageImports.size > 0) {
|
|
2344
|
+
importLines.push(`import { Picture } from 'astro:assets';`);
|
|
2345
|
+
const sortedImages = Array.from(ctx.imageImports.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
2346
|
+
for (const [varName, importPath] of sortedImages) {
|
|
2347
|
+
importLines.push(`import ${varName} from '${importPath}';`);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2040
2350
|
const componentImports = Array.from(ctx.imports).sort();
|
|
2041
2351
|
for (const comp of componentImports) {
|
|
2042
2352
|
const path = componentImportPath(fileDepth, comp);
|
|
@@ -2087,7 +2397,7 @@ import BaseLayout from '${layoutImport}';
|
|
|
2087
2397
|
|
|
2088
2398
|
// lib/server/astro/cmsPageEmitter.ts
|
|
2089
2399
|
function escapeTemplateLiteral3(s) {
|
|
2090
|
-
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
2400
|
+
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
2091
2401
|
}
|
|
2092
2402
|
function escapeJSX3(s) {
|
|
2093
2403
|
return s.replace(/&/g, "&").replace(/"/g, """);
|
|
@@ -2206,10 +2516,12 @@ function emitCMSPage(options) {
|
|
|
2206
2516
|
ssrFallbacks,
|
|
2207
2517
|
pageName,
|
|
2208
2518
|
breakpoints: breakpointsOpt,
|
|
2519
|
+
responsiveScales,
|
|
2209
2520
|
imageMetadataMap,
|
|
2210
2521
|
i18nConfig,
|
|
2211
2522
|
isMultiLocale,
|
|
2212
|
-
slugMappings
|
|
2523
|
+
slugMappings,
|
|
2524
|
+
processedRawHtml
|
|
2213
2525
|
} = options;
|
|
2214
2526
|
const breakpoints = breakpointsOpt ?? DEFAULT_BREAKPOINTS;
|
|
2215
2527
|
const binding = "entry";
|
|
@@ -2245,6 +2557,7 @@ function emitCMSPage(options) {
|
|
|
2245
2557
|
fileType: "page",
|
|
2246
2558
|
fileName: pageName,
|
|
2247
2559
|
breakpoints,
|
|
2560
|
+
responsiveScales,
|
|
2248
2561
|
imageMetadataMap,
|
|
2249
2562
|
locale,
|
|
2250
2563
|
cmsMode: true,
|
|
@@ -2253,12 +2566,22 @@ function emitCMSPage(options) {
|
|
|
2253
2566
|
cmsWrapFn: wrapFn,
|
|
2254
2567
|
slugMappings,
|
|
2255
2568
|
i18nDefaultLocale: i18nConfig.defaultLocale,
|
|
2256
|
-
imageFormat: options.imageFormat
|
|
2569
|
+
imageFormat: options.imageFormat,
|
|
2570
|
+
processedRawHtml,
|
|
2571
|
+
imageImports: /* @__PURE__ */ new Map(),
|
|
2572
|
+
fileDepth
|
|
2257
2573
|
};
|
|
2258
2574
|
const templateBody = nodeToAstro(root, ctx);
|
|
2259
2575
|
const importLines = [];
|
|
2260
2576
|
importLines.push(`import { getCollection } from 'astro:content';`);
|
|
2261
2577
|
importLines.push(`import BaseLayout from '${layoutImportPath2}';`);
|
|
2578
|
+
if (ctx.imageImports && ctx.imageImports.size > 0) {
|
|
2579
|
+
importLines.push(`import { Picture } from 'astro:assets';`);
|
|
2580
|
+
const sortedImages = Array.from(ctx.imageImports.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
2581
|
+
for (const [varName, importPath] of sortedImages) {
|
|
2582
|
+
importLines.push(`import ${varName} from '${importPath}';`);
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2262
2585
|
const componentImports = Array.from(ctx.imports).sort();
|
|
2263
2586
|
for (const comp of componentImports) {
|
|
2264
2587
|
const path = componentImportPath2(fileDepth, comp);
|
|
@@ -2338,25 +2661,32 @@ function isStyleMapping3(value) {
|
|
|
2338
2661
|
function isResponsiveStyle3(style) {
|
|
2339
2662
|
return "base" in style || "tablet" in style || "mobile" in style;
|
|
2340
2663
|
}
|
|
2341
|
-
function collectFromStyle(style, classes, breakpoints) {
|
|
2664
|
+
function collectFromStyle(style, classes, breakpoints, responsiveScales) {
|
|
2342
2665
|
if (!style) return;
|
|
2343
2666
|
if (isResponsiveStyle3(style)) {
|
|
2344
2667
|
for (const [bp, bpStyle] of Object.entries(style)) {
|
|
2345
2668
|
if (!bpStyle) continue;
|
|
2346
2669
|
let prefix = "";
|
|
2670
|
+
let bpName;
|
|
2347
2671
|
if (bp !== "base") {
|
|
2348
2672
|
const bpValue = breakpoints[bp]?.breakpoint;
|
|
2349
2673
|
if (bpValue) {
|
|
2350
2674
|
prefix = `max-[${bpValue}px]:`;
|
|
2675
|
+
bpName = bp;
|
|
2351
2676
|
}
|
|
2352
2677
|
}
|
|
2353
|
-
collectFromFlatStyle(bpStyle, prefix, classes);
|
|
2678
|
+
collectFromFlatStyle(bpStyle, prefix, classes, breakpoints, responsiveScales, bpName);
|
|
2354
2679
|
}
|
|
2355
2680
|
} else {
|
|
2356
|
-
collectFromFlatStyle(style, "", classes);
|
|
2681
|
+
collectFromFlatStyle(style, "", classes, breakpoints, responsiveScales);
|
|
2357
2682
|
}
|
|
2358
2683
|
}
|
|
2359
|
-
function collectFromFlatStyle(style, prefix, classes) {
|
|
2684
|
+
function collectFromFlatStyle(style, prefix, classes, breakpoints, responsiveScales, sourceBreakpoint) {
|
|
2685
|
+
const shouldAutoScale = responsiveScales?.enabled === true && sourceBreakpoint === void 0;
|
|
2686
|
+
const scaleBreakpoints = shouldAutoScale ? Object.entries(breakpoints).map(([name, cfg]) => ({ name, value: cfg?.breakpoint })).filter(
|
|
2687
|
+
(bp) => typeof bp.value === "number" && bp.value > 0
|
|
2688
|
+
).sort((a, b) => b.value - a.value) : [];
|
|
2689
|
+
const baseRef = responsiveScales?.baseReference ?? 16;
|
|
2360
2690
|
for (const [property, value] of Object.entries(style)) {
|
|
2361
2691
|
if (!isStyleMapping3(value)) continue;
|
|
2362
2692
|
for (const [, cssValue] of Object.entries(value.values)) {
|
|
@@ -2364,41 +2694,58 @@ function collectFromFlatStyle(style, prefix, classes) {
|
|
|
2364
2694
|
if (twClass) {
|
|
2365
2695
|
classes.add(prefix ? `${prefix}${twClass}` : twClass);
|
|
2366
2696
|
}
|
|
2697
|
+
if (shouldAutoScale && responsiveScales) {
|
|
2698
|
+
const strValue = String(cssValue);
|
|
2699
|
+
if (strValue === "") continue;
|
|
2700
|
+
for (const { name: bpName, value: bpPixels } of scaleBreakpoints) {
|
|
2701
|
+
const scale = getScaleMultiplier(
|
|
2702
|
+
responsiveScales,
|
|
2703
|
+
property,
|
|
2704
|
+
bpName
|
|
2705
|
+
);
|
|
2706
|
+
if (scale == null) continue;
|
|
2707
|
+
const scaledValue = scalePropertyValue(strValue, baseRef, scale);
|
|
2708
|
+
if (scaledValue == null || scaledValue === strValue) continue;
|
|
2709
|
+
const scaledClass = propertyToTailwind(property, scaledValue);
|
|
2710
|
+
if (!scaledClass) continue;
|
|
2711
|
+
classes.add(`max-[${bpPixels}px]:${scaledClass}`);
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2367
2714
|
}
|
|
2368
2715
|
}
|
|
2369
2716
|
}
|
|
2370
|
-
function walkNode(node, classes, breakpoints) {
|
|
2717
|
+
function walkNode(node, classes, breakpoints, responsiveScales) {
|
|
2371
2718
|
if (!node || typeof node === "string" || typeof node === "number") return;
|
|
2372
2719
|
if (Array.isArray(node)) {
|
|
2373
2720
|
for (const child of node) {
|
|
2374
|
-
walkNode(child, classes, breakpoints);
|
|
2721
|
+
walkNode(child, classes, breakpoints, responsiveScales);
|
|
2375
2722
|
}
|
|
2376
2723
|
return;
|
|
2377
2724
|
}
|
|
2378
2725
|
if ("style" in node && node.style) {
|
|
2379
|
-
collectFromStyle(node.style, classes, breakpoints);
|
|
2726
|
+
collectFromStyle(node.style, classes, breakpoints, responsiveScales);
|
|
2380
2727
|
}
|
|
2381
2728
|
if ("interactiveStyles" in node && Array.isArray(node.interactiveStyles)) {
|
|
2382
2729
|
for (const rule of node.interactiveStyles) {
|
|
2383
2730
|
if (rule.style) {
|
|
2384
|
-
collectFromStyle(rule.style, classes, breakpoints);
|
|
2731
|
+
collectFromStyle(rule.style, classes, breakpoints, responsiveScales);
|
|
2385
2732
|
}
|
|
2386
2733
|
}
|
|
2387
2734
|
}
|
|
2388
2735
|
if ("children" in node && node.children) {
|
|
2389
2736
|
if (Array.isArray(node.children)) {
|
|
2390
2737
|
for (const child of node.children) {
|
|
2391
|
-
walkNode(child, classes, breakpoints);
|
|
2738
|
+
walkNode(child, classes, breakpoints, responsiveScales);
|
|
2392
2739
|
}
|
|
2393
2740
|
}
|
|
2394
2741
|
}
|
|
2395
2742
|
}
|
|
2396
|
-
function collectAllMappingClasses(componentDefs, breakpoints = DEFAULT_BREAKPOINTS) {
|
|
2743
|
+
function collectAllMappingClasses(componentDefs, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales) {
|
|
2397
2744
|
const classes = /* @__PURE__ */ new Set();
|
|
2398
2745
|
for (const def of Object.values(componentDefs)) {
|
|
2399
2746
|
const structure = def.component?.structure;
|
|
2400
2747
|
if (structure) {
|
|
2401
|
-
walkNode(structure, classes, breakpoints);
|
|
2748
|
+
walkNode(structure, classes, breakpoints, responsiveScales);
|
|
2402
2749
|
}
|
|
2403
2750
|
}
|
|
2404
2751
|
return classes;
|
|
@@ -2408,18 +2755,40 @@ function collectAllMappingClasses(componentDefs, breakpoints = DEFAULT_BREAKPOIN
|
|
|
2408
2755
|
function hashContent2(content) {
|
|
2409
2756
|
return createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
2410
2757
|
}
|
|
2411
|
-
function
|
|
2758
|
+
function writePageScript(javascript, scriptsDir) {
|
|
2759
|
+
if (!javascript) return [];
|
|
2760
|
+
const hash = hashContent2(javascript);
|
|
2761
|
+
const scriptFile = `${hash}.js`;
|
|
2762
|
+
if (!existsSync(scriptsDir)) {
|
|
2763
|
+
mkdirSync(scriptsDir, { recursive: true });
|
|
2764
|
+
}
|
|
2765
|
+
const fullScriptPath = join(scriptsDir, scriptFile);
|
|
2766
|
+
if (!existsSync(fullScriptPath)) {
|
|
2767
|
+
writeFileSync(fullScriptPath, javascript, "utf-8");
|
|
2768
|
+
}
|
|
2769
|
+
return [`/_scripts/${scriptFile}`];
|
|
2770
|
+
}
|
|
2771
|
+
function copyDirectory(src, dest, filter) {
|
|
2412
2772
|
if (!existsSync(src)) return;
|
|
2413
2773
|
if (!existsSync(dest)) mkdirSync(dest, { recursive: true });
|
|
2414
2774
|
const files = readdirSync(src);
|
|
2415
2775
|
for (const file of files) {
|
|
2776
|
+
if (filter && !filter(file)) continue;
|
|
2416
2777
|
const srcPath = join(src, file);
|
|
2417
2778
|
const destPath = join(dest, file);
|
|
2418
2779
|
const stat = statSync(srcPath);
|
|
2419
|
-
if (stat.isDirectory()) copyDirectory(srcPath, destPath);
|
|
2780
|
+
if (stat.isDirectory()) copyDirectory(srcPath, destPath, filter);
|
|
2420
2781
|
else copyFileSync(srcPath, destPath);
|
|
2421
2782
|
}
|
|
2422
2783
|
}
|
|
2784
|
+
var imageVariantSuffixRe = new RegExp(
|
|
2785
|
+
`-(${RESPONSIVE_WIDTHS.join("|")})\\.(webp|avif)$`
|
|
2786
|
+
);
|
|
2787
|
+
function shouldCopyImageForAstro(filename) {
|
|
2788
|
+
if (filename === "manifest.json") return false;
|
|
2789
|
+
if (imageVariantSuffixRe.test(filename)) return false;
|
|
2790
|
+
return true;
|
|
2791
|
+
}
|
|
2423
2792
|
function isCMSPage(pageData) {
|
|
2424
2793
|
return pageData.meta?.source === "cms" && !!pageData.meta?.cms;
|
|
2425
2794
|
}
|
|
@@ -2588,6 +2957,7 @@ async function buildAstroProject(projectRoot, outputDir) {
|
|
|
2588
2957
|
const allComponentCSS = /* @__PURE__ */ new Set();
|
|
2589
2958
|
const jsContents = /* @__PURE__ */ new Map();
|
|
2590
2959
|
let errorCount = 0;
|
|
2960
|
+
let projectNeedsFormHandler = false;
|
|
2591
2961
|
function mergeInteractiveStyles(source) {
|
|
2592
2962
|
for (const [key, value] of source) {
|
|
2593
2963
|
if (!allInteractiveStyles.has(key)) {
|
|
@@ -2606,6 +2976,9 @@ async function buildAstroProject(projectRoot, outputDir) {
|
|
|
2606
2976
|
jsContents.set(hash, result.javascript);
|
|
2607
2977
|
}
|
|
2608
2978
|
}
|
|
2979
|
+
if (!projectNeedsFormHandler && needsFormHandler(result.html)) {
|
|
2980
|
+
projectNeedsFormHandler = true;
|
|
2981
|
+
}
|
|
2609
2982
|
allResults.push({
|
|
2610
2983
|
html: result.html,
|
|
2611
2984
|
meta: result.meta,
|
|
@@ -2620,7 +2993,8 @@ async function buildAstroProject(projectRoot, outputDir) {
|
|
|
2620
2993
|
pageData,
|
|
2621
2994
|
pageName,
|
|
2622
2995
|
isCMSPage: isCMSPage3,
|
|
2623
|
-
ssrFallbackCollector: result.ssrFallbackCollector
|
|
2996
|
+
ssrFallbackCollector: result.ssrFallbackCollector,
|
|
2997
|
+
processedRawHtmlCollector: result.processedRawHtmlCollector
|
|
2624
2998
|
});
|
|
2625
2999
|
}
|
|
2626
3000
|
for (const file of pageFiles) {
|
|
@@ -2680,8 +3054,39 @@ async function buildAstroProject(projectRoot, outputDir) {
|
|
|
2680
3054
|
const fontPreloads = generateFontPreloadTags();
|
|
2681
3055
|
const mergedLibraries = mergeLibraries(globalLibraries, componentLibraries);
|
|
2682
3056
|
const buildLibraries = filterLibrariesByContext(mergedLibraries, "build");
|
|
2683
|
-
const
|
|
3057
|
+
const inlineContents = /* @__PURE__ */ new Map();
|
|
3058
|
+
const localLibsToCopy = [];
|
|
3059
|
+
for (const css of buildLibraries.css || []) {
|
|
3060
|
+
if (!css.url.startsWith("/")) continue;
|
|
3061
|
+
const shouldInline = css.inline !== false;
|
|
3062
|
+
const relPath = css.url.slice(1);
|
|
3063
|
+
const srcPath = join(projectPaths.project, relPath);
|
|
3064
|
+
if (!existsSync(srcPath)) continue;
|
|
3065
|
+
if (shouldInline) {
|
|
3066
|
+
try {
|
|
3067
|
+
inlineContents.set(css.url, await readFile(srcPath, "utf-8"));
|
|
3068
|
+
} catch {
|
|
3069
|
+
localLibsToCopy.push(relPath);
|
|
3070
|
+
}
|
|
3071
|
+
} else {
|
|
3072
|
+
localLibsToCopy.push(relPath);
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
for (const js of buildLibraries.js || []) {
|
|
3076
|
+
if (js.url.startsWith("/")) {
|
|
3077
|
+
const relPath = js.url.slice(1);
|
|
3078
|
+
if (existsSync(join(projectPaths.project, relPath))) {
|
|
3079
|
+
localLibsToCopy.push(relPath);
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
const libraryTags = generateLibraryTags(buildLibraries, inlineContents);
|
|
2684
3084
|
const defaultTheme = themeConfig.default || "light";
|
|
3085
|
+
const customCode = configService.getCustomCode();
|
|
3086
|
+
const iconsConfig = await loadIconsConfig();
|
|
3087
|
+
const faviconTag = iconsConfig.favicon ? `<link rel="icon" href="${iconsConfig.favicon.replace(/"/g, """)}" />` : "";
|
|
3088
|
+
const appleTouchIconTag = iconsConfig.appleTouchIcon ? `<link rel="apple-touch-icon" href="${iconsConfig.appleTouchIcon.replace(/"/g, """)}" />` : "";
|
|
3089
|
+
const iconTagsHtml = [faviconTag, appleTouchIconTag].filter(Boolean).join("\n ");
|
|
2685
3090
|
const templatesDir = projectPaths.templates();
|
|
2686
3091
|
const templateSchemas = [];
|
|
2687
3092
|
let cmsPageCount = 0;
|
|
@@ -2776,12 +3181,14 @@ Processing ${templateFiles.length} CMS template(s)...
|
|
|
2776
3181
|
ssrFallbacks,
|
|
2777
3182
|
pageName: file.replace(".json", ""),
|
|
2778
3183
|
breakpoints,
|
|
3184
|
+
responsiveScales,
|
|
2779
3185
|
imageMetadataMap,
|
|
2780
3186
|
i18nConfig,
|
|
2781
3187
|
isMultiLocale: false,
|
|
2782
3188
|
// Each file handles one locale
|
|
2783
3189
|
slugMappings,
|
|
2784
|
-
imageFormat: configService.getImageFormat()
|
|
3190
|
+
imageFormat: configService.getImageFormat(),
|
|
3191
|
+
processedRawHtml: metaResult.processedRawHtmlCollector
|
|
2785
3192
|
});
|
|
2786
3193
|
const astroFileFull = join(pagesOutDir, astroFilePath);
|
|
2787
3194
|
const astroFileDir = astroFileFull.substring(0, astroFileFull.lastIndexOf("/"));
|
|
@@ -2798,12 +3205,12 @@ Processing ${templateFiles.length} CMS template(s)...
|
|
|
2798
3205
|
}
|
|
2799
3206
|
}
|
|
2800
3207
|
}
|
|
2801
|
-
const mappingClasses = collectAllMappingClasses(globalComponents, breakpoints);
|
|
3208
|
+
const mappingClasses = collectAllMappingClasses(globalComponents, breakpoints, responsiveScales);
|
|
2802
3209
|
const fontCSS = generateFontCSS();
|
|
2803
3210
|
const themeColorCSS = generateThemeColorVariablesCSS(themeConfig);
|
|
2804
3211
|
const variablesCSS = generateVariablesCSS(variablesConfig, breakpoints, responsiveScales);
|
|
2805
3212
|
const remConversionConfig = configService.getRemConversion();
|
|
2806
|
-
const interactiveCSS = generateAllInteractiveCSS(allInteractiveStyles, breakpoints, remConversionConfig);
|
|
3213
|
+
const interactiveCSS = generateAllInteractiveCSS(allInteractiveStyles, breakpoints, remConversionConfig, responsiveScales);
|
|
2807
3214
|
const componentCSSCombined = Array.from(allComponentCSS).join("\n");
|
|
2808
3215
|
const baseCSS = `@layer base {
|
|
2809
3216
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
@@ -2814,13 +3221,24 @@ Processing ${templateFiles.length} CMS template(s)...
|
|
|
2814
3221
|
.olink { text-decoration: none; display: block; }
|
|
2815
3222
|
.oem { display: inline-block; }
|
|
2816
3223
|
}`;
|
|
2817
|
-
const
|
|
2818
|
-
|
|
2819
|
-
|
|
3224
|
+
const safelistClasses = Array.from(mappingClasses);
|
|
3225
|
+
const safelistDirectives = safelistClasses.map((c) => `@source inline("${c}");`).join("\n");
|
|
3226
|
+
const tailwindDirectives = safelistDirectives ? `@import "tailwindcss";
|
|
3227
|
+
|
|
3228
|
+
${safelistDirectives}` : `@import "tailwindcss";`;
|
|
2820
3229
|
const globalCSS = [tailwindDirectives, fontCSS, themeColorCSS, variablesCSS, baseCSS, componentCSSCombined, interactiveCSS].filter(Boolean).join("\n\n");
|
|
2821
3230
|
await writeFile2(join(stylesDir, "global.css"), globalCSS, "utf-8");
|
|
2822
3231
|
console.log(`
|
|
2823
3232
|
Generated global.css (${(globalCSS.length / 1024).toFixed(1)} KB)`);
|
|
3233
|
+
const escForTemplateLiteral = (s) => s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
3234
|
+
const customHeadLiteral = escForTemplateLiteral(customCode.head || "");
|
|
3235
|
+
const customBodyStartLiteral = escForTemplateLiteral(customCode.bodyStart || "");
|
|
3236
|
+
const customBodyEndLiteral = escForTemplateLiteral(customCode.bodyEnd || "");
|
|
3237
|
+
const iconTagsLiteral = escForTemplateLiteral(iconTagsHtml);
|
|
3238
|
+
const formHandlerBlock = projectNeedsFormHandler ? `
|
|
3239
|
+
<script is:inline>
|
|
3240
|
+
${formHandlerScript}
|
|
3241
|
+
</script>` : "";
|
|
2824
3242
|
const baseLayoutContent = `---
|
|
2825
3243
|
import '../styles/global.css';
|
|
2826
3244
|
|
|
@@ -2841,16 +3259,20 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
2841
3259
|
<head>
|
|
2842
3260
|
<meta charset="UTF-8">
|
|
2843
3261
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3262
|
+
<Fragment set:html={\`${iconTagsLiteral}\`} />
|
|
2844
3263
|
<Fragment set:html={fontPreloads} />
|
|
2845
3264
|
<Fragment set:html={libraryTags.headCSS || ''} />
|
|
2846
3265
|
<Fragment set:html={libraryTags.headJS || ''} />
|
|
2847
3266
|
<Fragment set:html={meta} />
|
|
3267
|
+
<Fragment set:html={\`${customHeadLiteral}\`} />
|
|
2848
3268
|
<title>{title}</title>
|
|
2849
3269
|
</head>
|
|
2850
3270
|
<body>
|
|
3271
|
+
<Fragment set:html={\`${customBodyStartLiteral}\`} />
|
|
2851
3272
|
<slot />
|
|
2852
3273
|
{scripts.map((s) => <script src={s} />)}
|
|
2853
3274
|
<Fragment set:html={libraryTags.bodyEndJS || ''} />
|
|
3275
|
+
<Fragment set:html={\`${customBodyEndLiteral}\`} />${formHandlerBlock}
|
|
2854
3276
|
</body>
|
|
2855
3277
|
</html>
|
|
2856
3278
|
`;
|
|
@@ -2859,7 +3281,7 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
2859
3281
|
let componentFileCount = 0;
|
|
2860
3282
|
for (const [compName, compDef] of Object.entries(globalComponents)) {
|
|
2861
3283
|
try {
|
|
2862
|
-
const astroContent = emitAstroComponent(compName, compDef, globalComponents, breakpoints, i18nConfig.defaultLocale);
|
|
3284
|
+
const astroContent = emitAstroComponent(compName, compDef, globalComponents, breakpoints, i18nConfig.defaultLocale, responsiveScales);
|
|
2863
3285
|
await writeFile2(join(componentsOutDir, `${compName}.astro`), astroContent, "utf-8");
|
|
2864
3286
|
componentFileCount++;
|
|
2865
3287
|
} catch (error) {
|
|
@@ -2869,20 +3291,7 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
2869
3291
|
console.log(`Generated ${componentFileCount} component .astro file(s)`);
|
|
2870
3292
|
for (const result of allResults) {
|
|
2871
3293
|
const importPath = layoutImportPath(result.fileDepth);
|
|
2872
|
-
|
|
2873
|
-
if (result.javascript) {
|
|
2874
|
-
const hash = hashContent2(result.javascript);
|
|
2875
|
-
const scriptFile = `${hash}.js`;
|
|
2876
|
-
const scriptPublicPath = `/_scripts/${scriptFile}`;
|
|
2877
|
-
if (!existsSync(scriptsDir)) {
|
|
2878
|
-
mkdirSync(scriptsDir, { recursive: true });
|
|
2879
|
-
}
|
|
2880
|
-
const fullScriptPath = join(scriptsDir, scriptFile);
|
|
2881
|
-
if (!existsSync(fullScriptPath)) {
|
|
2882
|
-
await writeFile2(fullScriptPath, result.javascript, "utf-8");
|
|
2883
|
-
}
|
|
2884
|
-
scriptPaths.push(scriptPublicPath);
|
|
2885
|
-
}
|
|
3294
|
+
let scriptPaths = [];
|
|
2886
3295
|
let astroContent;
|
|
2887
3296
|
if (result.pageData) {
|
|
2888
3297
|
try {
|
|
@@ -2897,23 +3306,27 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
2897
3306
|
theme: defaultTheme,
|
|
2898
3307
|
fontPreloads,
|
|
2899
3308
|
libraryTags,
|
|
2900
|
-
scriptPaths,
|
|
3309
|
+
scriptPaths: [],
|
|
2901
3310
|
layoutImportPath: importPath,
|
|
2902
3311
|
fileDepth: result.fileDepth,
|
|
2903
3312
|
ssrFallbacks,
|
|
2904
3313
|
pageName: result.pageName || "index",
|
|
2905
3314
|
breakpoints,
|
|
3315
|
+
responsiveScales,
|
|
2906
3316
|
imageMetadataMap,
|
|
2907
3317
|
i18nConfig: i18nConfig.locales.length > 1 ? i18nConfig : void 0,
|
|
2908
3318
|
currentPageSlugMap: pageSlugMap,
|
|
2909
3319
|
slugMappings: i18nConfig.locales.length > 1 ? slugMappings : void 0,
|
|
2910
|
-
imageFormat: configService.getImageFormat()
|
|
3320
|
+
imageFormat: configService.getImageFormat(),
|
|
3321
|
+
processedRawHtml: result.processedRawHtmlCollector
|
|
2911
3322
|
});
|
|
2912
3323
|
} catch (error) {
|
|
2913
3324
|
console.warn(` Warning: component emission failed for ${result.urlPath}, using SSR fallback: ${error?.message}`);
|
|
3325
|
+
scriptPaths = writePageScript(result.javascript, scriptsDir);
|
|
2914
3326
|
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
2915
3327
|
}
|
|
2916
3328
|
} else {
|
|
3329
|
+
scriptPaths = writePageScript(result.javascript, scriptsDir);
|
|
2917
3330
|
astroContent = buildSSRFallbackPage(result, importPath, fontPreloads, libraryTags, defaultTheme, scriptPaths);
|
|
2918
3331
|
}
|
|
2919
3332
|
const astroFileFull = join(pagesOutDir, result.astroFilePath);
|
|
@@ -2924,6 +3337,24 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
2924
3337
|
await writeFile2(astroFileFull, astroContent, "utf-8");
|
|
2925
3338
|
}
|
|
2926
3339
|
console.log(`Generated ${allResults.length} .astro page file(s)`);
|
|
3340
|
+
const robotsTsContent = `import type { APIRoute } from 'astro';
|
|
3341
|
+
|
|
3342
|
+
export const GET: APIRoute = () => {
|
|
3343
|
+
const siteUrl = import.meta.env.SITE;
|
|
3344
|
+
const robotsTxt = [
|
|
3345
|
+
'User-agent: *',
|
|
3346
|
+
'Allow: /',
|
|
3347
|
+
'',
|
|
3348
|
+
siteUrl ? \`Sitemap: \${siteUrl}/sitemap-index.xml\` : '',
|
|
3349
|
+
].filter(Boolean).join('\\n');
|
|
3350
|
+
|
|
3351
|
+
return new Response(robotsTxt, {
|
|
3352
|
+
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
|
|
3353
|
+
});
|
|
3354
|
+
};
|
|
3355
|
+
`;
|
|
3356
|
+
await writeFile2(join(pagesOutDir, "robots.txt.ts"), robotsTsContent, "utf-8");
|
|
3357
|
+
console.log("Generated robots.txt.ts endpoint");
|
|
2927
3358
|
let collectionCount = 0;
|
|
2928
3359
|
if (templateSchemas.length > 0) {
|
|
2929
3360
|
const contentDir = join(srcDir, "content");
|
|
@@ -2959,7 +3390,7 @@ const { title, meta = '', scripts = [], locale = 'en', theme = '${themeConfig.de
|
|
|
2959
3390
|
}
|
|
2960
3391
|
}
|
|
2961
3392
|
collectionDefs.push(` '${schema.id}': defineCollection({
|
|
2962
|
-
|
|
3393
|
+
loader: glob({ pattern: '**/*.json', base: './src/content/${schema.id}' }),
|
|
2963
3394
|
schema: z.object({
|
|
2964
3395
|
${fieldDefs.join(",\n")}
|
|
2965
3396
|
})
|
|
@@ -2967,6 +3398,7 @@ ${fieldDefs.join(",\n")}
|
|
|
2967
3398
|
collectionCount++;
|
|
2968
3399
|
}
|
|
2969
3400
|
const configContent = `import { z, defineCollection } from 'astro:content';
|
|
3401
|
+
import { glob } from 'astro/loaders';
|
|
2970
3402
|
|
|
2971
3403
|
const collections = {
|
|
2972
3404
|
${collectionDefs.join(",\n")}
|
|
@@ -2974,12 +3406,18 @@ ${collectionDefs.join(",\n")}
|
|
|
2974
3406
|
|
|
2975
3407
|
export { collections };
|
|
2976
3408
|
`;
|
|
2977
|
-
await writeFile2(join(
|
|
2978
|
-
console.log(`Generated ${collectionCount} content collection(s) with config.ts`);
|
|
3409
|
+
await writeFile2(join(srcDir, "content.config.ts"), configContent, "utf-8");
|
|
3410
|
+
console.log(`Generated ${collectionCount} content collection(s) with content.config.ts`);
|
|
2979
3411
|
}
|
|
2980
|
-
const assetDirs = ["fonts", "images", "icons", "videos", "assets"];
|
|
2981
3412
|
let copiedAssets = 0;
|
|
2982
|
-
|
|
3413
|
+
const imagesSrcDir = join(projectPaths.project, "images");
|
|
3414
|
+
if (existsSync(imagesSrcDir)) {
|
|
3415
|
+
copyDirectory(imagesSrcDir, join(srcDir, "assets", "images"), shouldCopyImageForAstro);
|
|
3416
|
+
copyDirectory(imagesSrcDir, join(publicDir, "images"));
|
|
3417
|
+
copiedAssets++;
|
|
3418
|
+
}
|
|
3419
|
+
const publicAssetDirs = ["fonts", "icons", "videos", "assets"];
|
|
3420
|
+
for (const dir of publicAssetDirs) {
|
|
2983
3421
|
const srcAssetDir = join(projectPaths.project, dir);
|
|
2984
3422
|
if (existsSync(srcAssetDir)) {
|
|
2985
3423
|
copyDirectory(srcAssetDir, join(publicDir, dir));
|
|
@@ -2991,6 +3429,14 @@ export { collections };
|
|
|
2991
3429
|
copyDirectory(librariesDir, join(publicDir, "libraries"));
|
|
2992
3430
|
copiedAssets++;
|
|
2993
3431
|
}
|
|
3432
|
+
for (const relPath of localLibsToCopy) {
|
|
3433
|
+
const srcPath = join(projectPaths.project, relPath);
|
|
3434
|
+
const destPath = join(publicDir, relPath);
|
|
3435
|
+
const destDir = destPath.substring(0, destPath.lastIndexOf("/"));
|
|
3436
|
+
if (destDir && !existsSync(destDir)) mkdirSync(destDir, { recursive: true });
|
|
3437
|
+
copyFileSync(srcPath, destPath);
|
|
3438
|
+
copiedAssets++;
|
|
3439
|
+
}
|
|
2994
3440
|
if (copiedAssets > 0) {
|
|
2995
3441
|
console.log(`Copied ${copiedAssets} asset director${copiedAssets === 1 ? "y" : "ies"} to public/`);
|
|
2996
3442
|
}
|
|
@@ -3006,9 +3452,14 @@ export { collections };
|
|
|
3006
3452
|
preview: "astro preview"
|
|
3007
3453
|
},
|
|
3008
3454
|
dependencies: {
|
|
3009
|
-
"astro": "^
|
|
3010
|
-
"@astrojs/
|
|
3011
|
-
"tailwindcss": "^
|
|
3455
|
+
"astro": "^6.0.0",
|
|
3456
|
+
"@astrojs/sitemap": "^3.0.0",
|
|
3457
|
+
"@tailwindcss/vite": "^4.0.0",
|
|
3458
|
+
"tailwindcss": "^4.0.0"
|
|
3459
|
+
},
|
|
3460
|
+
// Astro 6 expects Vite 7; pin it so npm doesn't pull Vite 8+ and warn.
|
|
3461
|
+
overrides: {
|
|
3462
|
+
"vite": "^7.0.0"
|
|
3012
3463
|
}
|
|
3013
3464
|
};
|
|
3014
3465
|
await writeFile2(join(outDir, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8");
|
|
@@ -3020,34 +3471,23 @@ export { collections };
|
|
|
3020
3471
|
routing: { prefixDefaultLocale: false },
|
|
3021
3472
|
},` : "";
|
|
3022
3473
|
const astroConfig = `import { defineConfig } from 'astro/config';
|
|
3023
|
-
import
|
|
3474
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
3475
|
+
import sitemap from '@astrojs/sitemap';
|
|
3024
3476
|
|
|
3025
3477
|
export default defineConfig({${siteUrl ? `
|
|
3026
3478
|
site: '${siteUrl}',` : ""}${i18nBlock}
|
|
3027
|
-
integrations: [
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
const safelistArray = Array.from(mappingClasses);
|
|
3031
|
-
const safelistLiteral = safelistArray.length > 0 ? `
|
|
3032
|
-
safelist: [
|
|
3033
|
-
${safelistArray.map((c) => ` '${c}'`).join(",\n")}
|
|
3034
|
-
],` : "";
|
|
3035
|
-
const tailwindConfig = `/** @type {import('tailwindcss').Config} */
|
|
3036
|
-
export default {
|
|
3037
|
-
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],${safelistLiteral}
|
|
3038
|
-
theme: {
|
|
3039
|
-
extend: {},
|
|
3479
|
+
integrations: [sitemap()],
|
|
3480
|
+
vite: {
|
|
3481
|
+
plugins: [tailwindcss()],
|
|
3040
3482
|
},
|
|
3041
|
-
|
|
3042
|
-
};
|
|
3483
|
+
});
|
|
3043
3484
|
`;
|
|
3044
|
-
await writeFile2(join(outDir, "tailwind.config.mjs"), tailwindConfig, "utf-8");
|
|
3045
3485
|
await writeFile2(join(outDir, "astro.config.mjs"), astroConfig, "utf-8");
|
|
3046
3486
|
const tsConfig = {
|
|
3047
3487
|
extends: "astro/tsconfigs/strict"
|
|
3048
3488
|
};
|
|
3049
3489
|
await writeFile2(join(outDir, "tsconfig.json"), JSON.stringify(tsConfig, null, 2), "utf-8");
|
|
3050
|
-
console.log("Generated package.json, astro.config.mjs,
|
|
3490
|
+
console.log("Generated package.json, astro.config.mjs, tsconfig.json");
|
|
3051
3491
|
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
3052
3492
|
const totalPages = allResults.length;
|
|
3053
3493
|
console.log("\n" + "=".repeat(50));
|
|
@@ -3062,6 +3502,10 @@ export default {
|
|
|
3062
3502
|
if (errorCount > 0) {
|
|
3063
3503
|
console.log(` Errors: ${errorCount}`);
|
|
3064
3504
|
}
|
|
3505
|
+
console.log(` SEO: sitemap (@astrojs/sitemap), robots.txt`);
|
|
3506
|
+
if (projectNeedsFormHandler) {
|
|
3507
|
+
console.log(` Forms: fetch handler injected`);
|
|
3508
|
+
}
|
|
3065
3509
|
console.log(` Time: ${elapsed}s`);
|
|
3066
3510
|
console.log(` Output: ${outDir}`);
|
|
3067
3511
|
console.log("");
|