@webjsdev/server 0.8.68 → 0.8.69
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/package.json +1 -1
- package/src/dev/config.js +22 -0
- package/src/dev/handler.js +11 -5
- package/src/dev-embed.js +20 -2
- package/src/dev-source-locations.js +10 -4
- package/webjs-config.schema.json +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webjsdev/server",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.69",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The server for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Provides the file-based router, SSR, server actions, route handlers, middleware, and live reload on Node 24+ or Bun.",
|
|
6
6
|
"main": "index.js",
|
package/src/dev/config.js
CHANGED
|
@@ -317,6 +317,28 @@ export async function readDevWatchPathsFromApp(appDir) {
|
|
|
317
317
|
return out;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
+
/**
|
|
321
|
+
* The dev tooling switches in `webjs.dev` (#1504): `embedOrigins` (the embed
|
|
322
|
+
* bridge, #1498) and `sourceLocations` (#1499). Raw values; the env overrides
|
|
323
|
+
* and validation live with each feature (`resolveEmbedOrigins`,
|
|
324
|
+
* `sourceLocationsRequested`). A missing or unreadable package.json is both
|
|
325
|
+
* off.
|
|
326
|
+
*
|
|
327
|
+
* @param {string} appDir
|
|
328
|
+
* @returns {Promise<{ embedOrigins: unknown, sourceLocations: unknown }>}
|
|
329
|
+
*/
|
|
330
|
+
export async function readDevToolingFromApp(appDir) {
|
|
331
|
+
let dev;
|
|
332
|
+
try {
|
|
333
|
+
const pkg = JSON.parse(await readFile(join(appDir, 'package.json'), 'utf8'));
|
|
334
|
+
dev = pkg && pkg.webjs && pkg.webjs.dev;
|
|
335
|
+
} catch {
|
|
336
|
+
dev = undefined;
|
|
337
|
+
}
|
|
338
|
+
if (!dev || typeof dev !== 'object') return { embedOrigins: undefined, sourceLocations: undefined };
|
|
339
|
+
return { embedOrigins: dev.embedOrigins, sourceLocations: dev.sourceLocations };
|
|
340
|
+
}
|
|
341
|
+
|
|
320
342
|
/**
|
|
321
343
|
* Resolve the node:http server timeouts (issue #237) from the app's
|
|
322
344
|
* package.json `webjs.requestTimeoutMs` / `webjs.headersTimeoutMs` /
|
package/src/dev/handler.js
CHANGED
|
@@ -41,7 +41,7 @@ import { setAssetUrlProvider, setFormActionResolver } from '@webjsdev/core';
|
|
|
41
41
|
import { resolveActionIdentity } from '../form-action-identity.js';
|
|
42
42
|
import { setAssetRoots, clearAssetHashCache, setElisionFingerprint, withAssetHash, assetHashFor, resolveAssetUrl } from '../asset-hash.js';
|
|
43
43
|
import { applySecurityHeaders, webRequestIsHttps } from '../headers.js';
|
|
44
|
-
import {
|
|
44
|
+
import { resolveEmbedOrigins, setEmbedOrigins, allowEmbedFraming } from '../dev-embed.js';
|
|
45
45
|
import {
|
|
46
46
|
applyRedirects,
|
|
47
47
|
applyTrailingSlash,
|
|
@@ -62,6 +62,7 @@ import {
|
|
|
62
62
|
readAllowedOriginsFromApp,
|
|
63
63
|
readCspConfigFromApp,
|
|
64
64
|
readBodyLimitsFromApp,
|
|
65
|
+
readDevToolingFromApp,
|
|
65
66
|
} from './config.js';
|
|
66
67
|
import {
|
|
67
68
|
exists, kebab, resolveRequestId, shouldAccessLog, loadAppEnv, collectRouteModules,
|
|
@@ -216,11 +217,14 @@ export async function createRequestHandler(opts) {
|
|
|
216
217
|
// analysis pass re-reads it each rebuild so a dev toggle takes effect live.
|
|
217
218
|
setClientRouterEnabled(await readClientRouterEnabled(appDir));
|
|
218
219
|
|
|
219
|
-
// Dev embed bridge (#1498): `WEBJS_EMBED_ORIGINS` lets the listed parent
|
|
220
|
+
// Dev embed bridge (#1498): `WEBJS_EMBED_ORIGINS` (or `webjs.dev.embedOrigins`) lets the listed parent
|
|
220
221
|
// origins frame this dev server and receive the bridge's messages. Read once
|
|
221
222
|
// here, and only in dev, so a production handler records no origins and
|
|
222
223
|
// neither injects the script nor relaxes a framing header.
|
|
223
|
-
|
|
224
|
+
// `webjs.dev.embedOrigins` in package.json is the default (#1504); a set
|
|
225
|
+
// env var replaces it for one run.
|
|
226
|
+
const devTooling = dev ? await readDevToolingFromApp(appDir) : { embedOrigins: undefined, sourceLocations: undefined };
|
|
227
|
+
const embedOriginsValue = dev ? resolveEmbedOrigins(process.env.WEBJS_EMBED_ORIGINS, devTooling.embedOrigins) : [];
|
|
224
228
|
setEmbedOrigins(embedOriginsValue);
|
|
225
229
|
|
|
226
230
|
const coreDir = locateCoreDir(appDir);
|
|
@@ -288,13 +292,15 @@ export async function createRequestHandler(opts) {
|
|
|
288
292
|
// on seeding would mean `webjs.seed: false` silently broke every no-JS form.
|
|
289
293
|
await registerActionHooks({ seed: await readSeedEnabled(appDir), dev });
|
|
290
294
|
|
|
291
|
-
// Dev source locations (#1499): `WEBJS_SOURCE_LOCATIONS=1`
|
|
295
|
+
// Dev source locations (#1499): `WEBJS_SOURCE_LOCATIONS=1` (or
|
|
296
|
+
// `webjs.dev.sourceLocations: true`) under `webjs dev`
|
|
292
297
|
// stamps `data-webjs-src="<file>:<line>"` on the element opening tags of the
|
|
293
298
|
// app's `html` templates. Read once (the SSR load hook is process-global and
|
|
294
299
|
// cannot be uninstalled), never in prod. The browser half reads
|
|
295
300
|
// `state.sourceLocations` in serve.js; the SSR half is this load hook, which
|
|
296
301
|
// must be in place before any app module is imported.
|
|
297
|
-
|
|
302
|
+
// `webjs.dev.sourceLocations` is the default (#1504); the env var wins.
|
|
303
|
+
const sourceLocations = dev && sourceLocationsRequested(process.env, devTooling.sourceLocations);
|
|
298
304
|
if (sourceLocations) {
|
|
299
305
|
registerSourceLocationHook(appDir);
|
|
300
306
|
// Module URLs are realpaths, so a symlinked app dir registers both forms.
|
package/src/dev-embed.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* The dev embed bridge, SERVER half (#1498).
|
|
3
3
|
*
|
|
4
4
|
* `webjs dev` with `WEBJS_EMBED_ORIGINS` set (a comma-separated list of parent
|
|
5
|
-
* origins, e.g. `https://
|
|
6
|
-
*
|
|
5
|
+
* origins, e.g. `https://builder.example,http://localhost:8080`), or the app's
|
|
6
|
+
* `webjs.dev.embedOrigins` list (#1504), makes an app ready to be previewed
|
|
7
|
+
* inside an iframe on those origins:
|
|
7
8
|
*
|
|
8
9
|
* 1. every HTML document gets a small inline script (the browser half,
|
|
9
10
|
* `dev-embed-client.js`) that reports page state to the parent and takes
|
|
@@ -73,6 +74,23 @@ export function parseEmbedOrigins(raw, opts) {
|
|
|
73
74
|
return out;
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
/**
|
|
78
|
+
* The effective embed origins (#1504): `WEBJS_EMBED_ORIGINS`, when set and
|
|
79
|
+
* non-empty, replaces the app's `webjs.dev.embedOrigins`; otherwise the config
|
|
80
|
+
* list applies. Both go through `parseEmbedOrigins`, so a bad entry is dropped
|
|
81
|
+
* with the same warning wherever it was written.
|
|
82
|
+
*
|
|
83
|
+
* @param {string | undefined} envRaw
|
|
84
|
+
* @param {unknown} configured the app's `webjs.dev.embedOrigins`
|
|
85
|
+
* @param {{ warn?: (msg: string) => void }} [opts]
|
|
86
|
+
* @returns {string[]}
|
|
87
|
+
*/
|
|
88
|
+
export function resolveEmbedOrigins(envRaw, configured, opts) {
|
|
89
|
+
if (typeof envRaw === 'string' && envRaw.trim()) return parseEmbedOrigins(envRaw, opts);
|
|
90
|
+
if (!Array.isArray(configured)) return [];
|
|
91
|
+
return parseEmbedOrigins(configured.filter((o) => typeof o === 'string').join(','), opts);
|
|
92
|
+
}
|
|
93
|
+
|
|
76
94
|
/**
|
|
77
95
|
* Record the allowed embed origins for this process. `createRequestHandler`
|
|
78
96
|
* calls it at construction: the parsed env value in dev, `[]` otherwise.
|
|
@@ -64,15 +64,21 @@ const REGEX_AFTER_KEYWORDS = new Set([
|
|
|
64
64
|
export const SOURCE_LOCATIONS_ENV = 'WEBJS_SOURCE_LOCATIONS';
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
* Whether
|
|
68
|
-
*
|
|
67
|
+
* Whether source locations are on (#1499, #1504). The app's
|
|
68
|
+
* `webjs.dev.sourceLocations` sets the default; the env var, when set, wins
|
|
69
|
+
* either way (`1` / `true` on, `0` / `false` off), so one run can flip it
|
|
70
|
+
* without editing package.json. Read by the dev handler once, at construction;
|
|
71
|
+
* the caller also requires `dev`, so production never consults it.
|
|
69
72
|
*
|
|
70
73
|
* @param {Record<string, string | undefined>} [env]
|
|
74
|
+
* @param {unknown} [configured] the app's `webjs.dev.sourceLocations`
|
|
71
75
|
* @returns {boolean}
|
|
72
76
|
*/
|
|
73
|
-
export function sourceLocationsRequested(env = process.env) {
|
|
77
|
+
export function sourceLocationsRequested(env = process.env, configured = false) {
|
|
74
78
|
const v = String(env[SOURCE_LOCATIONS_ENV] || '').trim().toLowerCase();
|
|
75
|
-
|
|
79
|
+
if (v === '1' || v === 'true') return true;
|
|
80
|
+
if (v === '0' || v === 'false') return false;
|
|
81
|
+
return configured === true;
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
/**
|
package/webjs-config.schema.json
CHANGED
|
@@ -202,6 +202,15 @@
|
|
|
202
202
|
"description": "Extra directories the dev live-reload watcher follows in addition to the appDir (#894), for content the app reads from outside its own tree (e.g. blog markdown in a repo-root blog/ dir). Each entry is resolved relative to the app root and may escape it (../blog). Read by the server (readDevWatchPathsFromApp).",
|
|
203
203
|
"type": "array",
|
|
204
204
|
"items": { "type": "string" }
|
|
205
|
+
},
|
|
206
|
+
"embedOrigins": {
|
|
207
|
+
"description": "Dev embed bridge (#1498, #1504), DEV-ONLY and off by default. Parent origins (e.g. https://builder.example) allowed to frame the dev server: X-Frame-Options is dropped and frame-ancestors widened for them, and every document carries a nonce-signed script that posts { source: 'webjs-embed', type } messages to such a parent and takes { source: 'webjs-embed-host', type } commands from it. A set WEBJS_EMBED_ORIGINS env var replaces this list. Read by the server (readDevToolingFromApp). Ignored by webjs start.",
|
|
208
|
+
"type": "array",
|
|
209
|
+
"items": { "type": "string" }
|
|
210
|
+
},
|
|
211
|
+
"sourceLocations": {
|
|
212
|
+
"description": "Dev source locations (#1499, #1504), DEV-ONLY and off by default. When true, element opening tags in the app's html templates carry data-webjs-src=\"<app-relative-file>:<line>\" in SSR output and client renders. WEBJS_SOURCE_LOCATIONS=1 or 0 overrides it for one run. Read by the server (readDevToolingFromApp). Ignored by webjs start.",
|
|
213
|
+
"type": "boolean"
|
|
205
214
|
}
|
|
206
215
|
}
|
|
207
216
|
},
|