@taujs/server 0.5.5 → 0.5.7
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/index.js +99 -72
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -304,7 +304,7 @@ var SSRTAG = {
|
|
|
304
304
|
ssrHtml: "<!--ssr-html-->"
|
|
305
305
|
};
|
|
306
306
|
var TEMPLATE = {
|
|
307
|
-
defaultEntryClient: "entry-client",
|
|
307
|
+
defaultEntryClient: "entry-client.tsx",
|
|
308
308
|
defaultEntryServer: "entry-server",
|
|
309
309
|
defaultHtmlTemplate: "index.html"
|
|
310
310
|
};
|
|
@@ -1249,7 +1249,7 @@ import { pathToFileURL } from "url";
|
|
|
1249
1249
|
|
|
1250
1250
|
// src/utils/Templates.ts
|
|
1251
1251
|
var CSS_LANGS_RE = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
|
|
1252
|
-
async
|
|
1252
|
+
var collectStyle = async (server, entries) => {
|
|
1253
1253
|
const urls = await collectStyleUrls(server, entries);
|
|
1254
1254
|
const codes = await Promise.all(
|
|
1255
1255
|
urls.map(async (url) => {
|
|
@@ -1258,7 +1258,7 @@ async function collectStyle(server, entries) {
|
|
|
1258
1258
|
})
|
|
1259
1259
|
);
|
|
1260
1260
|
return codes.flat().filter(Boolean).join("\n\n");
|
|
1261
|
-
}
|
|
1261
|
+
};
|
|
1262
1262
|
async function collectStyleUrls(server, entries) {
|
|
1263
1263
|
const visited = /* @__PURE__ */ new Set();
|
|
1264
1264
|
async function traverse(url) {
|
|
@@ -1273,7 +1273,7 @@ async function collectStyleUrls(server, entries) {
|
|
|
1273
1273
|
await Promise.all(entries.map((url) => traverse(url)));
|
|
1274
1274
|
return [...visited].filter((url) => url.match(CSS_LANGS_RE));
|
|
1275
1275
|
}
|
|
1276
|
-
|
|
1276
|
+
var renderPreloadLinks = (ssrManifest, basePath = "") => {
|
|
1277
1277
|
const seen = /* @__PURE__ */ new Set();
|
|
1278
1278
|
let links = "";
|
|
1279
1279
|
for (const moduleId in ssrManifest) {
|
|
@@ -1288,8 +1288,8 @@ function renderPreloadLinks(ssrManifest, basePath = "") {
|
|
|
1288
1288
|
}
|
|
1289
1289
|
}
|
|
1290
1290
|
return links;
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1291
|
+
};
|
|
1292
|
+
var renderPreloadLink = (file) => {
|
|
1293
1293
|
const fileType = file.match(/\.(js|css|woff2?|gif|jpe?g|png|svg)$/)?.[1];
|
|
1294
1294
|
switch (fileType) {
|
|
1295
1295
|
case "js":
|
|
@@ -1309,8 +1309,8 @@ function renderPreloadLink(file) {
|
|
|
1309
1309
|
default:
|
|
1310
1310
|
return "";
|
|
1311
1311
|
}
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1312
|
+
};
|
|
1313
|
+
var getCssLinks = (manifest, basePath = "") => {
|
|
1314
1314
|
const seen = /* @__PURE__ */ new Set();
|
|
1315
1315
|
const styles = [];
|
|
1316
1316
|
for (const key in manifest) {
|
|
@@ -1325,7 +1325,7 @@ function getCssLinks(manifest, basePath = "") {
|
|
|
1325
1325
|
}
|
|
1326
1326
|
}
|
|
1327
1327
|
return styles.join("\n");
|
|
1328
|
-
}
|
|
1328
|
+
};
|
|
1329
1329
|
var overrideCSSHMRConsoleError = () => {
|
|
1330
1330
|
const originalConsoleError = console.error;
|
|
1331
1331
|
console.error = function(message, ...optionalParams) {
|
|
@@ -1337,7 +1337,7 @@ var ensureNonNull = (value, errorMessage) => {
|
|
|
1337
1337
|
if (value === void 0 || value === null) throw new Error(errorMessage);
|
|
1338
1338
|
return value;
|
|
1339
1339
|
};
|
|
1340
|
-
|
|
1340
|
+
var processTemplate = (template) => {
|
|
1341
1341
|
const [headSplit, bodySplit] = template.split(SSRTAG.ssrHead);
|
|
1342
1342
|
if (typeof bodySplit === "undefined") throw new Error(`Template is missing ${SSRTAG.ssrHead} marker.`);
|
|
1343
1343
|
const [beforeBody, afterBody] = bodySplit.split(SSRTAG.ssrHtml);
|
|
@@ -1348,10 +1348,33 @@ function processTemplate(template) {
|
|
|
1348
1348
|
beforeBody: beforeBody.replace(/\s*$/, ""),
|
|
1349
1349
|
afterBody: afterBody.replace(/^\s*/, "")
|
|
1350
1350
|
};
|
|
1351
|
-
}
|
|
1351
|
+
};
|
|
1352
1352
|
var rebuildTemplate = (parts, headContent, bodyContent) => {
|
|
1353
1353
|
return `${parts.beforeHead}${headContent}${parts.afterHead}${parts.beforeBody}${bodyContent}${parts.afterBody}`;
|
|
1354
1354
|
};
|
|
1355
|
+
var addNonceToInlineScripts = (html, nonce) => {
|
|
1356
|
+
if (!nonce) return html;
|
|
1357
|
+
return html.replace(/<script(?![^>]*\bnonce=)([^>]*)>/g, `<script nonce="${nonce}"$1>`);
|
|
1358
|
+
};
|
|
1359
|
+
var stripDevClientAndStyles = (template) => {
|
|
1360
|
+
return template.replace(/<script type="module" src="\/@vite\/client"><\/script>/g, "").replace(/<style type="text\/css">[\s\S]*?<\/style>/g, "");
|
|
1361
|
+
};
|
|
1362
|
+
var applyViteTransform = async (template, url, viteDevServer) => {
|
|
1363
|
+
return viteDevServer.transformIndexHtml(url, template);
|
|
1364
|
+
};
|
|
1365
|
+
var injectBootstrapModule = (template, bootstrapModule, nonce) => {
|
|
1366
|
+
if (!bootstrapModule) return template;
|
|
1367
|
+
const nonceAttr = nonce ? ` nonce="${nonce}"` : "";
|
|
1368
|
+
return template.replace("</body>", `<script${nonceAttr} type="module" src="${bootstrapModule}" defer></script></body>`);
|
|
1369
|
+
};
|
|
1370
|
+
var injectCssLink = (template, cssLink) => {
|
|
1371
|
+
if (!cssLink) return template;
|
|
1372
|
+
return template.replace("</head>", `${cssLink}</head>`);
|
|
1373
|
+
};
|
|
1374
|
+
var extractHeadInner = (html) => {
|
|
1375
|
+
const m = html.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
1376
|
+
return (m?.[1] ?? "").trim();
|
|
1377
|
+
};
|
|
1355
1378
|
|
|
1356
1379
|
// src/utils/AssetManager.ts
|
|
1357
1380
|
var createMaps = () => ({
|
|
@@ -1833,6 +1856,53 @@ function createRequestContext(req, reply, baseLogger) {
|
|
|
1833
1856
|
return { traceId, logger, headers };
|
|
1834
1857
|
}
|
|
1835
1858
|
|
|
1859
|
+
// src/utils/HandleNotFound.ts
|
|
1860
|
+
var handleNotFound = async (req, reply, processedConfigs, maps, opts = {}) => {
|
|
1861
|
+
const { viteDevServer } = opts;
|
|
1862
|
+
const logger = opts.logger ?? createLogger({
|
|
1863
|
+
debug: opts.debug,
|
|
1864
|
+
context: { component: "handle-not-found", url: req.url, method: req.method, traceId: req.id }
|
|
1865
|
+
});
|
|
1866
|
+
try {
|
|
1867
|
+
if (/\.\w+$/.test(req.raw.url ?? "")) {
|
|
1868
|
+
logger.debug?.("ssr", { url: req.raw.url }, "Delegating asset-like request to Fastify notFound handler");
|
|
1869
|
+
return reply.callNotFound();
|
|
1870
|
+
}
|
|
1871
|
+
const defaultConfig = processedConfigs[0];
|
|
1872
|
+
if (!defaultConfig) {
|
|
1873
|
+
logger.error?.({ configCount: processedConfigs.length, url: req.raw.url }, "No default configuration found");
|
|
1874
|
+
throw AppError.internal("No default configuration found", {
|
|
1875
|
+
details: { configCount: processedConfigs.length, url: req.raw.url }
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
const { clientRoot } = defaultConfig;
|
|
1879
|
+
const cspNonce = req.cspNonce ?? void 0;
|
|
1880
|
+
const template = ensureNonNull(maps.templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
|
|
1881
|
+
const cssLink = maps.cssLinks.get(clientRoot);
|
|
1882
|
+
const bootstrapModule = maps.bootstrapModules.get(clientRoot);
|
|
1883
|
+
let processedTemplate = template.replace(SSRTAG.ssrHead, "").replace(SSRTAG.ssrHtml, "");
|
|
1884
|
+
if (isDevelopment && viteDevServer) {
|
|
1885
|
+
processedTemplate = stripDevClientAndStyles(processedTemplate);
|
|
1886
|
+
const url = req.url ? new URL(req.url, `http://${req.headers.host}`).pathname : "/";
|
|
1887
|
+
processedTemplate = await applyViteTransform(processedTemplate, url, viteDevServer);
|
|
1888
|
+
if (cspNonce) processedTemplate = addNonceToInlineScripts(processedTemplate, cspNonce);
|
|
1889
|
+
} else if (!isDevelopment && cssLink) {
|
|
1890
|
+
processedTemplate = injectCssLink(processedTemplate, cssLink);
|
|
1891
|
+
}
|
|
1892
|
+
processedTemplate = injectBootstrapModule(processedTemplate, bootstrapModule, cspNonce);
|
|
1893
|
+
logger.debug?.("ssr", { status: 200 }, "Sending not-found fallback HTML");
|
|
1894
|
+
const result = reply.status(200).type("text/html").send(processedTemplate);
|
|
1895
|
+
return result;
|
|
1896
|
+
} catch (err) {
|
|
1897
|
+
logger.error?.({ error: err, url: req.url, clientRoot: processedConfigs[0]?.clientRoot }, "handleNotFound failed");
|
|
1898
|
+
throw AppError.internal("handleNotFound failed", err, {
|
|
1899
|
+
stage: "handleNotFound",
|
|
1900
|
+
url: req.url,
|
|
1901
|
+
clientRoot: processedConfigs[0]?.clientRoot
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
};
|
|
1905
|
+
|
|
1836
1906
|
// src/utils/HandleRender.ts
|
|
1837
1907
|
var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRegistry, maps, opts = {}) => {
|
|
1838
1908
|
const { viteDevServer } = opts;
|
|
@@ -1849,8 +1919,7 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
|
|
|
1849
1919
|
const rawNonce = req.cspNonce;
|
|
1850
1920
|
const cspNonce = rawNonce && rawNonce.length > 0 ? rawNonce : void 0;
|
|
1851
1921
|
if (!matchedRoute) {
|
|
1852
|
-
reply.callNotFound();
|
|
1853
|
-
return;
|
|
1922
|
+
return reply.callNotFound();
|
|
1854
1923
|
}
|
|
1855
1924
|
const { route, params } = matchedRoute;
|
|
1856
1925
|
const { attr, appId } = route;
|
|
@@ -1877,11 +1946,11 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
|
|
|
1877
1946
|
const manifest = maps.manifests.get(clientRoot);
|
|
1878
1947
|
const preloadLink = maps.preloadLinks.get(clientRoot);
|
|
1879
1948
|
const ssrManifest = maps.ssrManifests.get(clientRoot);
|
|
1949
|
+
let devHead = "";
|
|
1880
1950
|
let renderModule;
|
|
1881
1951
|
if (isDevelopment && viteDevServer) {
|
|
1882
1952
|
try {
|
|
1883
|
-
template = template
|
|
1884
|
-
template = template.replace(/<style type="text\/css">[\s\S]*?<\/style>/g, "");
|
|
1953
|
+
template = stripDevClientAndStyles(template);
|
|
1885
1954
|
const entryServerFile = resolveEntryFile(clientRoot, entryServer);
|
|
1886
1955
|
const entryServerPath = path5.join(clientRoot, entryServerFile);
|
|
1887
1956
|
const executedModule = await viteDevServer.ssrLoadModule(entryServerPath);
|
|
@@ -1889,7 +1958,16 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
|
|
|
1889
1958
|
const styles = await collectStyle(viteDevServer, [entryServerPath]);
|
|
1890
1959
|
const styleNonce = cspNonce ? ` nonce="${cspNonce}"` : "";
|
|
1891
1960
|
template = template?.replace("</head>", `<style type="text/css"${styleNonce}>${styles}</style></head>`);
|
|
1892
|
-
|
|
1961
|
+
const isStreaming = attr?.render === RENDERTYPE.streaming;
|
|
1962
|
+
if (isStreaming) {
|
|
1963
|
+
const stub = "<!doctype html><html><head></head><body></body></html>";
|
|
1964
|
+
const transformed = await viteDevServer.transformIndexHtml(url, stub);
|
|
1965
|
+
devHead = extractHeadInner(transformed);
|
|
1966
|
+
if (cspNonce) devHead = addNonceToInlineScripts(devHead, cspNonce);
|
|
1967
|
+
} else {
|
|
1968
|
+
template = await applyViteTransform(template, url, viteDevServer);
|
|
1969
|
+
if (cspNonce) template = addNonceToInlineScripts(template, cspNonce);
|
|
1970
|
+
}
|
|
1893
1971
|
} catch (error) {
|
|
1894
1972
|
throw AppError.internal("Failed to load dev assets", { cause: error, details: { clientRoot, entryServer, url } });
|
|
1895
1973
|
}
|
|
@@ -2031,7 +2109,9 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
|
|
|
2031
2109
|
writable,
|
|
2032
2110
|
{
|
|
2033
2111
|
onHead: (headContent) => {
|
|
2034
|
-
let aggregateHeadContent =
|
|
2112
|
+
let aggregateHeadContent = "";
|
|
2113
|
+
if (devHead) aggregateHeadContent += devHead;
|
|
2114
|
+
aggregateHeadContent += headContent;
|
|
2035
2115
|
if (ssrManifest && preloadLink) aggregateHeadContent += preloadLink;
|
|
2036
2116
|
if (manifest && cssLink) aggregateHeadContent += cssLink;
|
|
2037
2117
|
reply.raw.write(`${templateParts.beforeHead}${aggregateHeadContent}${templateParts.afterHead}${templateParts.beforeBody}`);
|
|
@@ -2106,60 +2186,6 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
|
|
|
2106
2186
|
}
|
|
2107
2187
|
};
|
|
2108
2188
|
|
|
2109
|
-
// src/utils/HandleNotFound.ts
|
|
2110
|
-
var handleNotFound = async (req, reply, processedConfigs, maps, opts = {}) => {
|
|
2111
|
-
const logger = opts.logger ?? createLogger({
|
|
2112
|
-
debug: opts.debug,
|
|
2113
|
-
context: { component: "handle-not-found", url: req.url, method: req.method, traceId: req.id }
|
|
2114
|
-
});
|
|
2115
|
-
try {
|
|
2116
|
-
if (/\.\w+$/.test(req.raw.url ?? "")) {
|
|
2117
|
-
logger.debug?.("ssr", { url: req.raw.url }, "Delegating asset-like request to Fastify notFound handler");
|
|
2118
|
-
return reply.callNotFound();
|
|
2119
|
-
}
|
|
2120
|
-
const defaultConfig = processedConfigs[0];
|
|
2121
|
-
if (!defaultConfig) {
|
|
2122
|
-
logger.error?.({ configCount: processedConfigs.length, url: req.raw.url }, "No default configuration found");
|
|
2123
|
-
throw AppError.internal("No default configuration found", {
|
|
2124
|
-
details: { configCount: processedConfigs.length, url: req.raw.url }
|
|
2125
|
-
});
|
|
2126
|
-
}
|
|
2127
|
-
const { clientRoot } = defaultConfig;
|
|
2128
|
-
const cspNonce = req.cspNonce ?? void 0;
|
|
2129
|
-
const template = ensureNonNull(maps.templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
|
|
2130
|
-
const cssLink = maps.cssLinks.get(clientRoot);
|
|
2131
|
-
const bootstrapModule = maps.bootstrapModules.get(clientRoot);
|
|
2132
|
-
logger.debug?.(
|
|
2133
|
-
"ssr",
|
|
2134
|
-
{
|
|
2135
|
-
clientRoot,
|
|
2136
|
-
hasCssLink: !!cssLink,
|
|
2137
|
-
hasBootstrapModule: !!bootstrapModule,
|
|
2138
|
-
isDevelopment,
|
|
2139
|
-
hasCspNonce: !!cspNonce
|
|
2140
|
-
},
|
|
2141
|
-
"Preparing not-found fallback HTML"
|
|
2142
|
-
);
|
|
2143
|
-
let processedTemplate = template.replace(SSRTAG.ssrHead, "").replace(SSRTAG.ssrHtml, "");
|
|
2144
|
-
if (!isDevelopment && cssLink) {
|
|
2145
|
-
processedTemplate = processedTemplate.replace("</head>", `${cssLink}</head>`);
|
|
2146
|
-
}
|
|
2147
|
-
if (bootstrapModule) {
|
|
2148
|
-
const nonceAttr = cspNonce ? ` nonce="${cspNonce}"` : "";
|
|
2149
|
-
processedTemplate = processedTemplate.replace("</body>", `<script${nonceAttr} type="module" src="${bootstrapModule}" defer></script></body>`);
|
|
2150
|
-
}
|
|
2151
|
-
logger.debug?.("ssr", { status: 200 }, "Sending not-found fallback HTML");
|
|
2152
|
-
return reply.status(200).type("text/html").send(processedTemplate);
|
|
2153
|
-
} catch (err) {
|
|
2154
|
-
logger.error?.({ error: err, url: req.url, clientRoot: processedConfigs[0]?.clientRoot }, "handleNotFound failed");
|
|
2155
|
-
throw AppError.internal("handleNotFound failed", err, {
|
|
2156
|
-
stage: "handleNotFound",
|
|
2157
|
-
url: req.url,
|
|
2158
|
-
clientRoot: processedConfigs[0]?.clientRoot
|
|
2159
|
-
});
|
|
2160
|
-
}
|
|
2161
|
-
};
|
|
2162
|
-
|
|
2163
2189
|
// src/utils/StaticAssets.ts
|
|
2164
2190
|
function normaliseStaticAssets(reg) {
|
|
2165
2191
|
if (!reg) return [];
|
|
@@ -2288,7 +2314,8 @@ var SSRServer = fp3(
|
|
|
2288
2314
|
},
|
|
2289
2315
|
{
|
|
2290
2316
|
debug: opts.debug,
|
|
2291
|
-
logger
|
|
2317
|
+
logger,
|
|
2318
|
+
viteDevServer
|
|
2292
2319
|
}
|
|
2293
2320
|
);
|
|
2294
2321
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taujs/server",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "τjs [ taujs ]",
|
|
5
5
|
"author": "John Smith | Aoede <taujs@aoede.uk.net> (https://www.aoede.uk.net)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"fastify": "^5.6.1",
|
|
49
49
|
"fastify-plugin": "^5.1.0",
|
|
50
50
|
"path-to-regexp": "^8.1.0",
|
|
51
|
-
"vite": "^7.1
|
|
51
|
+
"vite": "^7.3.1"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@arethetypeswrong/cli": "^0.15.4",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"fastify": "^5.6.1",
|
|
68
68
|
"typescript": "^5.5.4",
|
|
69
|
-
"vite": "^7.1
|
|
69
|
+
"vite": "^7.3.1"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsup",
|