@constela/start 1.6.3 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LKFIMB3Q.js → chunk-7OAUINHU.js} +1 -1
- package/dist/{chunk-PG3Y4EJN.js → chunk-IGSM7NWL.js} +50 -1
- package/dist/cli/index.js +2 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2 -2
- package/dist/runtime/entry-server.d.ts +2 -0
- package/dist/runtime/entry-server.js +1 -1
- package/package.json +6 -6
|
@@ -88,6 +88,13 @@ ${routeDeclaration ? "\n" + routeDeclaration : ""}${widgetDeclarations ? "\n" +
|
|
|
88
88
|
hydrateApp(${hydrateOptions});${widgetMounting}`;
|
|
89
89
|
}
|
|
90
90
|
function wrapHtml(content, hydrationScript, head, options) {
|
|
91
|
+
let langAttr = "";
|
|
92
|
+
if (options?.lang) {
|
|
93
|
+
if (!/^[a-zA-Z]{2,3}(-[a-zA-Z]{4})?(-[a-zA-Z]{2}|-[0-9]{3})?$/.test(options.lang)) {
|
|
94
|
+
throw new Error(`Invalid lang: ${options.lang}. Expected BCP 47 language tag (e.g., 'en', 'ja', 'en-US', 'zh-Hans-CN').`);
|
|
95
|
+
}
|
|
96
|
+
langAttr = ` lang="${options.lang}"`;
|
|
97
|
+
}
|
|
91
98
|
const htmlClass = options?.defaultTheme === "dark" || options?.theme === "dark" ? ' class="dark"' : "";
|
|
92
99
|
let processedScript = hydrationScript;
|
|
93
100
|
let importMapScript = "";
|
|
@@ -149,7 +156,7 @@ ${importMapJson}
|
|
|
149
156
|
`;
|
|
150
157
|
}
|
|
151
158
|
return `<!DOCTYPE html>
|
|
152
|
-
<html${htmlClass}>
|
|
159
|
+
<html${langAttr}${htmlClass}>
|
|
153
160
|
<head>
|
|
154
161
|
<meta charset="utf-8">
|
|
155
162
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
@@ -190,6 +197,30 @@ function evaluateMetaExpression(expr, ctx) {
|
|
|
190
197
|
return "";
|
|
191
198
|
}
|
|
192
199
|
}
|
|
200
|
+
function evaluateJsonLdExpression(expr, ctx) {
|
|
201
|
+
switch (expr.expr) {
|
|
202
|
+
case "lit":
|
|
203
|
+
return expr.value;
|
|
204
|
+
case "route":
|
|
205
|
+
if (expr.source === "param") {
|
|
206
|
+
return ctx.params[expr.name] ?? "";
|
|
207
|
+
} else if (expr.source === "query") {
|
|
208
|
+
return ctx.query[expr.name] ?? "";
|
|
209
|
+
} else if (expr.source === "path") {
|
|
210
|
+
return ctx.path;
|
|
211
|
+
}
|
|
212
|
+
return "";
|
|
213
|
+
case "bin":
|
|
214
|
+
if (expr.op === "+") {
|
|
215
|
+
return String(evaluateJsonLdExpression(expr.left, ctx)) + String(evaluateJsonLdExpression(expr.right, ctx));
|
|
216
|
+
}
|
|
217
|
+
return "";
|
|
218
|
+
case "concat":
|
|
219
|
+
return expr.items.map((item) => String(evaluateJsonLdExpression(item, ctx))).join("");
|
|
220
|
+
default:
|
|
221
|
+
return "";
|
|
222
|
+
}
|
|
223
|
+
}
|
|
193
224
|
function generateMetaTags(route, ctx) {
|
|
194
225
|
if (!route) {
|
|
195
226
|
return "";
|
|
@@ -215,6 +246,24 @@ function generateMetaTags(route, ctx) {
|
|
|
215
246
|
}
|
|
216
247
|
}
|
|
217
248
|
}
|
|
249
|
+
if (route.canonical) {
|
|
250
|
+
const canonicalValue = evaluateMetaExpression(route.canonical, ctx);
|
|
251
|
+
if (canonicalValue) {
|
|
252
|
+
tags.push(`<link rel="canonical" href="${escapeHtmlForMeta(canonicalValue)}">`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (route.jsonLd) {
|
|
256
|
+
const jsonLdObject = {
|
|
257
|
+
"@context": "https://schema.org",
|
|
258
|
+
"@type": route.jsonLd.type
|
|
259
|
+
};
|
|
260
|
+
for (const [key, expr] of Object.entries(route.jsonLd.properties)) {
|
|
261
|
+
const value = evaluateJsonLdExpression(expr, ctx);
|
|
262
|
+
jsonLdObject[key] = value;
|
|
263
|
+
}
|
|
264
|
+
const jsonString = escapeJsonForScript(JSON.stringify(jsonLdObject));
|
|
265
|
+
tags.push(`<script type="application/ld+json">${jsonString}</script>`);
|
|
266
|
+
}
|
|
218
267
|
return tags.join("\n");
|
|
219
268
|
}
|
|
220
269
|
|
package/dist/cli/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -540,6 +540,11 @@ interface ConstelaConfigFile {
|
|
|
540
540
|
port?: number;
|
|
541
541
|
host?: string;
|
|
542
542
|
};
|
|
543
|
+
/** SEO settings */
|
|
544
|
+
seo?: {
|
|
545
|
+
/** HTML lang attribute (e.g., 'ja', 'en', 'zh-CN') */
|
|
546
|
+
lang?: string;
|
|
547
|
+
};
|
|
543
548
|
}
|
|
544
549
|
interface CLIOptions {
|
|
545
550
|
css?: string | undefined;
|
package/dist/index.js
CHANGED
|
@@ -28,14 +28,14 @@ import {
|
|
|
28
28
|
transformCsv,
|
|
29
29
|
transformMdx,
|
|
30
30
|
transformYaml
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-7OAUINHU.js";
|
|
32
32
|
import {
|
|
33
33
|
evaluateMetaExpression,
|
|
34
34
|
generateHydrationScript,
|
|
35
35
|
generateMetaTags,
|
|
36
36
|
renderPage,
|
|
37
37
|
wrapHtml
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-IGSM7NWL.js";
|
|
39
39
|
|
|
40
40
|
// src/build/ssg.ts
|
|
41
41
|
import { mkdir, writeFile } from "fs/promises";
|
|
@@ -13,6 +13,8 @@ interface SSRContext {
|
|
|
13
13
|
}
|
|
14
14
|
interface WrapHtmlOptions {
|
|
15
15
|
theme?: 'dark' | 'light';
|
|
16
|
+
/** HTML lang attribute for SEO */
|
|
17
|
+
lang?: string;
|
|
16
18
|
/** Import map entries for resolving bare module specifiers */
|
|
17
19
|
importMap?: Record<string, string>;
|
|
18
20
|
/** Path to bundled runtime for production builds. When provided, replaces @constela/runtime imports and excludes importmap. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constela/start",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Meta-framework for Constela applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"@tailwindcss/postcss": "^4.0.0",
|
|
45
45
|
"tailwindcss": "^4.0.0",
|
|
46
46
|
"ws": "^8.18.0",
|
|
47
|
-
"@constela/compiler": "0.
|
|
48
|
-
"@constela/
|
|
49
|
-
"@constela/
|
|
50
|
-
"@constela/
|
|
51
|
-
"@constela/
|
|
47
|
+
"@constela/compiler": "0.12.0",
|
|
48
|
+
"@constela/core": "0.13.0",
|
|
49
|
+
"@constela/router": "15.0.0",
|
|
50
|
+
"@constela/runtime": "0.16.5",
|
|
51
|
+
"@constela/server": "9.0.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/ws": "^8.5.0",
|