@zenithbuild/cli 0.7.11 → 0.7.12
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 +10 -1
- package/dist/adapters/adapter-netlify-static.d.ts +2 -5
- package/dist/adapters/adapter-netlify.d.ts +2 -5
- package/dist/adapters/adapter-netlify.js +22 -5
- package/dist/adapters/adapter-types.d.ts +32 -13
- package/dist/adapters/adapter-types.js +0 -59
- package/dist/adapters/adapter-vercel-static.d.ts +2 -5
- package/dist/adapters/adapter-vercel.d.ts +2 -5
- package/dist/adapters/adapter-vercel.js +21 -6
- package/dist/adapters/copy-hosted-page-runtime.d.ts +2 -1
- package/dist/adapters/copy-hosted-page-runtime.js +68 -3
- package/dist/adapters/resolve-adapter.d.ts +6 -4
- package/dist/build/expression-rewrites.d.ts +3 -1
- package/dist/build/expression-rewrites.js +14 -2
- package/dist/build/page-component-loop.d.ts +1 -0
- package/dist/build/page-component-loop.js +66 -6
- package/dist/build/page-ir-normalization.js +7 -0
- package/dist/build/page-loop-state.d.ts +2 -1
- package/dist/build/page-loop-state.js +9 -2
- package/dist/build/page-loop.js +10 -1
- package/dist/build/scoped-expression-context.d.ts +5 -0
- package/dist/build/scoped-expression-context.js +133 -0
- package/dist/build/type-declarations.d.ts +2 -1
- package/dist/build/type-declarations.js +31 -1
- package/dist/build-output-manifest.d.ts +10 -6
- package/dist/build-output-manifest.js +4 -1
- package/dist/build.js +11 -2
- package/dist/component-instance-ir.js +1 -0
- package/dist/component-occurrences.d.ts +9 -0
- package/dist/component-occurrences.js +18 -0
- package/dist/config-plugins.d.ts +12 -0
- package/dist/config-plugins.js +100 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +56 -5
- package/dist/dev-server/request-handler.js +46 -4
- package/dist/dev-server.js +92 -4
- package/dist/global-middleware-runtime-source.d.ts +15 -0
- package/dist/global-middleware-runtime-source.js +62 -0
- package/dist/global-middleware.d.ts +13 -0
- package/dist/global-middleware.js +252 -0
- package/dist/manifest.d.ts +9 -1
- package/dist/manifest.js +66 -26
- package/dist/preview/request-handler.js +78 -5
- package/dist/preview/server-runner.d.ts +7 -2
- package/dist/preview/server-runner.js +19 -6
- package/dist/preview/server-script-runner-template.js +97 -29
- package/dist/route-classification.d.ts +2 -1
- package/dist/route-classification.js +6 -2
- package/dist/scoped-server-data/analyze-owner-file.d.ts +3 -0
- package/dist/scoped-server-data/analyze-owner-file.js +149 -0
- package/dist/scoped-server-data/diagnostics.d.ts +18 -0
- package/dist/scoped-server-data/diagnostics.js +32 -0
- package/dist/scoped-server-data/lowering.d.ts +27 -0
- package/dist/scoped-server-data/lowering.js +242 -0
- package/dist/scoped-server-data/manifest-integration.d.ts +4 -0
- package/dist/scoped-server-data/manifest-integration.js +125 -0
- package/dist/scoped-server-data/owner-scanner.d.ts +6 -0
- package/dist/scoped-server-data/owner-scanner.js +55 -0
- package/dist/scoped-server-data/parse-owner-server-block.d.ts +12 -0
- package/dist/scoped-server-data/parse-owner-server-block.js +35 -0
- package/dist/scoped-server-data/runtime.d.ts +24 -0
- package/dist/scoped-server-data/runtime.js +121 -0
- package/dist/scoped-server-data/serialization-set.d.ts +2 -0
- package/dist/scoped-server-data/serialization-set.js +52 -0
- package/dist/scoped-server-data/static-props.d.ts +12 -0
- package/dist/scoped-server-data/static-props.js +307 -0
- package/dist/scoped-server-data/type-declarations.d.ts +10 -0
- package/dist/scoped-server-data/type-declarations.js +368 -0
- package/dist/scoped-server-data/types.d.ts +74 -0
- package/dist/scoped-server-data/types.js +1 -0
- package/dist/server-contract/auth-control-flow.d.ts +1 -0
- package/dist/server-contract/auth-control-flow.js +10 -0
- package/dist/server-contract/resolve.d.ts +19 -0
- package/dist/server-contract/resolve.js +85 -13
- package/dist/server-contract/resolved-envelope.d.ts +9 -0
- package/dist/server-contract/resolved-envelope.js +14 -0
- package/dist/server-contract/stage.js +1 -10
- package/dist/server-module-output.d.ts +9 -0
- package/dist/server-module-output.js +250 -0
- package/dist/server-output.d.ts +7 -1
- package/dist/server-output.js +138 -179
- package/dist/server-runtime/matched-route-pipeline.d.ts +1 -0
- package/dist/server-runtime/matched-route-pipeline.js +1 -0
- package/dist/server-runtime/node-server.js +21 -1
- package/dist/server-runtime/route-render.d.ts +12 -3
- package/dist/server-runtime/route-render.js +67 -13
- package/package.json +3 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
2
3
|
import { pathToFileURL } from 'node:url';
|
|
3
4
|
import { attachRouteAuth } from '../auth/route-auth.js';
|
|
4
5
|
import { appLocalRedirectLocation, normalizeBasePath, prependBasePath } from '../base-path.js';
|
|
@@ -6,9 +7,27 @@ import { createImageRuntimePayload, injectImageRuntimePayload } from '../images/
|
|
|
6
7
|
import { materializeImageMarkup } from '../images/materialize.js';
|
|
7
8
|
import { buildResourceResponseDescriptor } from '../resource-response.js';
|
|
8
9
|
import { clientFacingRouteMessage, defaultRouteDenyMessage, logServerException } from '../server-error.js';
|
|
9
|
-
import { allow, data, deny, download, invalid, json, redirect,
|
|
10
|
+
import { allow, data, deny, download, invalid, json, redirect, text } from '../server-contract.js';
|
|
11
|
+
import { executeMatchedRoutePipeline } from '../server-contract/resolve.js';
|
|
10
12
|
const MODULE_CACHE = new Map();
|
|
13
|
+
const GLOBAL_MIDDLEWARE_MODULE_CACHE = new Map();
|
|
11
14
|
const INTERNAL_QUERY_PREFIX = '__zenith_param_';
|
|
15
|
+
const SCOPED_ROUTE_FIELD = ['scoped', 'server', 'data'].join('_');
|
|
16
|
+
const HAS_SCOPED_ROUTE_FIELD = ['has', SCOPED_ROUTE_FIELD].join('_');
|
|
17
|
+
let SCOPED_SERVER_DATA_RUNTIME_PROMISE = null;
|
|
18
|
+
function hasRouteScopedServerData(route) {
|
|
19
|
+
return route?.route_kind !== 'resource' &&
|
|
20
|
+
route?.prerender !== true &&
|
|
21
|
+
route?.[HAS_SCOPED_ROUTE_FIELD] === true &&
|
|
22
|
+
Array.isArray(route?.[SCOPED_ROUTE_FIELD]) &&
|
|
23
|
+
route[SCOPED_ROUTE_FIELD].length > 0;
|
|
24
|
+
}
|
|
25
|
+
async function loadScopedServerDataRuntime() {
|
|
26
|
+
if (!SCOPED_SERVER_DATA_RUNTIME_PROMISE) {
|
|
27
|
+
SCOPED_SERVER_DATA_RUNTIME_PROMISE = import('../scoped-server-data/runtime.js');
|
|
28
|
+
}
|
|
29
|
+
return SCOPED_SERVER_DATA_RUNTIME_PROMISE;
|
|
30
|
+
}
|
|
12
31
|
function parseCookies(rawCookieHeader) {
|
|
13
32
|
const out = Object.create(null);
|
|
14
33
|
const raw = String(rawCookieHeader || '');
|
|
@@ -159,6 +178,22 @@ async function loadRouteExports(routeModulePath) {
|
|
|
159
178
|
MODULE_CACHE.set(cacheKey, value);
|
|
160
179
|
return value;
|
|
161
180
|
}
|
|
181
|
+
async function loadGlobalMiddleware(globalMiddlewareModulePath) {
|
|
182
|
+
if (!globalMiddlewareModulePath) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
const cacheKey = globalMiddlewareModulePath;
|
|
186
|
+
if (GLOBAL_MIDDLEWARE_MODULE_CACHE.has(cacheKey)) {
|
|
187
|
+
return GLOBAL_MIDDLEWARE_MODULE_CACHE.get(cacheKey);
|
|
188
|
+
}
|
|
189
|
+
const mod = await import(pathToFileURL(globalMiddlewareModulePath).href);
|
|
190
|
+
const middlewareFn = mod?.default;
|
|
191
|
+
if (typeof middlewareFn !== 'function') {
|
|
192
|
+
throw new Error('[Zenith:Middleware] Compiled global middleware module must default export a function.');
|
|
193
|
+
}
|
|
194
|
+
GLOBAL_MIDDLEWARE_MODULE_CACHE.set(cacheKey, middlewareFn);
|
|
195
|
+
return middlewareFn;
|
|
196
|
+
}
|
|
162
197
|
function createRouteContext({ request, route, params, publicUrl, guardOnly = false }) {
|
|
163
198
|
const requestHeaders = Object.fromEntries(request.headers.entries());
|
|
164
199
|
const ctx = {
|
|
@@ -198,24 +233,28 @@ function createRouteContext({ request, route, params, publicUrl, guardOnly = fal
|
|
|
198
233
|
* route: { path: string, params?: string[], route_id?: string | null, server_script_path?: string | null, file?: string | null },
|
|
199
234
|
* params: Record<string, string>,
|
|
200
235
|
* routeModulePath: string,
|
|
236
|
+
* globalMiddlewareModulePath?: string | null,
|
|
201
237
|
* guardOnly?: boolean
|
|
202
238
|
* }} options
|
|
203
|
-
* @returns {Promise<{ publicUrl: URL, result: { kind: string, [key: string]: unknown }, trace: { guard: string, action: string, load: string }, status?: number, setCookies?: string[] }>}
|
|
239
|
+
* @returns {Promise<{ publicUrl: URL, ctx: object, result: { kind: string, [key: string]: unknown }, trace: { guard: string, action: string, load: string }, status?: number, setCookies?: string[] }>}
|
|
204
240
|
*/
|
|
205
241
|
export async function executeRouteRequest(options) {
|
|
206
|
-
const { request, route, params, routeModulePath, guardOnly = false } = options;
|
|
242
|
+
const { request, route, params, routeModulePath, globalMiddlewareModulePath = null, guardOnly = false } = options;
|
|
207
243
|
const publicUrl = buildPublicUrl(request.url, route, params);
|
|
208
244
|
const ctx = createRouteContext({ request, route, params, publicUrl, guardOnly });
|
|
209
245
|
const exports = await loadRouteExports(routeModulePath);
|
|
210
|
-
const
|
|
246
|
+
const globalMiddleware = await loadGlobalMiddleware(globalMiddlewareModulePath);
|
|
247
|
+
const resolved = await executeMatchedRoutePipeline({
|
|
211
248
|
exports,
|
|
212
249
|
ctx,
|
|
213
250
|
filePath: route.file || route.server_script_path || route.path,
|
|
214
251
|
guardOnly,
|
|
215
|
-
routeKind: route.route_kind === 'resource' ? 'resource' : 'page'
|
|
252
|
+
routeKind: route.route_kind === 'resource' ? 'resource' : 'page',
|
|
253
|
+
globalMiddleware
|
|
216
254
|
});
|
|
217
255
|
return {
|
|
218
256
|
publicUrl,
|
|
257
|
+
ctx,
|
|
219
258
|
result: resolved.result,
|
|
220
259
|
trace: resolved.trace,
|
|
221
260
|
status: resolved.status,
|
|
@@ -228,20 +267,23 @@ export async function executeRouteRequest(options) {
|
|
|
228
267
|
* route: { path: string, params?: string[], route_id?: string | null, server_script_path?: string | null, file?: string | null },
|
|
229
268
|
* params: Record<string, string>,
|
|
230
269
|
* routeModulePath: string,
|
|
270
|
+
* globalMiddlewareModulePath?: string | null,
|
|
231
271
|
* shellHtmlPath: string,
|
|
232
272
|
* imageManifestPath?: string | null,
|
|
233
|
-
* imageConfig?: Record<string, unknown
|
|
273
|
+
* imageConfig?: Record<string, unknown>,
|
|
274
|
+
* scopedModuleBaseDir?: string | null
|
|
234
275
|
* }} options
|
|
235
276
|
* @returns {Promise<Response>}
|
|
236
277
|
*/
|
|
237
278
|
export async function renderRouteRequest(options) {
|
|
238
|
-
const { request, route, params, routeModulePath, shellHtmlPath, imageManifestPath = null, imageConfig = {} } = options;
|
|
279
|
+
const { request, route, params, routeModulePath, globalMiddlewareModulePath = null, shellHtmlPath, imageManifestPath = null, imageConfig = {}, scopedModuleBaseDir = null } = options;
|
|
239
280
|
try {
|
|
240
|
-
const {
|
|
281
|
+
const { ctx, result, status, setCookies = [] } = await executeRouteRequest({
|
|
241
282
|
request,
|
|
242
283
|
route,
|
|
243
284
|
params,
|
|
244
|
-
routeModulePath
|
|
285
|
+
routeModulePath,
|
|
286
|
+
globalMiddlewareModulePath
|
|
245
287
|
});
|
|
246
288
|
if (result.kind === 'redirect') {
|
|
247
289
|
const headers = new Headers({
|
|
@@ -261,6 +303,16 @@ export async function renderRouteRequest(options) {
|
|
|
261
303
|
const ssrPayload = result.kind === 'data' && result.data && typeof result.data === 'object' && !Array.isArray(result.data)
|
|
262
304
|
? result.data
|
|
263
305
|
: {};
|
|
306
|
+
let finalSsrPayload = ssrPayload;
|
|
307
|
+
if (hasRouteScopedServerData(route)) {
|
|
308
|
+
const scopedRuntime = await loadScopedServerDataRuntime();
|
|
309
|
+
const scopedPayload = await scopedRuntime.executeScopedServerData({
|
|
310
|
+
route,
|
|
311
|
+
ctx,
|
|
312
|
+
serverDir: scopedModuleBaseDir || dirname(dirname(dirname(dirname(routeModulePath))))
|
|
313
|
+
});
|
|
314
|
+
finalSsrPayload = scopedRuntime.mergeScopedSsrPayload(ssrPayload, scopedPayload);
|
|
315
|
+
}
|
|
264
316
|
const localImages = await loadImageManifest(imageManifestPath);
|
|
265
317
|
const imagePayload = createImageRuntimePayload(imageConfig, localImages, 'passthrough', route.base_path || '/');
|
|
266
318
|
let html = await readFile(shellHtmlPath, 'utf8');
|
|
@@ -271,7 +323,7 @@ export async function renderRouteRequest(options) {
|
|
|
271
323
|
? route.image_materialization
|
|
272
324
|
: []
|
|
273
325
|
});
|
|
274
|
-
html = injectSsrPayload(html,
|
|
326
|
+
html = injectSsrPayload(html, finalSsrPayload);
|
|
275
327
|
html = injectImageRuntimePayload(html, imagePayload);
|
|
276
328
|
const headers = new Headers({
|
|
277
329
|
'Content-Type': 'text/html; charset=utf-8'
|
|
@@ -292,18 +344,20 @@ export async function renderRouteRequest(options) {
|
|
|
292
344
|
* request: Request,
|
|
293
345
|
* route: { path: string, params?: string[], route_id?: string | null, server_script_path?: string | null, file?: string | null, route_kind?: string | null, base_path?: string | null },
|
|
294
346
|
* params: Record<string, string>,
|
|
295
|
-
* routeModulePath: string
|
|
347
|
+
* routeModulePath: string,
|
|
348
|
+
* globalMiddlewareModulePath?: string | null
|
|
296
349
|
* }} options
|
|
297
350
|
* @returns {Promise<Response>}
|
|
298
351
|
*/
|
|
299
352
|
export async function renderResourceRouteRequest(options) {
|
|
300
|
-
const { request, route, params, routeModulePath } = options;
|
|
353
|
+
const { request, route, params, routeModulePath, globalMiddlewareModulePath = null } = options;
|
|
301
354
|
try {
|
|
302
355
|
const { result, setCookies = [] } = await executeRouteRequest({
|
|
303
356
|
request,
|
|
304
357
|
route: { ...route, route_kind: 'resource' },
|
|
305
358
|
params,
|
|
306
|
-
routeModulePath
|
|
359
|
+
routeModulePath,
|
|
360
|
+
globalMiddlewareModulePath
|
|
307
361
|
});
|
|
308
362
|
return createResourceResponse(result, route.base_path || '/', setCookies);
|
|
309
363
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenithbuild/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.12",
|
|
4
4
|
"description": "Deterministic project orchestrator for Zenith framework",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"prepublishOnly": "npm run build"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@zenithbuild/compiler": "0.7.
|
|
39
|
-
"@zenithbuild/bundler": "0.7.
|
|
38
|
+
"@zenithbuild/compiler": "0.7.12",
|
|
39
|
+
"@zenithbuild/bundler": "0.7.12",
|
|
40
40
|
"picocolors": "^1.1.1",
|
|
41
41
|
"sharp": "^0.34.4"
|
|
42
42
|
},
|