@zenithbuild/cli 0.7.3 → 0.7.5
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/README.md +18 -13
- package/dist/adapters/adapter-netlify.d.ts +1 -1
- package/dist/adapters/adapter-netlify.js +56 -13
- package/dist/adapters/adapter-node.js +8 -0
- package/dist/adapters/adapter-static-export.d.ts +5 -0
- package/dist/adapters/adapter-static-export.js +115 -0
- package/dist/adapters/adapter-types.d.ts +3 -1
- package/dist/adapters/adapter-types.js +5 -2
- package/dist/adapters/adapter-vercel.d.ts +1 -1
- package/dist/adapters/adapter-vercel.js +70 -13
- package/dist/adapters/copy-hosted-page-runtime.d.ts +1 -0
- package/dist/adapters/copy-hosted-page-runtime.js +49 -0
- package/dist/adapters/resolve-adapter.js +4 -0
- package/dist/adapters/route-rules.d.ts +5 -0
- package/dist/adapters/route-rules.js +9 -0
- package/dist/adapters/validate-hosted-resource-routes.d.ts +1 -0
- package/dist/adapters/validate-hosted-resource-routes.js +13 -0
- package/dist/auth/route-auth.d.ts +6 -0
- package/dist/auth/route-auth.js +236 -0
- package/dist/build/compiler-runtime.d.ts +10 -9
- package/dist/build/compiler-runtime.js +58 -2
- package/dist/build/compiler-signal-expression.d.ts +1 -0
- package/dist/build/compiler-signal-expression.js +155 -0
- package/dist/build/expression-rewrites.d.ts +1 -6
- package/dist/build/expression-rewrites.js +61 -65
- package/dist/build/page-component-loop.d.ts +3 -13
- package/dist/build/page-component-loop.js +21 -46
- package/dist/build/page-ir-normalization.d.ts +0 -8
- package/dist/build/page-ir-normalization.js +13 -234
- package/dist/build/page-loop-state.d.ts +6 -9
- package/dist/build/page-loop-state.js +9 -8
- package/dist/build/page-loop.js +27 -22
- package/dist/build/scoped-identifier-rewrite.d.ts +37 -44
- package/dist/build/scoped-identifier-rewrite.js +28 -128
- package/dist/build/server-script.d.ts +3 -1
- package/dist/build/server-script.js +35 -5
- package/dist/build-output-manifest.d.ts +3 -2
- package/dist/build-output-manifest.js +3 -0
- package/dist/build.js +32 -18
- package/dist/component-instance-ir.js +158 -52
- package/dist/dev-build-session.js +20 -6
- package/dist/dev-server.js +152 -55
- package/dist/download-result.d.ts +14 -0
- package/dist/download-result.js +148 -0
- package/dist/framework-components/Image.zen +1 -1
- package/dist/images/materialization-plan.d.ts +1 -0
- package/dist/images/materialization-plan.js +6 -0
- package/dist/images/materialize.d.ts +5 -3
- package/dist/images/materialize.js +24 -109
- package/dist/images/router-manifest.d.ts +1 -0
- package/dist/images/router-manifest.js +49 -0
- package/dist/images/service.d.ts +13 -1
- package/dist/images/service.js +45 -15
- package/dist/index.js +8 -2
- package/dist/manifest.d.ts +15 -1
- package/dist/manifest.js +27 -7
- package/dist/preview.d.ts +13 -4
- package/dist/preview.js +261 -101
- package/dist/request-body.d.ts +1 -0
- package/dist/request-body.js +7 -0
- package/dist/request-origin.d.ts +2 -0
- package/dist/request-origin.js +45 -0
- package/dist/resource-manifest.d.ts +16 -0
- package/dist/resource-manifest.js +53 -0
- package/dist/resource-response.d.ts +34 -0
- package/dist/resource-response.js +71 -0
- package/dist/resource-route-module.d.ts +15 -0
- package/dist/resource-route-module.js +129 -0
- package/dist/route-check-support.d.ts +1 -0
- package/dist/route-check-support.js +4 -0
- package/dist/server-contract.d.ts +29 -6
- package/dist/server-contract.js +304 -42
- package/dist/server-error.d.ts +4 -0
- package/dist/server-error.js +36 -0
- package/dist/server-output.d.ts +4 -1
- package/dist/server-output.js +71 -10
- package/dist/server-runtime/node-server.js +67 -31
- package/dist/server-runtime/route-render.d.ts +27 -3
- package/dist/server-runtime/route-render.js +94 -53
- package/dist/server-script-composition.d.ts +13 -5
- package/dist/server-script-composition.js +29 -11
- package/dist/static-export-paths.d.ts +3 -0
- package/dist/static-export-paths.js +160 -0
- package/package.json +6 -3
|
@@ -1,116 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
* @param {string} value
|
|
4
|
-
* @returns {string | null}
|
|
5
|
-
*/
|
|
6
|
-
function deriveScopedIdentifierAlias(value) {
|
|
7
|
-
const ident = String(value || '').trim();
|
|
8
|
-
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(ident)) {
|
|
9
|
-
return null;
|
|
10
|
-
}
|
|
11
|
-
const parts = ident.split('_').filter(Boolean);
|
|
12
|
-
const candidate = parts.length > 1 ? parts[parts.length - 1] : ident;
|
|
13
|
-
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(candidate) ? candidate : ident;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* @param {Map<string, string>} map
|
|
17
|
-
* @param {Set<string>} ambiguous
|
|
18
|
-
* @param {string | null} raw
|
|
19
|
-
* @param {string | null} rewritten
|
|
20
|
-
*/
|
|
21
|
-
function recordScopedIdentifierRewrite(map, ambiguous, raw, rewritten) {
|
|
22
|
-
if (typeof raw !== 'string' || raw.length === 0 || typeof rewritten !== 'string' || rewritten.length === 0) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const existing = map.get(raw);
|
|
26
|
-
if (existing && existing !== rewritten) {
|
|
27
|
-
map.delete(raw);
|
|
28
|
-
ambiguous.add(raw);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (!ambiguous.has(raw)) {
|
|
32
|
-
map.set(raw, rewritten);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* @param {object | null | undefined} ir
|
|
37
|
-
* @returns {{ map: Map<string, string>, ambiguous: Set<string> }}
|
|
38
|
-
*/
|
|
39
|
-
export function buildScopedIdentifierRewrite(ir) {
|
|
40
|
-
const out = { map: new Map(), ambiguous: new Set() };
|
|
41
|
-
if (!ir || typeof ir !== 'object') {
|
|
42
|
-
return out;
|
|
43
|
-
}
|
|
44
|
-
const stateBindings = Array.isArray(ir?.hoisted?.state) ? ir.hoisted.state : [];
|
|
45
|
-
for (const stateEntry of stateBindings) {
|
|
46
|
-
const key = typeof stateEntry?.key === 'string' ? stateEntry.key : null;
|
|
47
|
-
recordScopedIdentifierRewrite(out.map, out.ambiguous, deriveScopedIdentifierAlias(key), key);
|
|
48
|
-
}
|
|
49
|
-
const functionBindings = Array.isArray(ir?.hoisted?.functions) ? ir.hoisted.functions : [];
|
|
50
|
-
for (const fnName of functionBindings) {
|
|
51
|
-
if (typeof fnName !== 'string') {
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
recordScopedIdentifierRewrite(out.map, out.ambiguous, deriveScopedIdentifierAlias(fnName), fnName);
|
|
55
|
-
}
|
|
56
|
-
const declarations = Array.isArray(ir?.hoisted?.declarations) ? ir.hoisted.declarations : [];
|
|
57
|
-
for (const declaration of declarations) {
|
|
58
|
-
if (typeof declaration !== 'string') {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
for (const identifier of extractDeclaredIdentifiers(declaration)) {
|
|
62
|
-
recordScopedIdentifierRewrite(out.map, out.ambiguous, deriveScopedIdentifierAlias(identifier), identifier);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return out;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* @param {string} expr
|
|
69
|
-
* @param {{
|
|
70
|
-
* expressionRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null,
|
|
71
|
-
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
72
|
-
* } | null} rewriteContext
|
|
73
|
-
* @returns {string}
|
|
74
|
-
*/
|
|
75
|
-
export function rewritePropsExpression(expr, rewriteContext = null) {
|
|
76
|
-
const trimmed = String(expr || '').trim();
|
|
77
|
-
if (!trimmed) {
|
|
78
|
-
return trimmed;
|
|
79
|
-
}
|
|
80
|
-
const expressionMap = rewriteContext?.expressionRewrite?.map;
|
|
81
|
-
const expressionAmbiguous = rewriteContext?.expressionRewrite?.ambiguous;
|
|
82
|
-
if (expressionMap instanceof Map &&
|
|
83
|
-
!(expressionAmbiguous instanceof Set && expressionAmbiguous.has(trimmed))) {
|
|
84
|
-
const exact = expressionMap.get(trimmed);
|
|
85
|
-
if (typeof exact === 'string' && exact.length > 0) {
|
|
86
|
-
return normalizeTypeScriptExpression(exact);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const scopeMap = rewriteContext?.scopeRewrite?.map;
|
|
90
|
-
const scopeAmbiguous = rewriteContext?.scopeRewrite?.ambiguous;
|
|
91
|
-
const rootMatch = trimmed.match(/^([A-Za-z_$][A-Za-z0-9_$]*)([\s\S]*)$/);
|
|
92
|
-
if (!(scopeMap instanceof Map)) {
|
|
93
|
-
return normalizeTypeScriptExpression(trimmed);
|
|
94
|
-
}
|
|
95
|
-
if (!rootMatch) {
|
|
96
|
-
return rewriteIdentifiersWithinExpression(trimmed, scopeMap, scopeAmbiguous);
|
|
97
|
-
}
|
|
98
|
-
const root = rootMatch[1];
|
|
99
|
-
if (scopeAmbiguous instanceof Set && scopeAmbiguous.has(root)) {
|
|
100
|
-
return rewriteIdentifiersWithinExpression(trimmed, scopeMap, scopeAmbiguous);
|
|
101
|
-
}
|
|
102
|
-
const rewrittenRoot = scopeMap.get(root);
|
|
103
|
-
if (typeof rewrittenRoot !== 'string' || rewrittenRoot.length === 0 || rewrittenRoot === root) {
|
|
104
|
-
return rewriteIdentifiersWithinExpression(trimmed, scopeMap, scopeAmbiguous);
|
|
105
|
-
}
|
|
106
|
-
if (rootMatch[2].trim().length === 0) {
|
|
107
|
-
return normalizeTypeScriptExpression(rewrittenRoot);
|
|
108
|
-
}
|
|
109
|
-
const rewrittenExpr = rewriteIdentifiersWithinExpression(trimmed, scopeMap, scopeAmbiguous);
|
|
110
|
-
return typeof rewrittenExpr === 'string' && rewrittenExpr.length > 0
|
|
111
|
-
? rewrittenExpr
|
|
112
|
-
: normalizeTypeScriptExpression(`${rewrittenRoot}${rootMatch[2]}`);
|
|
113
|
-
}
|
|
1
|
+
import { normalizeTypeScriptExpression, renderObjectKey } from './typescript-expression-utils.js';
|
|
2
|
+
import { rewriteCompilerSignalMapReferences } from './compiler-signal-expression.js';
|
|
114
3
|
/**
|
|
115
4
|
* @param {string | null | undefined} compiledExpr
|
|
116
5
|
* @param {{
|
|
@@ -126,22 +15,24 @@ export function resolveCompiledPropsExpression(compiledExpr, expressionRewrite =
|
|
|
126
15
|
}
|
|
127
16
|
const signals = Array.isArray(expressionRewrite?.signals) ? expressionRewrite.signals : [];
|
|
128
17
|
const stateBindings = Array.isArray(expressionRewrite?.stateBindings) ? expressionRewrite.stateBindings : [];
|
|
129
|
-
|
|
130
|
-
const signalIndex = Number.parseInt(rawIndex, 10);
|
|
131
|
-
if (!Number.isInteger(signalIndex)) {
|
|
132
|
-
return full;
|
|
133
|
-
}
|
|
18
|
+
return rewriteCompilerSignalMapReferences(source, ({ ts, signalIndex, valueRead }) => {
|
|
134
19
|
const signal = signals[signalIndex];
|
|
135
20
|
const stateIndex = signal?.state_index;
|
|
136
21
|
const stateKey = Number.isInteger(stateIndex) ? stateBindings[stateIndex]?.key : null;
|
|
137
22
|
if (typeof stateKey !== 'string' || stateKey.length === 0) {
|
|
138
|
-
return
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
if (valueRead) {
|
|
26
|
+
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(stateKey), 'get'), undefined, []);
|
|
139
27
|
}
|
|
140
|
-
return
|
|
28
|
+
return ts.factory.createIdentifier(stateKey);
|
|
141
29
|
});
|
|
142
|
-
return normalizeTypeScriptExpression(resolved);
|
|
143
30
|
}
|
|
144
31
|
/**
|
|
32
|
+
* The only allowed downstream props rewrite boundary is compiler-owned exact lookup.
|
|
33
|
+
* If the compiler did not emit a mapping for the attr expression, CLI keeps the
|
|
34
|
+
* original expression text without attempting identifier reinterpretation.
|
|
35
|
+
*
|
|
145
36
|
* @param {string} expr
|
|
146
37
|
* @param {{
|
|
147
38
|
* expressionRewrite?: {
|
|
@@ -150,8 +41,7 @@ export function resolveCompiledPropsExpression(compiledExpr, expressionRewrite =
|
|
|
150
41
|
* ambiguous?: Set<string>,
|
|
151
42
|
* signals?: Array<{ state_index?: number }>,
|
|
152
43
|
* stateBindings?: Array<{ key?: string }>
|
|
153
|
-
* } | null
|
|
154
|
-
* scopeRewrite?: { map?: Map<string, string>, ambiguous?: Set<string> } | null
|
|
44
|
+
* } | null
|
|
155
45
|
* } | null} rewriteContext
|
|
156
46
|
* @returns {string}
|
|
157
47
|
*/
|
|
@@ -177,13 +67,18 @@ export function resolvePropsValueCode(expr, rewriteContext = null) {
|
|
|
177
67
|
return normalizeTypeScriptExpression(exact);
|
|
178
68
|
}
|
|
179
69
|
}
|
|
180
|
-
return
|
|
70
|
+
return normalizeTypeScriptExpression(trimmed);
|
|
181
71
|
}
|
|
182
72
|
/**
|
|
183
73
|
* @param {string} attrs
|
|
184
74
|
* @param {{
|
|
185
|
-
* expressionRewrite?: {
|
|
186
|
-
*
|
|
75
|
+
* expressionRewrite?: {
|
|
76
|
+
* map?: Map<string, string>,
|
|
77
|
+
* bindings?: Map<string, { compiled_expr?: string | null }>,
|
|
78
|
+
* ambiguous?: Set<string>,
|
|
79
|
+
* signals?: Array<{ state_index?: number }>,
|
|
80
|
+
* stateBindings?: Array<{ key?: string }>
|
|
81
|
+
* } | null
|
|
187
82
|
* } | null} rewriteContext
|
|
188
83
|
* @returns {string}
|
|
189
84
|
*/
|
|
@@ -225,8 +120,13 @@ export function renderPropsLiteralFromAttrs(attrs, rewriteContext = null) {
|
|
|
225
120
|
* @param {string} source
|
|
226
121
|
* @param {string} attrs
|
|
227
122
|
* @param {{
|
|
228
|
-
* expressionRewrite?: {
|
|
229
|
-
*
|
|
123
|
+
* expressionRewrite?: {
|
|
124
|
+
* map?: Map<string, string>,
|
|
125
|
+
* bindings?: Map<string, { compiled_expr?: string | null }>,
|
|
126
|
+
* ambiguous?: Set<string>,
|
|
127
|
+
* signals?: Array<{ state_index?: number }>,
|
|
128
|
+
* stateBindings?: Array<{ key?: string }>
|
|
129
|
+
* } | null
|
|
230
130
|
* } | null} rewriteContext
|
|
231
131
|
* @returns {string}
|
|
232
132
|
*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @param {string} source
|
|
3
3
|
* @param {string} sourceFile
|
|
4
4
|
* @param {object} [compilerOpts]
|
|
5
|
-
* @returns {{ source: string, serverScript: { source: string, prerender: boolean, has_guard: boolean, has_load: boolean, source_path: string } | null }}
|
|
5
|
+
* @returns {{ source: string, serverScript: { source: string, prerender: boolean, has_guard: boolean, has_load: boolean, has_action: boolean, source_path: string, export_paths?: string[] } | null }}
|
|
6
6
|
*/
|
|
7
7
|
export function extractServerScript(source: string, sourceFile: string, compilerOpts?: object): {
|
|
8
8
|
source: string;
|
|
@@ -11,7 +11,9 @@ export function extractServerScript(source: string, sourceFile: string, compiler
|
|
|
11
11
|
prerender: boolean;
|
|
12
12
|
has_guard: boolean;
|
|
13
13
|
has_load: boolean;
|
|
14
|
+
has_action: boolean;
|
|
14
15
|
source_path: string;
|
|
16
|
+
export_paths?: string[];
|
|
15
17
|
} | null;
|
|
16
18
|
};
|
|
17
19
|
/**
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { findNextKnownComponentTag } from '../component-tag-parser.js';
|
|
3
|
+
import { extractStaticExportPaths } from '../static-export-paths.js';
|
|
3
4
|
/**
|
|
4
5
|
* @param {string} source
|
|
5
6
|
* @param {string} sourceFile
|
|
6
7
|
* @param {object} [compilerOpts]
|
|
7
|
-
* @returns {{ source: string, serverScript: { source: string, prerender: boolean, has_guard: boolean, has_load: boolean, source_path: string } | null }}
|
|
8
|
+
* @returns {{ source: string, serverScript: { source: string, prerender: boolean, has_guard: boolean, has_load: boolean, has_action: boolean, source_path: string, export_paths?: string[] } | null }}
|
|
8
9
|
*/
|
|
9
10
|
export function extractServerScript(source, sourceFile, compilerOpts = {}) {
|
|
10
11
|
const scriptRe = /<script\b([^>]*)>([\s\S]*?)<\/script>/gi;
|
|
11
12
|
const serverMatches = [];
|
|
12
|
-
const reservedServerExportRe = /\bexport\s+const\s+(?:data|prerender|guard|load|ssr_data|props|ssr)\b|\bexport\s+(?:async\s+)?function\s+(?:load|guard)\s*\(|\bexport\s+const\s+(?:load|guard)\s*=/;
|
|
13
|
+
const reservedServerExportRe = /\bexport\s+const\s+(?:data|prerender|guard|load|action|ssr_data|props|ssr)\b|\bexport\s+(?:async\s+)?function\s+(?:load|guard|action)\s*\(|\bexport\s+const\s+(?:load|guard|action)\s*=/;
|
|
13
14
|
for (const match of source.matchAll(scriptRe)) {
|
|
14
15
|
const attrs = String(match[1] || '');
|
|
15
16
|
const body = String(match[2] || '');
|
|
@@ -17,7 +18,7 @@ export function extractServerScript(source, sourceFile, compilerOpts = {}) {
|
|
|
17
18
|
if (!isServer && reservedServerExportRe.test(body)) {
|
|
18
19
|
throw new Error(`Zenith server script contract violation:\n` +
|
|
19
20
|
` File: ${sourceFile}\n` +
|
|
20
|
-
` Reason: guard/load/data exports are only allowed in <script server lang="ts"> or adjacent .guard.ts / .load.ts files\n` +
|
|
21
|
+
` Reason: guard/load/action/data exports are only allowed in <script server lang="ts"> or adjacent .guard.ts / .load.ts / .action.ts files\n` +
|
|
21
22
|
` Example: move the export into <script server lang="ts">`);
|
|
22
23
|
}
|
|
23
24
|
if (isServer) {
|
|
@@ -81,6 +82,19 @@ export function extractServerScript(source, sourceFile, compilerOpts = {}) {
|
|
|
81
82
|
` Reason: multiple guard exports detected\n` +
|
|
82
83
|
` Example: keep exactly one export const guard = async (ctx) => ({ ... })`);
|
|
83
84
|
}
|
|
85
|
+
const actionFnMatch = serverSource.match(/\bexport\s+(?:async\s+)?function\s+action\s*\(([^)]*)\)/);
|
|
86
|
+
const actionConstParenMatch = serverSource.match(/\bexport\s+const\s+action\s*=\s*(?:async\s*)?\(([^)]*)\)\s*=>/);
|
|
87
|
+
const actionConstSingleArgMatch = serverSource.match(/\bexport\s+const\s+action\s*=\s*(?:async\s*)?([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=>/);
|
|
88
|
+
const hasAction = Boolean(actionFnMatch || actionConstParenMatch || actionConstSingleArgMatch);
|
|
89
|
+
const actionMatchCount = Number(Boolean(actionFnMatch)) +
|
|
90
|
+
Number(Boolean(actionConstParenMatch)) +
|
|
91
|
+
Number(Boolean(actionConstSingleArgMatch));
|
|
92
|
+
if (actionMatchCount > 1) {
|
|
93
|
+
throw new Error(`Zenith server script contract violation:\n` +
|
|
94
|
+
` File: ${sourceFile}\n` +
|
|
95
|
+
` Reason: multiple action exports detected\n` +
|
|
96
|
+
` Example: keep exactly one export const action = async (ctx) => ({ ... })`);
|
|
97
|
+
}
|
|
84
98
|
const hasData = /\bexport\s+const\s+data\b/.test(serverSource);
|
|
85
99
|
const hasSsrData = /\bexport\s+const\s+ssr_data\b/.test(serverSource);
|
|
86
100
|
const hasSsr = /\bexport\s+const\s+ssr\b/.test(serverSource);
|
|
@@ -119,6 +133,17 @@ export function extractServerScript(source, sourceFile, compilerOpts = {}) {
|
|
|
119
133
|
` Example: export const guard = async (ctx) => ({ ... })`);
|
|
120
134
|
}
|
|
121
135
|
}
|
|
136
|
+
if (hasAction) {
|
|
137
|
+
const singleArg = String(actionConstSingleArgMatch?.[1] || '').trim();
|
|
138
|
+
const paramsText = String((actionFnMatch || actionConstParenMatch)?.[1] || '').trim();
|
|
139
|
+
const arity = singleArg ? 1 : paramsText.length === 0 ? 0 : paramsText.split(',').length;
|
|
140
|
+
if (arity !== 1) {
|
|
141
|
+
throw new Error(`Zenith server script contract violation:\n` +
|
|
142
|
+
` File: ${sourceFile}\n` +
|
|
143
|
+
` Reason: action(ctx) must accept exactly one argument\n` +
|
|
144
|
+
` Example: export const action = async (ctx) => ({ ... })`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
122
147
|
const prerenderMatch = serverSource.match(/\bexport\s+const\s+prerender\s*=\s*([^\n;]+)/);
|
|
123
148
|
let prerender = false;
|
|
124
149
|
if (prerenderMatch) {
|
|
@@ -131,6 +156,7 @@ export function extractServerScript(source, sourceFile, compilerOpts = {}) {
|
|
|
131
156
|
}
|
|
132
157
|
prerender = rawValue.startsWith('true');
|
|
133
158
|
}
|
|
159
|
+
const exportPaths = extractStaticExportPaths(serverSource, sourceFile) || [];
|
|
134
160
|
const start = match.index ?? -1;
|
|
135
161
|
if (start < 0) {
|
|
136
162
|
return {
|
|
@@ -140,7 +166,9 @@ export function extractServerScript(source, sourceFile, compilerOpts = {}) {
|
|
|
140
166
|
prerender,
|
|
141
167
|
has_guard: hasGuard,
|
|
142
168
|
has_load: hasLoad,
|
|
143
|
-
|
|
169
|
+
has_action: hasAction,
|
|
170
|
+
source_path: sourceFile,
|
|
171
|
+
export_paths: exportPaths
|
|
144
172
|
}
|
|
145
173
|
};
|
|
146
174
|
}
|
|
@@ -153,7 +181,9 @@ export function extractServerScript(source, sourceFile, compilerOpts = {}) {
|
|
|
153
181
|
prerender,
|
|
154
182
|
has_guard: hasGuard,
|
|
155
183
|
has_load: hasLoad,
|
|
156
|
-
|
|
184
|
+
has_action: hasAction,
|
|
185
|
+
source_path: sourceFile,
|
|
186
|
+
export_paths: exportPaths
|
|
157
187
|
}
|
|
158
188
|
};
|
|
159
189
|
}
|
|
@@ -11,14 +11,15 @@ export function writeBuildOutputManifest({ coreOutputDir, staticDir, target, rou
|
|
|
11
11
|
base_path: string;
|
|
12
12
|
content_hash: any;
|
|
13
13
|
routes: {
|
|
14
|
+
html: any;
|
|
15
|
+
assets: any[];
|
|
16
|
+
export_paths?: any[] | undefined;
|
|
14
17
|
path: any;
|
|
15
18
|
file: any;
|
|
16
19
|
path_kind: any;
|
|
17
20
|
render_mode: any;
|
|
18
21
|
requires_hydration: boolean;
|
|
19
22
|
params: any[];
|
|
20
|
-
html: any;
|
|
21
|
-
assets: any[];
|
|
22
23
|
}[];
|
|
23
24
|
assets: {
|
|
24
25
|
js: any[];
|
|
@@ -67,6 +67,9 @@ export async function writeBuildOutputManifest({ coreOutputDir, staticDir, targe
|
|
|
67
67
|
render_mode: entry.render_mode,
|
|
68
68
|
requires_hydration: /<script\b[^>]*type="module"/i.test(html),
|
|
69
69
|
params: [...entry.params],
|
|
70
|
+
...(Array.isArray(entry.export_paths) && entry.export_paths.length > 0
|
|
71
|
+
? { export_paths: [...entry.export_paths] }
|
|
72
|
+
: {}),
|
|
70
73
|
html: htmlPath,
|
|
71
74
|
assets
|
|
72
75
|
});
|
package/dist/build.js
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import { mkdir, rm } from 'node:fs/promises';
|
|
1
|
+
import { cp, mkdir, rm } from 'node:fs/promises';
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { resolveBuildAdapter } from './adapters/resolve-adapter.js';
|
|
4
4
|
import { normalizeBasePath } from './base-path.js';
|
|
5
5
|
import { rewriteSoftNavigationHrefBasePathInHtmlFiles } from './base-path-html.js';
|
|
6
6
|
import { writeBuildOutputManifest } from './build-output-manifest.js';
|
|
7
7
|
import { generateManifest } from './manifest.js';
|
|
8
|
+
import { writeResourceRouteManifest } from './resource-manifest.js';
|
|
8
9
|
import { buildComponentRegistry } from './resolve-components.js';
|
|
9
10
|
import { collectAssets, createCompilerWarningEmitter, runBundler } from './build/compiler-runtime.js';
|
|
10
11
|
import { buildPageEnvelopes } from './build/page-loop.js';
|
|
11
12
|
import { deriveProjectRootFromPagesDir, ensureZenithTypeDeclarations } from './build/type-declarations.js';
|
|
12
|
-
import { materializeImageMarkupInHtmlFiles } from './images/materialize.js';
|
|
13
13
|
import { buildImageArtifacts } from './images/service.js';
|
|
14
|
+
import { injectImageMaterializationIntoRouterManifest } from './images/router-manifest.js';
|
|
14
15
|
import { createImageRuntimePayload, injectImageRuntimePayloadIntoHtmlFiles } from './images/payload.js';
|
|
16
|
+
import { supportsTargetRouteCheck } from './route-check-support.js';
|
|
15
17
|
import { createStartupProfiler } from './startup-profile.js';
|
|
16
18
|
import { writeServerOutput } from './server-output.js';
|
|
17
19
|
import { resolveBundlerBin } from './toolchain-paths.js';
|
|
18
20
|
import { createBundlerToolchain, createCompilerToolchain, ensureToolchainCompatibility, getActiveToolchainCandidate } from './toolchain-runner.js';
|
|
19
21
|
import { maybeWarnAboutZenithVersionMismatch } from './version-check.js';
|
|
20
22
|
export { createCompilerWarningEmitter };
|
|
21
|
-
const RUNTIME_MARKUP_BINDING = '__ZENITH_INTERNAL_ZENHTML';
|
|
22
23
|
function createCompilerTotals() {
|
|
23
24
|
return {
|
|
24
25
|
pageMs: 0,
|
|
@@ -49,12 +50,14 @@ export async function build(options) {
|
|
|
49
50
|
const projectRoot = deriveProjectRootFromPagesDir(pagesDir);
|
|
50
51
|
const coreOutputDir = join(projectRoot, '.zenith-output');
|
|
51
52
|
const staticOutputDir = join(coreOutputDir, 'static');
|
|
53
|
+
const imageStageDir = join(coreOutputDir, 'image-materialization-stage');
|
|
52
54
|
const srcDir = resolve(pagesDir, '..');
|
|
53
55
|
const compilerBin = createCompilerToolchain({ projectRoot, logger });
|
|
54
56
|
const bundlerBin = createBundlerToolchain({ projectRoot, logger });
|
|
55
57
|
const compilerTotals = createCompilerTotals();
|
|
56
58
|
const { target, adapter, mode } = resolveBuildAdapter(config);
|
|
57
59
|
const basePath = normalizeBasePath(config.basePath || '/');
|
|
60
|
+
const routeCheckEnabled = supportsTargetRouteCheck(target);
|
|
58
61
|
const routerEnabled = config.router === true;
|
|
59
62
|
const compilerOpts = {
|
|
60
63
|
typescriptDefault: config.typescriptDefault === true,
|
|
@@ -72,13 +75,13 @@ export async function build(options) {
|
|
|
72
75
|
}));
|
|
73
76
|
}
|
|
74
77
|
const registry = startupProfile.measureSync('build_component_registry', () => buildComponentRegistry(srcDir));
|
|
75
|
-
void RUNTIME_MARKUP_BINDING;
|
|
76
78
|
const manifest = await startupProfile.measureAsync('generate_manifest', () => generateManifest(pagesDir, '.zen', { compilerOpts }));
|
|
79
|
+
const pageManifest = manifest.filter((entry) => entry?.route_kind !== 'resource');
|
|
77
80
|
if (mode !== 'legacy') {
|
|
78
81
|
adapter.validateRoutes(manifest);
|
|
79
82
|
}
|
|
80
83
|
await startupProfile.measureAsync('ensure_zenith_type_declarations', () => ensureZenithTypeDeclarations({
|
|
81
|
-
manifest,
|
|
84
|
+
manifest: pageManifest,
|
|
82
85
|
pagesDir
|
|
83
86
|
}));
|
|
84
87
|
await startupProfile.measureAsync('reset_core_output', () => rm(coreOutputDir, { recursive: true, force: true }));
|
|
@@ -91,7 +94,7 @@ export async function build(options) {
|
|
|
91
94
|
console.warn(line);
|
|
92
95
|
});
|
|
93
96
|
const { envelopes, expressionRewriteMetrics } = await buildPageEnvelopes({
|
|
94
|
-
manifest,
|
|
97
|
+
manifest: pageManifest,
|
|
95
98
|
pagesDir,
|
|
96
99
|
srcDir,
|
|
97
100
|
registry,
|
|
@@ -102,26 +105,37 @@ export async function build(options) {
|
|
|
102
105
|
compilerTotals,
|
|
103
106
|
emitCompilerWarning
|
|
104
107
|
});
|
|
105
|
-
if (envelopes.length > 0) {
|
|
106
|
-
await startupProfile.measureAsync('run_bundler', () => runBundler(envelopes, staticOutputDir, projectRoot, logger, showBundlerInfo, bundlerBin, { basePath }), { envelopes: envelopes.length });
|
|
107
|
-
}
|
|
108
|
-
await startupProfile.measureAsync('rewrite_soft_navigation_base_path', () => rewriteSoftNavigationHrefBasePathInHtmlFiles(staticOutputDir, basePath));
|
|
109
108
|
const { manifest: imageManifest } = await startupProfile.measureAsync('build_image_artifacts', () => buildImageArtifacts({
|
|
110
109
|
projectRoot,
|
|
111
|
-
outDir:
|
|
110
|
+
outDir: imageStageDir,
|
|
112
111
|
config: config.images
|
|
113
112
|
}));
|
|
114
113
|
const imageRuntimePayload = createImageRuntimePayload(config.images, imageManifest, 'passthrough', basePath);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
if (envelopes.length > 0) {
|
|
115
|
+
await startupProfile.measureAsync('run_bundler', () => runBundler(envelopes, staticOutputDir, projectRoot, logger, showBundlerInfo, bundlerBin, {
|
|
116
|
+
basePath,
|
|
117
|
+
routeCheck: routeCheckEnabled,
|
|
118
|
+
imageRuntimePayload
|
|
119
|
+
}), { envelopes: envelopes.length });
|
|
120
|
+
await startupProfile.measureAsync('inject_image_materialization_manifest', () => injectImageMaterializationIntoRouterManifest(staticOutputDir, envelopes), { envelopes: envelopes.length });
|
|
121
|
+
}
|
|
122
|
+
await startupProfile.measureAsync('write_resource_manifest', () => writeResourceRouteManifest(staticOutputDir, manifest, basePath));
|
|
123
|
+
await startupProfile.measureAsync('rewrite_soft_navigation_base_path', () => rewriteSoftNavigationHrefBasePathInHtmlFiles(staticOutputDir, basePath));
|
|
124
|
+
await startupProfile.measureAsync('stage_image_artifacts_into_static_output', async () => {
|
|
125
|
+
if (Object.keys(imageManifest).length === 0) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
await cp(join(imageStageDir, '_zenith'), join(staticOutputDir, '_zenith'), {
|
|
129
|
+
recursive: true,
|
|
130
|
+
force: true
|
|
131
|
+
});
|
|
132
|
+
});
|
|
119
133
|
await startupProfile.measureAsync('inject_image_runtime_payload', () => injectImageRuntimePayloadIntoHtmlFiles(staticOutputDir, imageRuntimePayload));
|
|
120
134
|
const buildManifest = await startupProfile.measureAsync('write_core_manifest', () => writeBuildOutputManifest({
|
|
121
135
|
coreOutputDir,
|
|
122
136
|
staticDir: staticOutputDir,
|
|
123
137
|
target,
|
|
124
|
-
routeManifest:
|
|
138
|
+
routeManifest: pageManifest,
|
|
125
139
|
basePath
|
|
126
140
|
}));
|
|
127
141
|
await startupProfile.measureAsync('write_server_output', () => writeServerOutput({
|
|
@@ -134,11 +148,11 @@ export async function build(options) {
|
|
|
134
148
|
await startupProfile.measureAsync('adapt_output', () => adapter.adapt({ coreOutput: coreOutputDir, outDir, manifest: buildManifest, config }));
|
|
135
149
|
const assets = await startupProfile.measureAsync('collect_assets', () => collectAssets(outDir));
|
|
136
150
|
startupProfile.emit('build_complete', {
|
|
137
|
-
pages:
|
|
151
|
+
pages: pageManifest.length,
|
|
138
152
|
assets: assets.length,
|
|
139
153
|
target,
|
|
140
154
|
compilerTotals,
|
|
141
155
|
expressionRewriteMetrics
|
|
142
156
|
});
|
|
143
|
-
return { pages:
|
|
157
|
+
return { pages: pageManifest.length, assets };
|
|
144
158
|
}
|