@stacksjs/stx 0.2.342 → 0.2.343
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/dist/caching.js +1 -0
- package/dist/{chunk-48x5bsqv.js → chunk-0dpgh7a6.js} +1 -1
- package/dist/{chunk-evtrctj9.js → chunk-0fp16c1x.js} +1 -1
- package/dist/{chunk-p5d8sb50.js → chunk-0s3ry262.js} +1 -1
- package/dist/{chunk-tmj45xq5.js → chunk-12qteqk8.js} +1 -1
- package/dist/chunk-160g7ynw.js +2 -0
- package/dist/chunk-16hr5y08.js +2 -0
- package/dist/{chunk-anf2y2h5.js → chunk-1bfvdjpy.js} +1 -1
- package/dist/{chunk-y956wapy.js → chunk-1h1c2048.js} +1 -1
- package/dist/{chunk-bt8w146r.js → chunk-1qtd4ex2.js} +2 -2
- package/dist/{chunk-2swnc8kg.js → chunk-1zav2sf1.js} +1 -1
- package/dist/{chunk-gbkq5qnw.js → chunk-2853ye06.js} +2 -2
- package/dist/{chunk-4vcyf1kh.js → chunk-36j9qset.js} +2 -2
- package/dist/{chunk-74r1zw2h.js → chunk-3d3x7dwy.js} +1 -1
- package/dist/chunk-3h97y3n3.js +2 -0
- package/dist/chunk-3j915h2d.js +2 -0
- package/dist/{chunk-1gwbw81h.js → chunk-45ydb29q.js} +1 -1
- package/dist/{chunk-ts3wfjh9.js → chunk-4fafxr8d.js} +1 -1
- package/dist/chunk-4hkg6kx4.js +2 -0
- package/dist/{chunk-8tsr51hj.js → chunk-4pg6wbt6.js} +1 -1
- package/dist/{chunk-saqbtgqr.js → chunk-4vd0rqfs.js} +1 -1
- package/dist/{chunk-wv8h3d68.js → chunk-53sjbp3z.js} +1 -1
- package/dist/chunk-57494khk.js +2 -0
- package/dist/{chunk-4wpxbkbe.js → chunk-57dxdvjh.js} +1 -1
- package/dist/{chunk-k3w3gwm3.js → chunk-5azeswj2.js} +1 -1
- package/dist/{chunk-k5b9471y.js → chunk-5hq25yky.js} +1 -1
- package/dist/chunk-5xavmr4t.js +2 -0
- package/dist/{chunk-kznb3hdj.js → chunk-5zemhhwe.js} +1 -1
- package/dist/{chunk-ghd80w8a.js → chunk-62vng8g8.js} +2 -2
- package/dist/{chunk-reskzmsb.js → chunk-649dfqqz.js} +1 -1
- package/dist/{chunk-6nxq8rcw.js → chunk-6g8rvnhc.js} +1 -1
- package/dist/chunk-6rsfkms1.js +2 -0
- package/dist/{chunk-xe93ae3r.js → chunk-6xs80tka.js} +3 -3
- package/dist/{chunk-s4mmmwj4.js → chunk-7mc1k1tq.js} +1 -1
- package/dist/{chunk-25b8z7xa.js → chunk-7r79j1hs.js} +1 -1
- package/dist/{chunk-drs93sry.js → chunk-7yfk9393.js} +1 -1
- package/dist/{chunk-r46cg4qa.js → chunk-7zxv2631.js} +1 -1
- package/dist/{chunk-d389vyyz.js → chunk-8ah5mhst.js} +2 -2
- package/dist/{chunk-zv4gb3wb.js → chunk-905j49fe.js} +1 -1
- package/dist/chunk-9czj483k.js +2 -0
- package/dist/chunk-9kv0qavn.js +2 -0
- package/dist/{chunk-m39hb2a2.js → chunk-a0ajg9z5.js} +1 -1
- package/dist/{chunk-mznr9nyp.js → chunk-ag8gdk51.js} +1 -1
- package/dist/{chunk-gwc54hjc.js → chunk-amfq5rnz.js} +2 -2
- package/dist/{chunk-rh7mwwb4.js → chunk-aqxwwq6w.js} +2 -2
- package/dist/{chunk-hk8j3eps.js → chunk-ay336sqb.js} +1 -1
- package/dist/chunk-bcz8yp2g.js +2 -0
- package/dist/{chunk-rr49zrz6.js → chunk-brjfzbq9.js} +1 -1
- package/dist/chunk-bxefsc7k.js +2 -0
- package/dist/chunk-c4kv3r8t.js +2 -0
- package/dist/{chunk-yzv702kk.js → chunk-c7qdnc5d.js} +1 -1
- package/dist/{chunk-ys56ecvx.js → chunk-daxr6p6q.js} +1 -1
- package/dist/{chunk-yhvrq2qd.js → chunk-dj5mqnp1.js} +1 -1
- package/dist/{chunk-da0tfpa2.js → chunk-e53pwshq.js} +1 -1
- package/dist/{chunk-k9ep24bd.js → chunk-e6rxvz3p.js} +1 -1
- package/dist/{chunk-x7dv5rq7.js → chunk-ec18ftcg.js} +1 -1
- package/dist/chunk-eh3meyd3.js +64 -0
- package/dist/{chunk-yq7fc8sa.js → chunk-em8cr7wy.js} +1 -1
- package/dist/{chunk-thrv2nbz.js → chunk-ey1tsk22.js} +1 -1
- package/dist/{chunk-e0kzyf1g.js → chunk-fbmjw0bh.js} +1 -1
- package/dist/chunk-fytemc96.js +2 -0
- package/dist/{chunk-zv4nf0x2.js → chunk-g0dbtyk7.js} +1 -1
- package/dist/chunk-g7gc0ten.js +2 -0
- package/dist/chunk-gqsxxd81.js +2 -0
- package/dist/{chunk-sytwy0mg.js → chunk-grnmr3y1.js} +1 -1
- package/dist/{chunk-4ecv1e3w.js → chunk-gvfgrve8.js} +1 -1
- package/dist/chunk-gx9z0wmm.js +2 -0
- package/dist/{chunk-3b0mgxbk.js → chunk-h6y99nak.js} +1 -1
- package/dist/chunk-hq3phk1a.js +3 -0
- package/dist/{chunk-01ggk8k8.js → chunk-hrdd26r4.js} +1 -1
- package/dist/{chunk-567g1ttv.js → chunk-hzbty7hz.js} +1 -1
- package/dist/{chunk-6nvm939g.js → chunk-jagf7h9y.js} +1 -1
- package/dist/{chunk-xec226zb.js → chunk-jh6f1a9y.js} +1 -1
- package/dist/chunk-jnxzzzm4.js +2 -0
- package/dist/chunk-jy6jwxhs.js +2 -0
- package/dist/{chunk-r1rfwm01.js → chunk-k3dtvay1.js} +1 -1
- package/dist/chunk-k8skvm0d.js +2 -0
- package/dist/{chunk-1xwfws06.js → chunk-kbah2k8e.js} +2 -2
- package/dist/{chunk-beextc84.js → chunk-kgbz86sa.js} +2 -2
- package/dist/chunk-khqn40gv.js +2 -0
- package/dist/{chunk-fx29n4vc.js → chunk-m0xaw0qw.js} +1 -1
- package/dist/chunk-mhbzrh5y.js +2 -0
- package/dist/{chunk-mbstfjnj.js → chunk-mwvxhv0r.js} +1 -1
- package/dist/{chunk-cqw3c1xg.js → chunk-p3awq80d.js} +1 -1
- package/dist/chunk-p8anntjb.js +2 -0
- package/dist/chunk-pwe51myj.js +2 -0
- package/dist/{chunk-gkq323fg.js → chunk-pwhf5kte.js} +1 -1
- package/dist/{chunk-25f0s8t1.js → chunk-q6825wwz.js} +1 -1
- package/dist/{chunk-f2qbjr3z.js → chunk-q9ckfwhh.js} +1 -1
- package/dist/{chunk-ytx17bg2.js → chunk-rns7wjy9.js} +1 -1
- package/dist/chunk-rqqdvnp5.js +2 -0
- package/dist/chunk-rzg9pars.js +7 -0
- package/dist/{chunk-yr7camcd.js → chunk-s60eccqk.js} +1 -1
- package/dist/{chunk-ntm1761b.js → chunk-s7qbba8r.js} +10 -10
- package/dist/{chunk-hrmxxs0w.js → chunk-safmgrq5.js} +1 -1
- package/dist/{chunk-ebd3z4j9.js → chunk-stqm4brp.js} +1 -1
- package/dist/{chunk-1t3j8a0q.js → chunk-t00ga194.js} +1 -1
- package/dist/{chunk-fm5211ec.js → chunk-tqw1yean.js} +1 -1
- package/dist/{chunk-hnffkdzc.js → chunk-tz68qv47.js} +1 -1
- package/dist/{chunk-1spzqjve.js → chunk-vaggjvsm.js} +1 -1
- package/dist/{chunk-q4cemvkw.js → chunk-vj3nx26v.js} +1 -1
- package/dist/chunk-w1mbrq1g.js +2 -0
- package/dist/chunk-w84qe2m6.js +2 -0
- package/dist/{chunk-c33y19bn.js → chunk-wdaf98ya.js} +1 -1
- package/dist/chunk-wjm7hv5e.js +2 -0
- package/dist/{chunk-byjy9far.js → chunk-wnmegbw0.js} +1 -1
- package/dist/{chunk-0sq5mdrh.js → chunk-wyhb3nb0.js} +1 -1
- package/dist/{chunk-j82hfkcf.js → chunk-xgw269cf.js} +234 -236
- package/dist/{chunk-jcbj3xp4.js → chunk-y5sxa2sq.js} +1 -1
- package/dist/{chunk-mkgbrbr9.js → chunk-yefnrr5z.js} +1 -1
- package/dist/chunk-yr7s02f7.js +2 -0
- package/dist/{chunk-p52cm7ch.js → chunk-z9hb80mk.js} +1 -1
- package/dist/{chunk-c73pyeak.js → chunk-zcytk5w9.js} +1 -1
- package/dist/chunk-zq3tm2c2.js +2 -0
- package/dist/{chunk-5g9vbhbt.js → chunk-zr1x54bt.js} +1 -1
- package/dist/cli.js +14 -14
- package/dist/craft-entry.js +1 -1
- package/dist/craft.js +1 -1
- package/dist/custom-directives.js +21 -8
- package/dist/database.js +1 -1
- package/dist/directive-arguments.d.ts +107 -0
- package/dist/directive-arguments.js +171 -0
- package/dist/head.d.ts +7 -30
- package/dist/head.js +15 -5
- package/dist/meta-arguments.d.ts +52 -0
- package/dist/meta-arguments.js +55 -0
- package/dist/process.js +1 -1
- package/dist/pwa.js +2 -2
- package/dist/seo.d.ts +39 -17
- package/dist/seo.js +221 -255
- package/dist/ssg.js +2 -2
- package/dist/types/directive-types.d.ts +12 -0
- package/dist/visual-testing.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-025z2btp.js +0 -2
- package/dist/chunk-19fp0z9s.js +0 -2
- package/dist/chunk-23sv24cm.js +0 -2
- package/dist/chunk-2p68bkza.js +0 -2
- package/dist/chunk-5grrqaqs.js +0 -2
- package/dist/chunk-6jx4r94x.js +0 -2
- package/dist/chunk-6p6b01kp.js +0 -4
- package/dist/chunk-a1rt1fms.js +0 -2
- package/dist/chunk-ahpmjg3f.js +0 -64
- package/dist/chunk-akp89n3w.js +0 -2
- package/dist/chunk-bqhrryqs.js +0 -2
- package/dist/chunk-czvzaa42.js +0 -3
- package/dist/chunk-de2cfcf5.js +0 -2
- package/dist/chunk-exhbc57n.js +0 -2
- package/dist/chunk-fhhp6pmx.js +0 -2
- package/dist/chunk-fqsrft0a.js +0 -2
- package/dist/chunk-gqzccw30.js +0 -2
- package/dist/chunk-h47e1c03.js +0 -2
- package/dist/chunk-kbemcvp1.js +0 -2
- package/dist/chunk-ks4j8fjz.js +0 -2
- package/dist/chunk-pbct6nxk.js +0 -2
- package/dist/chunk-peerbcwj.js +0 -2
- package/dist/chunk-pt1w6vq2.js +0 -2
- package/dist/chunk-rgda0gwf.js +0 -2
- package/dist/chunk-rwa10jm4.js +0 -2
- package/dist/chunk-snsh9ye4.js +0 -2
- package/dist/chunk-td39mtts.js +0 -2
- package/dist/chunk-trncnwem.js +0 -2
- package/dist/chunk-vk2j3vvs.js +0 -2
- package/dist/chunk-vph6zpeq.js +0 -2
- package/dist/chunk-wa3ks5zv.js +0 -2
- package/dist/chunk-xer5kn26.js +0 -2
- package/dist/chunk-zx2krbqf.js +0 -2
package/dist/seo.js
CHANGED
|
@@ -1,267 +1,248 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describeValue,
|
|
3
|
+
evaluateDirectiveArgument,
|
|
4
|
+
isPlainRecord,
|
|
5
|
+
replaceDirectiveCalls,
|
|
6
|
+
reportDirectiveFailure,
|
|
7
|
+
splitTopLevelArgs,
|
|
8
|
+
warnDirective
|
|
9
|
+
} from "./directive-arguments.js";
|
|
1
10
|
import { ErrorCodes, inlineError } from "./error-handling.js";
|
|
2
11
|
import { mergeHeadConfigs } from "./head.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
tag += ` property="${escapeHtml(String(attrs.property))}"`;
|
|
46
|
-
if (attrs.httpEquiv)
|
|
47
|
-
tag += ` http-equiv="${escapeHtml(String(attrs.httpEquiv))}"`;
|
|
48
|
-
if (attrs.content)
|
|
49
|
-
tag += ` content="${escapeHtml(String(attrs.content))}"`;
|
|
50
|
-
tag += ">";
|
|
51
|
-
return tag;
|
|
52
|
-
} catch (error) {
|
|
53
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
54
|
-
return inlineError("MetaTag", errorMessage, ErrorCodes.EVALUATION_ERROR);
|
|
55
|
-
}
|
|
56
|
-
})();
|
|
57
|
-
output = output.substring(0, mtStart) + mtReplacement + output.substring(fullEnd);
|
|
58
|
-
metaTagPat.lastIndex = 0;
|
|
59
|
-
}
|
|
12
|
+
import { resolveMetaArguments } from "./meta-arguments.js";
|
|
13
|
+
const META_CALL = /(?<![\w$@])@meta\s*\(/g, META_TAG_CALL = /(?<![\w$@])@metaTag\s*\(/g, STRUCTURED_DATA_CALL = /(?<![\w$@])@structuredData\s*\(/g, SEO_CALL = /(?<![\w$@])@seo\s*\(/g;
|
|
14
|
+
function unterminated(label, filePath) {
|
|
15
|
+
return (call) => reportDirectiveFailure(label, call, "the call has no closing parenthesis", filePath, ErrorCodes.INVALID_DIRECTIVE_SYNTAX);
|
|
16
|
+
}
|
|
17
|
+
function renderMetaTag(tag) {
|
|
18
|
+
return "property" in tag ? `<meta property="${escapeHtml(tag.property)}" content="${escapeHtml(tag.content)}">` : `<meta name="${escapeHtml(tag.name)}" content="${escapeHtml(tag.content)}">`;
|
|
19
|
+
}
|
|
20
|
+
export function processMetaDirectives(template, context, filePath, _options) {
|
|
21
|
+
if (!template.includes("@meta"))
|
|
22
|
+
return template;
|
|
23
|
+
let output = replaceDirectiveCalls(template, META_CALL, (args, call) => {
|
|
24
|
+
const resolved = resolveMetaArguments(splitTopLevelArgs(args), context);
|
|
25
|
+
if (resolved.kind === "tag")
|
|
26
|
+
return renderMetaTag(resolved.tag);
|
|
27
|
+
if (resolved.kind === "empty")
|
|
28
|
+
return "";
|
|
29
|
+
return reportDirectiveFailure("Meta", call, resolved.message, filePath, resolved.code);
|
|
30
|
+
}, unterminated("Meta", filePath));
|
|
31
|
+
output = replaceDirectiveCalls(output, META_TAG_CALL, (args, call) => {
|
|
32
|
+
const result = evaluateDirectiveArgument(args, context);
|
|
33
|
+
if (!result.ok)
|
|
34
|
+
return reportDirectiveFailure("MetaTag", call, result.message, filePath, result.code);
|
|
35
|
+
if (result.value === void 0 || result.value === null)
|
|
36
|
+
return "";
|
|
37
|
+
if (!isPlainRecord(result.value))
|
|
38
|
+
return reportDirectiveFailure("MetaTag", call, `expected an object such as { name, content }, got ${describeValue(result.value)}`, filePath, ErrorCodes.TYPE_ERROR);
|
|
39
|
+
const attrs = result.value;
|
|
40
|
+
if (!attrs.name && !attrs.property && !attrs.httpEquiv)
|
|
41
|
+
return reportDirectiveFailure("MetaTag", call, "the tag needs a name, property or httpEquiv", filePath, ErrorCodes.INVALID_DIRECTIVE_SYNTAX);
|
|
42
|
+
if (attrs.content === void 0 || attrs.content === null || attrs.content === "" || attrs.content === !1)
|
|
43
|
+
return "";
|
|
44
|
+
let tag = "<meta";
|
|
45
|
+
if (attrs.name)
|
|
46
|
+
tag += ` name="${escapeHtml(attrs.name)}"`;
|
|
47
|
+
if (attrs.property)
|
|
48
|
+
tag += ` property="${escapeHtml(attrs.property)}"`;
|
|
49
|
+
if (attrs.httpEquiv)
|
|
50
|
+
tag += ` http-equiv="${escapeHtml(attrs.httpEquiv)}"`;
|
|
51
|
+
tag += ` content="${escapeHtml(attrs.content)}">`;
|
|
52
|
+
return tag;
|
|
53
|
+
}, unterminated("MetaTag", filePath));
|
|
60
54
|
return output;
|
|
61
55
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
function withSchemaContext(value) {
|
|
57
|
+
const fill = (item) => item["@context"] ? { ...item } : { ...item, "@context": "https://schema.org" };
|
|
58
|
+
if (isPlainRecord(value))
|
|
59
|
+
return fill(value);
|
|
60
|
+
if (Array.isArray(value) && value.length > 0 && value.every(isPlainRecord))
|
|
61
|
+
return value.map(fill);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function jsonLdScript(data) {
|
|
65
|
+
return `<script type="application/ld+json">${JSON.stringify(data).replace(/<\//g, "<\\/")}</script>`;
|
|
66
|
+
}
|
|
67
|
+
export function processStructuredData(template, context, filePath) {
|
|
68
|
+
if (!template.includes("@structuredData"))
|
|
69
|
+
return template;
|
|
70
|
+
return replaceDirectiveCalls(template, STRUCTURED_DATA_CALL, (args, call) => {
|
|
71
|
+
const result = evaluateDirectiveArgument(args, context);
|
|
72
|
+
if (!result.ok)
|
|
73
|
+
return reportDirectiveFailure("StructuredData", call, result.message, filePath, result.code);
|
|
74
|
+
if (result.value === void 0 || result.value === null)
|
|
75
|
+
return "";
|
|
76
|
+
const data = withSchemaContext(result.value);
|
|
77
|
+
if (!data)
|
|
78
|
+
return reportDirectiveFailure("StructuredData", call, `expected an object or an array of objects, got ${describeValue(result.value)}`, filePath, ErrorCodes.TYPE_ERROR);
|
|
79
|
+
try {
|
|
80
|
+
return jsonLdScript(data);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
return reportDirectiveFailure("StructuredData", call, `the data cannot be written as JSON: ${message}`, filePath, ErrorCodes.EVALUATION_ERROR);
|
|
78
84
|
}
|
|
79
|
-
|
|
80
|
-
break;
|
|
81
|
-
const dataObject = output.substring(openParen + 1, pos).trim(), fullEnd = pos + 1, replacement = (() => {
|
|
82
|
-
try {
|
|
83
|
-
const data = safeEvaluateObject(dataObject, context);
|
|
84
|
-
if (!data)
|
|
85
|
-
return "";
|
|
86
|
-
if (!data["@context"])
|
|
87
|
-
data["@context"] = "https://schema.org";
|
|
88
|
-
return `<script type="application/ld+json">${JSON.stringify(data).replace(/<\//g, "<\\/")}</script>`;
|
|
89
|
-
} catch (error) {
|
|
90
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
91
|
-
return inlineError("StructuredData", errorMessage, ErrorCodes.EVALUATION_ERROR);
|
|
92
|
-
}
|
|
93
|
-
})();
|
|
94
|
-
output = output.substring(0, sdStart) + replacement + output.substring(fullEnd);
|
|
95
|
-
structuredDataPattern.lastIndex = 0;
|
|
96
|
-
}
|
|
97
|
-
return output;
|
|
85
|
+
}, unterminated("StructuredData", filePath));
|
|
98
86
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
pos++;
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
if (c === "{")
|
|
130
|
-
depth++;
|
|
131
|
-
else if (c === "}")
|
|
132
|
-
depth--;
|
|
133
|
-
pos++;
|
|
87
|
+
const SEO_KEYS = new Set(["title", "description", "keywords", "robots", "canonical", "openGraph", "twitter", "structuredData"]), SEO_KEY_HINTS = {
|
|
88
|
+
image: "openGraph.image",
|
|
89
|
+
url: "canonical or openGraph.url",
|
|
90
|
+
type: "openGraph.type",
|
|
91
|
+
siteName: "openGraph.siteName",
|
|
92
|
+
locale: "openGraph.locale",
|
|
93
|
+
og: "openGraph",
|
|
94
|
+
author: "@meta('author', ...)"
|
|
95
|
+
};
|
|
96
|
+
export function processSeoDirective(template, context, filePath, _options) {
|
|
97
|
+
if (!template.includes("@seo"))
|
|
98
|
+
return template;
|
|
99
|
+
return replaceDirectiveCalls(template, SEO_CALL, (args, call) => {
|
|
100
|
+
if (!args.trim())
|
|
101
|
+
return reportDirectiveFailure("SEO", call, "expected an object: @seo({ title, description }) or @seo(seoVariable)", filePath, ErrorCodes.INVALID_DIRECTIVE_SYNTAX);
|
|
102
|
+
const result = evaluateDirectiveArgument(args, context);
|
|
103
|
+
if (!result.ok)
|
|
104
|
+
return reportDirectiveFailure("SEO", call, result.message, filePath, result.code);
|
|
105
|
+
if (result.value === void 0 || result.value === null)
|
|
106
|
+
return "";
|
|
107
|
+
if (!isPlainRecord(result.value))
|
|
108
|
+
return reportDirectiveFailure("SEO", call, `expected an object such as { title, description }, got ${describeValue(result.value)}`, filePath, ErrorCodes.TYPE_ERROR);
|
|
109
|
+
try {
|
|
110
|
+
return renderSeoTags(result.value, call, filePath);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
113
|
+
return reportDirectiveFailure("SEO", call, `Error processing @seo directive: ${message}`, filePath, ErrorCodes.EVALUATION_ERROR);
|
|
134
114
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
115
|
+
}, unterminated("SEO", filePath));
|
|
116
|
+
}
|
|
117
|
+
function nestedConfig(config, key, call, filePath) {
|
|
118
|
+
const value = config[key];
|
|
119
|
+
if (value === void 0 || value === null || value === !1)
|
|
120
|
+
return;
|
|
121
|
+
if (isPlainRecord(value))
|
|
122
|
+
return value;
|
|
123
|
+
warnDirective(call, `${key} must be an object, got ${describeValue(value)}; its tags were left out`, filePath);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
function renderSeoTags(config, call, filePath) {
|
|
127
|
+
const unknown = Object.keys(config).filter((key) => !SEO_KEYS.has(key));
|
|
128
|
+
if (unknown.length > 0) {
|
|
129
|
+
const described = unknown.map((key) => SEO_KEY_HINTS[key] ? `${key} (use ${SEO_KEY_HINTS[key]})` : key).join(", ");
|
|
130
|
+
warnDirective(call, `@seo does not read ${described}; ${unknown.length === 1 ? "it was" : "they were"} ignored`, filePath);
|
|
131
|
+
}
|
|
132
|
+
let metaTags = "";
|
|
133
|
+
if (config.title) {
|
|
134
|
+
metaTags += `<title>${escapeHtml(config.title)}</title>
|
|
148
135
|
`;
|
|
149
|
-
|
|
136
|
+
metaTags += `<meta name="title" content="${escapeHtml(config.title)}">
|
|
150
137
|
`;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
138
|
+
}
|
|
139
|
+
if (config.description)
|
|
140
|
+
metaTags += `<meta name="description" content="${escapeHtml(config.description)}">
|
|
154
141
|
`;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
142
|
+
if (config.keywords) {
|
|
143
|
+
const keywordsStr = Array.isArray(config.keywords) ? config.keywords.join(", ") : config.keywords;
|
|
144
|
+
metaTags += `<meta name="keywords" content="${escapeHtml(keywordsStr)}">
|
|
158
145
|
`;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
146
|
+
}
|
|
147
|
+
if (config.robots)
|
|
148
|
+
metaTags += `<meta name="robots" content="${escapeHtml(config.robots)}">
|
|
162
149
|
`;
|
|
163
|
-
|
|
164
|
-
|
|
150
|
+
if (config.canonical)
|
|
151
|
+
metaTags += `<link rel="canonical" href="${escapeHtml(config.canonical)}">
|
|
165
152
|
`;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
153
|
+
const og = nestedConfig(config, "openGraph", call, filePath);
|
|
154
|
+
if (og) {
|
|
155
|
+
metaTags += `<meta property="og:type" content="${escapeHtml(og.type || "website")}">
|
|
169
156
|
`;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
157
|
+
if (og.title || config.title) {
|
|
158
|
+
const ogTitle = og.title || config.title || "";
|
|
159
|
+
metaTags += `<meta property="og:title" content="${escapeHtml(ogTitle)}">
|
|
173
160
|
`;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
161
|
+
}
|
|
162
|
+
if (og.description || config.description) {
|
|
163
|
+
const ogDescription = og.description || config.description || "";
|
|
164
|
+
metaTags += `<meta property="og:description" content="${escapeHtml(ogDescription)}">
|
|
178
165
|
`;
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
166
|
+
}
|
|
167
|
+
if (og.url || config.canonical) {
|
|
168
|
+
const ogUrl = og.url || config.canonical || "";
|
|
169
|
+
metaTags += `<meta property="og:url" content="${escapeHtml(ogUrl)}">
|
|
183
170
|
`;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
171
|
+
}
|
|
172
|
+
if (og.image) {
|
|
173
|
+
metaTags += `<meta property="og:image" content="${escapeHtml(og.image)}">
|
|
187
174
|
`;
|
|
188
|
-
|
|
189
|
-
|
|
175
|
+
if (og.imageAlt)
|
|
176
|
+
metaTags += `<meta property="og:image:alt" content="${escapeHtml(og.imageAlt)}">
|
|
190
177
|
`;
|
|
191
|
-
|
|
192
|
-
|
|
178
|
+
if (og.imageWidth)
|
|
179
|
+
metaTags += `<meta property="og:image:width" content="${escapeHtml(String(og.imageWidth))}">
|
|
193
180
|
`;
|
|
194
|
-
|
|
195
|
-
|
|
181
|
+
if (og.imageHeight)
|
|
182
|
+
metaTags += `<meta property="og:image:height" content="${escapeHtml(String(og.imageHeight))}">
|
|
196
183
|
`;
|
|
197
|
-
|
|
198
|
-
|
|
184
|
+
if (og.imageType)
|
|
185
|
+
metaTags += `<meta property="og:image:type" content="${escapeHtml(og.imageType)}">
|
|
199
186
|
`;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
187
|
+
}
|
|
188
|
+
if (og.siteName)
|
|
189
|
+
metaTags += `<meta property="og:site_name" content="${escapeHtml(og.siteName)}">
|
|
203
190
|
`;
|
|
204
|
-
|
|
205
|
-
|
|
191
|
+
if (og.locale)
|
|
192
|
+
metaTags += `<meta property="og:locale" content="${escapeHtml(og.locale)}">
|
|
206
193
|
`;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
194
|
+
if (og.profile) {
|
|
195
|
+
const profile = [
|
|
196
|
+
["first_name", og.profile.firstName],
|
|
197
|
+
["last_name", og.profile.lastName],
|
|
198
|
+
["username", og.profile.username],
|
|
199
|
+
["gender", og.profile.gender]
|
|
200
|
+
];
|
|
201
|
+
for (const [key, value] of profile)
|
|
202
|
+
if (value)
|
|
203
|
+
metaTags += `<meta property="profile:${key}" content="${escapeHtml(value)}">
|
|
217
204
|
`;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const twitter = nestedConfig(config, "twitter", call, filePath);
|
|
208
|
+
if (twitter) {
|
|
209
|
+
metaTags += `<meta name="twitter:card" content="${escapeHtml(twitter.card || "summary_large_image")}">
|
|
223
210
|
`;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
211
|
+
if (twitter.title || config.title) {
|
|
212
|
+
const twitterTitle = twitter.title || config.title || "";
|
|
213
|
+
metaTags += `<meta name="twitter:title" content="${escapeHtml(twitterTitle)}">
|
|
227
214
|
`;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
215
|
+
}
|
|
216
|
+
if (twitter.description || config.description) {
|
|
217
|
+
const twitterDesc = twitter.description || config.description || "";
|
|
218
|
+
metaTags += `<meta name="twitter:description" content="${escapeHtml(twitterDesc)}">
|
|
232
219
|
`;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
220
|
+
}
|
|
221
|
+
if (twitter.image || og && og.image) {
|
|
222
|
+
const twitterImage = twitter.image || (og ? og.image : "") || "";
|
|
223
|
+
metaTags += `<meta name="twitter:image" content="${escapeHtml(twitterImage)}">
|
|
237
224
|
`;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
225
|
+
const twitterImageAlt = twitter.imageAlt || (!twitter.image && og ? og.imageAlt : void 0);
|
|
226
|
+
if (twitterImageAlt)
|
|
227
|
+
metaTags += `<meta name="twitter:image:alt" content="${escapeHtml(twitterImageAlt)}">
|
|
241
228
|
`;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
229
|
+
}
|
|
230
|
+
if (twitter.site)
|
|
231
|
+
metaTags += `<meta name="twitter:site" content="${escapeHtml(twitter.site)}">
|
|
245
232
|
`;
|
|
246
|
-
|
|
247
|
-
|
|
233
|
+
if (twitter.creator)
|
|
234
|
+
metaTags += `<meta name="twitter:creator" content="${escapeHtml(twitter.creator)}">
|
|
248
235
|
`;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
236
|
+
}
|
|
237
|
+
if (config.structuredData !== void 0 && config.structuredData !== null) {
|
|
238
|
+
const data = withSchemaContext(config.structuredData);
|
|
239
|
+
if (data)
|
|
240
|
+
metaTags += `${jsonLdScript(data)}
|
|
253
241
|
`;
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
} catch (error) {
|
|
257
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
258
|
-
return inlineError("SEO", `Error processing @seo directive: ${errorMessage}`, ErrorCodes.EVALUATION_ERROR);
|
|
259
|
-
}
|
|
260
|
-
})(seoConfig);
|
|
261
|
-
output = output.substring(0, seoMatch.index) + replacement + output.substring(fullEnd);
|
|
262
|
-
seoPat.lastIndex = seoMatch.index + replacement.length;
|
|
242
|
+
else
|
|
243
|
+
warnDirective(call, `structuredData must be an object or an array of objects, got ${describeValue(config.structuredData)}; it was left out`, filePath);
|
|
263
244
|
}
|
|
264
|
-
return
|
|
245
|
+
return metaTags.trim();
|
|
265
246
|
}
|
|
266
247
|
export function injectSeoTags(html, context, options) {
|
|
267
248
|
if (options.seo?.enabled === !1)
|
|
@@ -367,35 +348,20 @@ function readPageDescription(head) {
|
|
|
367
348
|
}
|
|
368
349
|
return "";
|
|
369
350
|
}
|
|
370
|
-
function escapeHtml(
|
|
371
|
-
return
|
|
372
|
-
}
|
|
373
|
-
const PROPERTY_NAMESPACES = ["og:", "article:", "book:", "profile:", "fb:", "music:", "video:"];
|
|
374
|
-
function unquoteParam(raw) {
|
|
375
|
-
const text = raw.trim(), first = text[0];
|
|
376
|
-
if ((first === "'" || first === '"' || first === "`") && text.length > 1 && text.at(-1) === first)
|
|
377
|
-
return { value: text.slice(1, -1), quoted: !0 };
|
|
378
|
-
return { value: text, quoted: !1 };
|
|
351
|
+
function escapeHtml(value) {
|
|
352
|
+
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
379
353
|
}
|
|
380
354
|
export const metaDirective = {
|
|
381
355
|
name: "meta",
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if (
|
|
388
|
-
const arg = unquoteParam(params[1]);
|
|
389
|
-
metaContent = arg.quoted ? arg.value : String(context?.[arg.value] ?? arg.value);
|
|
390
|
-
} else {
|
|
391
|
-
const segment = name.includes(":") ? name.slice(name.indexOf(":") + 1) : name, openGraph = context?.openGraph;
|
|
392
|
-
metaContent = String(context?.[segment] ?? openGraph?.[segment] ?? "");
|
|
393
|
-
}
|
|
394
|
-
if (!metaContent)
|
|
356
|
+
rawParams: !0,
|
|
357
|
+
handler: (_content, params, context, filePath) => {
|
|
358
|
+
const resolved = resolveMetaArguments(params, context ?? {});
|
|
359
|
+
if (resolved.kind === "error")
|
|
360
|
+
return reportDirectiveFailure("Meta", `@meta(${params.join(", ")})`, resolved.message, filePath, resolved.code);
|
|
361
|
+
if (resolved.kind === "empty")
|
|
395
362
|
return "";
|
|
396
|
-
const tag = PROPERTY_NAMESPACES.some((prefix) => name.startsWith(prefix)) ? { property: name, content: metaContent } : { name, content: metaContent };
|
|
397
363
|
if (context)
|
|
398
|
-
context.__stx_runtime_head = mergeHeadConfigs(context.__stx_runtime_head ?? {}, { meta: [tag] });
|
|
364
|
+
context.__stx_runtime_head = mergeHeadConfigs(context.__stx_runtime_head ?? {}, { meta: [resolved.tag] });
|
|
399
365
|
return "";
|
|
400
366
|
},
|
|
401
367
|
hasEndTag: !1
|
|
@@ -410,7 +376,7 @@ export const metaDirective = {
|
|
|
410
376
|
data["@context"] = "https://schema.org";
|
|
411
377
|
if (!data["@type"])
|
|
412
378
|
return inlineError("StructuredData", "structuredData requires @type property", ErrorCodes.INVALID_DIRECTIVE_SYNTAX);
|
|
413
|
-
return
|
|
379
|
+
return jsonLdScript(data);
|
|
414
380
|
} catch (error) {
|
|
415
381
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
416
382
|
return inlineError("StructuredData", errorMessage, ErrorCodes.EVALUATION_ERROR);
|
package/dist/ssg.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{Bk as Fq,wk as Uq,xk as Iq}from"./chunk-
|
|
2
|
+
import{Bk as Fq,wk as Uq,xk as Iq}from"./chunk-wnmegbw0.js";import{Ck as Eq,Dk as Tq,Ek as Dq}from"./chunk-c0n802j1.js";import{Zk as _q,al as zq,bl as Aq}from"./chunk-57dxdvjh.js";import"./chunk-2853ye06.js";import"./chunk-fvsefztj.js";import{Jp as P,Sm as Oq,io as l,lo as Hq,rr as n}from"./chunk-xgw269cf.js";import"./chunk-aqxwwq6w.js";import"./chunk-t00ga194.js";import"./chunk-hrdd26r4.js";import"./chunk-7r79j1hs.js";import"./chunk-ay336sqb.js";import{ht as Xq}from"./chunk-6xs80tka.js";import{mt as d}from"./chunk-vaggjvsm.js";import"./chunk-q9ckfwhh.js";import"./chunk-kbah2k8e.js";import"./chunk-k3dtvay1.js";import{Tt as Bq}from"./chunk-eh3meyd3.js";import"./chunk-rzg9pars.js";import"./chunk-1qtd4ex2.js";import"./chunk-ec18ftcg.js";import"./chunk-fbmjw0bh.js";import"./chunk-53sjbp3z.js";import{lw as Yq,mw as Vq,nw as jq,ow as Gq,pw as Lq,qw as Nq}from"./chunk-kgbz86sa.js";import"./chunk-s60eccqk.js";import{Hw as y}from"./chunk-0s3ry262.js";import O from"fs";import j from"path";import{createHash as xq}from"crypto";function yq(q){try{return new Bun.Transpiler({loader:"js",minifyWhitespace:!0}).transformSync(q).replace(/\}(var |let |const |function )/g,"};$1").trim()}catch{return q}}var Pq=/<script\s+type="stx\/island"\s+data-stx-island="([^"]+)"([^>]*)>([\s\S]*?)<\/script>/g;function Cq(q){return Bun.hash(q).toString(16)}function Qq(q,Z={}){if(!q.includes('type="stx/island"'))return{html:q,chunks:[]};let $=new Map,Q=q.replace(Pq,(J,W,z,A)=>{let G=A.trim();if(!G)return J;if(/\bdata-stx-src=/.test(z))return J;if(Z.minify)G=yq(G);let X=Cq(G);if(!$.has(X))$.set(X,G);let B=Z.integrity?` data-stx-integrity="sha384-${xq("sha384").update(G).digest("base64")}"`:"";return`<script type="stx/island" data-stx-island="${W}" data-stx-src="/_stx/islands/${X}.js"${B}${z}></script>`}),K=Array.from($,([J,W])=>({hash:J,code:W}));return{html:Q,chunks:K}}var gq=new Set(["visible","idle"]);function Zq(q){if(!q.includes("data-stx-src="))return q;let Z=new Map,$=/data-stx-scope="([^"]+)"[^>]*?stx-hydrate="([^"]+)"/g,Q;while((Q=$.exec(q))!==null)Z.set(Q[1],Q[2]);let K=new Set,J=/data-stx-island="([^"]+)"[^>]*?data-stx-src="([^"]+)"/g,W;while((W=J.exec(q))!==null)if(gq.has(Z.get(W[1])||""))K.add(W[2]);let z=q.lastIndexOf("</head>");if(K.size===0||z===-1)return q;let A=Array.from(K).filter((G)=>!q.includes(`rel="prefetch" href="${G}"`)).map((G)=>`<link rel="prefetch" href="${G}" as="script">`).join("");if(!A)return q;return q.slice(0,z)+A+q.slice(z)}var fq=["STX_SITE_URL","SITE_URL","URL","VERCEL_URL","CF_PAGES_URL"];function h(q){let Z=q.trim();if(!Z)return null;let $=/^https?:\/\//i.test(Z)?Z:`https://${Z}`;try{return new URL($).origin+new URL($).pathname.replace(/\/$/,"")}catch{return null}}function mq(q){for(let Z of fq){let $=q[Z];if(!$)continue;let Q=h($);if(Q)return{url:Q,source:"env",via:Z}}return null}function $q(q){if(!q||typeof q!=="object")return null;let Z=q,$=Z.site?.url??Z.url??Z.app?.url;return typeof $==="string"?h($):null}async function dq(q){let{existsSync:Z}=await import("fs"),$=await import("path");for(let Q of["site.config.ts","site.config.js",".config/site.config.ts"]){let K=$.resolve(q,Q);if(!Z(K))continue;try{let J=await import(K),W=$q(J.default??J);if(W)return W}catch{}}return null}async function Kq(q={}){let Z=q.cwd??process.cwd(),$=q.env??process.env;if(q.explicit){let W=h(q.explicit);if(W)return{url:W,source:"option"}}let Q=$q(q.stxConfig);if(Q)return{url:Q,source:"stx.config",via:"site.url"};let K=await dq(Z);if(K)return{url:K,source:"site.config",via:"url"};let J=mq($);if(J)return J;return{url:"http://localhost",source:"fallback"}}function Wq(){return["No site URL configured \u2014 sitemap.xml and robots.txt will point at http://localhost."," Set one in stx.config.ts (site: { url: 'https://example.com' }), in site.config.ts,"," via --domain, or with SITE_URL in the build environment."].join(`
|
|
3
3
|
`)}class wq{cacheDir;cache=new Map;loaded=!1;salt;constructor(q,Z=""){this.cacheDir=q,this.salt=Z}async load(){if(this.loaded)return;let q=j.join(this.cacheDir,"build-cache.json");if(await Bun.file(q).exists())try{let Z=JSON.parse(await Bun.file(q).text());for(let[$,Q]of Object.entries(Z))this.cache.set($,Q)}catch{}this.loaded=!0}async save(){await O.promises.mkdir(this.cacheDir,{recursive:!0});let q=j.join(this.cacheDir,"build-cache.json"),Z={};for(let[$,Q]of this.cache)Z[$]=Q;await Bun.write(q,JSON.stringify(Z))}getHash(q,Z){let $=O.statSync(q),Q=`${this.salt}|${q}:${$.mtimeMs}`;for(let J of Z)if(O.existsSync(J)){let W=O.statSync(J);Q+=`:${J}:${W.mtimeMs}`}let K=0;for(let J=0;J<Q.length;J++){let W=Q.charCodeAt(J);K=(K<<5)-K+W,K=K&K}return Math.abs(K).toString(36)}get(q,Z){let $=this.cache.get(q);if(!$)return null;let Q=this.getHash(Z,$.dependencies??[]);if($.hash!==Q)return this.cache.delete(q),null;return $.html}set(q,Z,$,Q){let K=this.getHash(Z,$);this.cache.set(q,{hash:K,html:Q,generatedAt:Date.now(),dependencies:$})}}class Rq{cacheDir;constructor(q){this.cacheDir=q}getFilePath(q){let Z=q.replace(/[^a-zA-Z0-9]/g,"_")+".json";return j.join(this.cacheDir,"isr",Z)}async get(q){let Z=this.getFilePath(q);if(!await Bun.file(Z).exists())return null;try{return JSON.parse(await Bun.file(Z).text())}catch{return null}}async set(q,Z){let $=this.getFilePath(q);await O.promises.mkdir(j.dirname($),{recursive:!0}),await Bun.write($,JSON.stringify(Z))}async invalidate(q){let Z=this.getFilePath(q);if(await Bun.file(Z).exists())await O.promises.unlink(Z)}async invalidatePattern(q){let Z=j.join(this.cacheDir,"isr");if(!O.existsSync(Z))return;let $=await O.promises.readdir(Z);for(let Q of $){let K=Q.replace(/_/g,"/").replace(".json","");if(q.test(K))await O.promises.unlink(j.join(Z,Q))}}async needsRevalidation(q){let Z=await this.get(q);if(!Z)return!0;return Date.now()>Z.revalidateAfter}}async function pq(q){try{let $=(await Bun.file(q).text()).match(/<script\s+server\b[^>]*>([\s\S]*?)<\/script>/i);if(!$)return null;let Q=$[1];if(!Q.includes("getStaticPaths"))return null;let K=Q.match(/(?:export\s+)?(?:async\s+)?function\s+getStaticPaths\s*\([^)]*\)\s*\{([\s\S]*?)\n[\t ]*\}/);if(!K)return null;return await Function(`
|
|
4
4
|
return (async function getStaticPaths() {
|
|
5
5
|
${K[1]}
|
|
@@ -41,7 +41,7 @@ ${q.map((Q)=>{let K=new URL(Q.loc,Z).href,J=` <url>
|
|
|
41
41
|
${$.join(`
|
|
42
42
|
`)}
|
|
43
43
|
</channel>
|
|
44
|
-
</rss>`}async function aq(q={}){let Z=Date.now();Aq();let $=await n(process.cwd()),Q=$.build||{},K=await Kq({explicit:q.domain||Q.domain,stxConfig:$});if(K.source==="fallback"&&(q.sitemap??Q.sitemap??!0))console.warn(Wq());let J={router:q.router??$?.router??{},pagesDir:q.pagesDir||Q.pagesDir||"pages",outputDir:q.outputDir||Q.outputDir||"dist",baseUrl:q.baseUrl||Q.baseUrl||"/",domain:K.url,revalidate:q.revalidate??Q.revalidate??!1,sitemap:q.sitemap??Q.sitemap??!0,sitemapExclude:q.sitemapExclude||Q.sitemapExclude||[],robots:q.robots??Q.robots??!0,rss:q.rss??Q.rss??!1,concurrency:q.concurrency||Q.concurrency||10,cache:q.cache??Q.cache??!0,cacheDir:q.cacheDir||Q.cacheDir||d(process.cwd(),"ssg-cache"),contentLoaders:q.contentLoaders||[],hooks:q.hooks||{},minify:q.minify??Q.minify??!0,generate404:q.generate404??Q.generate404??!0,publicDir:q.publicDir||Q.publicDir||"public",trailingSlash:q.trailingSlash??Q.trailingSlash??!1,cleanOutput:q.cleanOutput??Q.cleanOutput??!0,cacheSalt:q.cacheSalt??"",partialsDir:q.partialsDir||$?.partialsDir||"",componentsDir:q.componentsDir||$?.componentsDir||"",failOnIncludeError:q.failOnIncludeError??!0,chunkIslands:q.chunkIslands===!0,prefetchIslands:q.prefetchIslands===!0,integrityIslands:q.integrityIslands===!0},W={totalPages:0,successCount:0,failedCount:0,cachedCount:0,buildTime:0,pages:[],errors:[]},z=new Set,A=0,G={},X={};await J.hooks.onBuildStart?.();try{if(J.cleanOutput&&O.existsSync(J.outputDir))await O.promises.rm(J.outputDir,{recursive:!0});await O.promises.mkdir(J.outputDir,{recursive:!0});let L=J.cacheSalt;if(!L){let{resolveUserCssConfig:Y,fingerprintConfig:N}=await import("./chunk-
|
|
44
|
+
</rss>`}async function aq(q={}){let Z=Date.now();Aq();let $=await n(process.cwd()),Q=$.build||{},K=await Kq({explicit:q.domain||Q.domain,stxConfig:$});if(K.source==="fallback"&&(q.sitemap??Q.sitemap??!0))console.warn(Wq());let J={router:q.router??$?.router??{},pagesDir:q.pagesDir||Q.pagesDir||"pages",outputDir:q.outputDir||Q.outputDir||"dist",baseUrl:q.baseUrl||Q.baseUrl||"/",domain:K.url,revalidate:q.revalidate??Q.revalidate??!1,sitemap:q.sitemap??Q.sitemap??!0,sitemapExclude:q.sitemapExclude||Q.sitemapExclude||[],robots:q.robots??Q.robots??!0,rss:q.rss??Q.rss??!1,concurrency:q.concurrency||Q.concurrency||10,cache:q.cache??Q.cache??!0,cacheDir:q.cacheDir||Q.cacheDir||d(process.cwd(),"ssg-cache"),contentLoaders:q.contentLoaders||[],hooks:q.hooks||{},minify:q.minify??Q.minify??!0,generate404:q.generate404??Q.generate404??!0,publicDir:q.publicDir||Q.publicDir||"public",trailingSlash:q.trailingSlash??Q.trailingSlash??!1,cleanOutput:q.cleanOutput??Q.cleanOutput??!0,cacheSalt:q.cacheSalt??"",partialsDir:q.partialsDir||$?.partialsDir||"",componentsDir:q.componentsDir||$?.componentsDir||"",failOnIncludeError:q.failOnIncludeError??!0,chunkIslands:q.chunkIslands===!0,prefetchIslands:q.prefetchIslands===!0,integrityIslands:q.integrityIslands===!0},W={totalPages:0,successCount:0,failedCount:0,cachedCount:0,buildTime:0,pages:[],errors:[]},z=new Set,A=0,G={},X={};await J.hooks.onBuildStart?.();try{if(J.cleanOutput&&O.existsSync(J.outputDir))await O.promises.rm(J.outputDir,{recursive:!0});await O.promises.mkdir(J.outputDir,{recursive:!0});let L=J.cacheSalt;if(!L){let{resolveUserCssConfig:Y,fingerprintConfig:N}=await import("./chunk-pwhf5kte.js");try{L=N(await Y(process.cwd()))}catch{}}let{prepareImageDelivery:_}=await import("./chunk-4pg6wbt6.js"),F=await _(J.publicDir,J.outputDir);if(F.count>0)console.log(`Optimized ${F.count} image(s) for responsive delivery`),L=[L,F.fingerprint].filter(Boolean).join(":");let C=new wq(J.cacheDir,L);if(J.cache)await C.load();try{let{generateCss:Y}=await import("./chunk-pwhf5kte.js");await Y('<div class="bg-black"></div>')}catch{}Yq();let kq=$?.routeMiddleware?.dir||"middleware";await jq(process.cwd(),kq);let p=Vq();if(p.length>0)console.log(`Loaded ${p.length} middleware: ${p.join(", ")}`);let bq=$?.routeMiddleware?.global||[];Fq($?.layoutsDir,d(process.cwd()));let i=l(".",{pagesDir:J.pagesDir,pagesDirs:$?._layerPageDirs});console.log(`Found ${i.length} routes`);let g=[];for(let Y of i){let N=await uq(Y);for(let H of N)g.push({route:Y,url:H.url,params:H.params,props:H.props,revalidate:H.revalidate??J.revalidate})}W.totalPages=g.length,console.log(`Generating ${W.totalPages} pages...`);let b=[],s=[];for(let Y=0;Y<g.length;Y+=J.concurrency)s.push(g.slice(Y,Y+J.concurrency));for(let Y of s)await Promise.all(Y.map(async(N)=>{let{route:H,url:V,params:S,props:Sq,revalidate:a}=N;try{await J.hooks.onPageStart?.(V);let w=await Bun.file(H.filePath).text(),R=JJ(w),vq=R?.middleware?Array.isArray(R.middleware)?R.middleware:[R.middleware]:[],t=[...bq,...vq];if(t.length>0){let D=Gq(V,S,R||{}),M=Lq(D,null,void 0,{isServer:!0}),E=await Nq(t,M);if(E.redirect){let U=typeof E.redirect==="string"?E.redirect:E.redirect.path||E.redirect,x=QJ(String(U),V),k=ZJ(V,J);await O.promises.mkdir(j.dirname(k),{recursive:!0}),await Bun.write(k,x),W.successCount++,W.pages.push({route:V,outputPath:k,size:Buffer.byteLength(x),cached:!1}),b.push({loc:V,lastmod:new Date().toISOString()}),console.log(` \u21B3 ${V} \u2192 redirect to ${U}`);return}if(E.abort){let U=typeof E.abort==="string"?E.abort:E.abort?.error?.message||"aborted";console.warn(` \u21B3 ${V} \u2014 middleware aborted: ${U}`);return}}let e=w.match(/definePageMeta\s*\(\s*\{[\s\S]*?validate\s*:\s*((?:\([^)]*\)|[^,}])*(?:\{[\s\S]*?\})?)/m);if(e)try{if(!await Function("route",`
|
|
45
45
|
const validate = ${e[1]};
|
|
46
46
|
return validate(route);
|
|
47
47
|
`)({params:S})){console.warn(`Validation failed for ${V}, skipping...`);return}}catch{}let I=null,qq=!1;if(J.cache){if(I=C.get(V,H.filePath),I)qq=!0,W.cachedCount++}if(!I){let D=await Mq(H,S,Sq,J,$);if(I=D.html,J.failOnIncludeError&&D.includeFailures.length>0)throw Error(`${D.includeFailures.length} include(s) failed to resolve, so this page would have shipped with an error banner where the markup should be:
|
|
@@ -292,6 +292,18 @@ export interface CustomDirective {
|
|
|
292
292
|
handler: CustomDirectiveHandler;
|
|
293
293
|
/** Whether the directive has a closing tag (e.g., @directive...@enddirective) */
|
|
294
294
|
hasEndTag?: boolean;
|
|
295
|
+
/**
|
|
296
|
+
* Pass each argument exactly as written, quotes included, split only at
|
|
297
|
+
* top-level commas, instead of with its quotes stripped.
|
|
298
|
+
*
|
|
299
|
+
* Stripping quotes erases the difference between `'title'` (the word) and
|
|
300
|
+
* `title` (a variable), and splitting at every comma breaks `fn(a, b)` apart,
|
|
301
|
+
* so a directive that evaluates its arguments needs this. The call is also
|
|
302
|
+
* matched by balance rather than a pattern, so `'Smile :)'` and nested calls
|
|
303
|
+
* stay inside it. Parse a literal with `parseStringLiteral` and evaluate the
|
|
304
|
+
* rest with `evaluateDirectiveArgument` (directive-arguments.ts).
|
|
305
|
+
*/
|
|
306
|
+
rawParams?: boolean;
|
|
295
307
|
/** Optional description for documentation */
|
|
296
308
|
description?: string;
|
|
297
309
|
}
|