@jay-framework/production-server 0.23.0 → 0.24.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/index.d.ts +10 -3
- package/dist/index.js +146 -92
- package/dist/{init-services-AtDV4X1i.js → init-services-Dy2SiHzw.js} +31 -50
- package/dist/{serve-index-XSavezh8.d.ts → serve-index-cRXZm8vQ.d.ts} +5 -1
- package/dist/serve-index.d.ts +1 -1
- package/dist/serve-index.js +8 -18
- package/package.json +12 -12
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { B as BuildOptions, R as RouteManifest, a as RouteEntry } from './serve-index-
|
|
2
|
-
export { A as ActionEntry,
|
|
1
|
+
import { B as BuildOptions, R as RouteManifest, a as RouteEntry } from './serve-index-cRXZm8vQ.js';
|
|
2
|
+
export { A as ActionEntry, b as ArtifactStore, c as BuildMetadata, C as CacheEntry, F as FilesystemArtifactStore, I as InstanceEntry, M as MatchResult, P as PageModule, d as PluginEntry, e as PreImportedPlugin, f as RouteSegment, S as ServerElementModule, g as fetchActionRequest, h as fetchPageRequest, i as fetchStaticFile, j as initializeServices, k as initializeServicesFromModules, l as isActionRequest, m as matchRequest, r as registerActionsFromManifest, n as registerActionsFromModules } from './serve-index-cRXZm8vQ.js';
|
|
3
3
|
import '@jay-framework/ssr-runtime';
|
|
4
4
|
import '@jay-framework/compiler-shared';
|
|
5
5
|
import '@jay-framework/stack-server-runtime';
|
|
6
6
|
|
|
7
7
|
declare function buildVersion(options: BuildOptions): Promise<RouteManifest>;
|
|
8
8
|
|
|
9
|
+
declare function generateSitemap(manifest: RouteManifest, baseUrl: string, outputPath: string): Promise<number>;
|
|
10
|
+
|
|
9
11
|
interface MainServerOptions {
|
|
10
12
|
buildRoot: string;
|
|
11
13
|
version: string;
|
|
@@ -24,6 +26,8 @@ interface RendererServerOptions {
|
|
|
24
26
|
pagesRoot: string;
|
|
25
27
|
tsConfigFilePath?: string;
|
|
26
28
|
minify?: boolean;
|
|
29
|
+
/** Site base URL for sitemap regeneration on rebuild (e.g. "https://example.com"). */
|
|
30
|
+
siteBaseUrl?: string;
|
|
27
31
|
}
|
|
28
32
|
declare function startRendererServer(options: RendererServerOptions): Promise<void>;
|
|
29
33
|
|
|
@@ -47,6 +51,8 @@ interface RebuildOptions {
|
|
|
47
51
|
target: RebuildTarget;
|
|
48
52
|
tsConfigFilePath?: string;
|
|
49
53
|
minify?: boolean;
|
|
54
|
+
/** Site base URL for sitemap regeneration (e.g. "https://example.com"). */
|
|
55
|
+
siteBaseUrl?: string;
|
|
50
56
|
}
|
|
51
57
|
interface RebuildResult {
|
|
52
58
|
affected: number;
|
|
@@ -69,7 +75,8 @@ declare function rebuildContract(options: {
|
|
|
69
75
|
params?: Record<string, string>;
|
|
70
76
|
tsConfigFilePath?: string;
|
|
71
77
|
minify?: boolean;
|
|
78
|
+
siteBaseUrl?: string;
|
|
72
79
|
}): Promise<RebuildResult>;
|
|
73
80
|
declare function cleanupOrphanedFiles(buildRoot: string, version: string): Promise<number>;
|
|
74
81
|
|
|
75
|
-
export { BuildOptions, type RebuildOptions, type RebuildResult, type RebuildTarget, type RendererServerOptions, RouteEntry, RouteManifest, buildVersion, cleanupOrphanedFiles, rebuild, rebuildContract, resolveContractToRoutes, startMainServer, startRendererServer };
|
|
82
|
+
export { BuildOptions, type RebuildOptions, type RebuildResult, type RebuildTarget, type RendererServerOptions, RouteEntry, RouteManifest, buildVersion, cleanupOrphanedFiles, generateSitemap, rebuild, rebuildContract, resolveContractToRoutes, startMainServer, startRendererServer };
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,8 @@ import path from "node:path";
|
|
|
6
6
|
import fs from "node:fs/promises";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import { DevSlowlyChangingPhase, slowRenderInstances, scanPlugins, runLoadParams, parseCookies } from "@jay-framework/stack-server-runtime";
|
|
9
|
-
import { l as loadProductionPageParts, g as buildPagePartsConfig,
|
|
10
|
-
import {
|
|
9
|
+
import { l as loadProductionPageParts, g as buildPagePartsConfig, F as FilesystemArtifactStore, i as initializeServices, r as registerActionsFromManifest, d as isActionRequest, f as fetchActionRequest, b as fetchStaticFile, m as matchRequest, a as fetchPageRequest } from "./init-services-Dy2SiHzw.js";
|
|
10
|
+
import { c, e } from "./init-services-Dy2SiHzw.js";
|
|
11
11
|
import crypto, { createHash } from "node:crypto";
|
|
12
12
|
import fs$1 from "node:fs";
|
|
13
13
|
import { jayRuntime } from "@jay-framework/vite-plugin";
|
|
@@ -18,8 +18,27 @@ import { transform } from "esbuild";
|
|
|
18
18
|
import http from "node:http";
|
|
19
19
|
import { Readable } from "node:stream";
|
|
20
20
|
import { isJayWebhook } from "@jay-framework/fullstack-component";
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
function isCompilableTypeScriptFile(fileName) {
|
|
22
|
+
return fileName.endsWith(".ts") && !fileName.endsWith(".d.ts") && fileName !== "page.ts";
|
|
23
|
+
}
|
|
24
|
+
async function collectTypeScriptEntries(rootDir, entryPrefix, pages) {
|
|
25
|
+
async function walk(currentDir, relativePath) {
|
|
26
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
29
|
+
if (entry.isDirectory()) {
|
|
30
|
+
const nextRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
31
|
+
await walk(fullPath, nextRelative);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (!isCompilableTypeScriptFile(entry.name)) continue;
|
|
35
|
+
const stem = entry.name.replace(/\.ts$/, "");
|
|
36
|
+
const entryName = relativePath ? `${entryPrefix}/${relativePath}/${stem}` : `${entryPrefix}/${stem}`;
|
|
37
|
+
pages[entryName] = fullPath;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
await walk(rootDir, "");
|
|
41
|
+
}
|
|
23
42
|
async function discoverServerEntries(projectRoot, pagesRoot) {
|
|
24
43
|
const logger = getLogger();
|
|
25
44
|
const routes = await scanRoutes(pagesRoot, {
|
|
@@ -49,18 +68,16 @@ async function discoverServerEntries(projectRoot, pagesRoot) {
|
|
|
49
68
|
for (const subDir of ["plugins", "components"]) {
|
|
50
69
|
const scanDir = path.join(projectRoot, "src", subDir);
|
|
51
70
|
try {
|
|
52
|
-
const
|
|
53
|
-
for (const
|
|
54
|
-
|
|
71
|
+
const entries2 = await fs.readdir(scanDir, { withFileTypes: true });
|
|
72
|
+
for (const entry of entries2) {
|
|
73
|
+
const entryPath = path.join(scanDir, entry.name);
|
|
74
|
+
if (entry.isDirectory()) {
|
|
75
|
+
await collectTypeScriptEntries(entryPath, `${subDir}/${entry.name}`, pages);
|
|
55
76
|
continue;
|
|
56
|
-
const dirPath = path.join(scanDir, dir.name);
|
|
57
|
-
const files = await fs.readdir(dirPath);
|
|
58
|
-
for (const file of files) {
|
|
59
|
-
if (file.endsWith(".ts") && !file.endsWith(".d.ts") && file !== "page.ts") {
|
|
60
|
-
const entryName = `${subDir}/${dir.name}/${file.replace(/\.ts$/, "")}`;
|
|
61
|
-
pages[entryName] = path.join(dirPath, file);
|
|
62
|
-
}
|
|
63
77
|
}
|
|
78
|
+
if (!isCompilableTypeScriptFile(entry.name)) continue;
|
|
79
|
+
const stem = entry.name.replace(/\.ts$/, "");
|
|
80
|
+
pages[`${subDir}/${stem}`] = entryPath;
|
|
64
81
|
}
|
|
65
82
|
} catch {
|
|
66
83
|
}
|
|
@@ -194,8 +211,7 @@ async function parseViteManifest(outputDir, packages) {
|
|
|
194
211
|
}
|
|
195
212
|
const manifest = {};
|
|
196
213
|
for (const [, entry] of Object.entries(raw)) {
|
|
197
|
-
if (!entry.isEntry)
|
|
198
|
-
continue;
|
|
214
|
+
if (!entry.isEntry) continue;
|
|
199
215
|
const outputBase = path.basename(entry.file, ".js");
|
|
200
216
|
for (const [varName, pkg] of varNameToPackage) {
|
|
201
217
|
if (outputBase.startsWith(varName)) {
|
|
@@ -218,8 +234,7 @@ function hashParams(params, suffix) {
|
|
|
218
234
|
{}
|
|
219
235
|
);
|
|
220
236
|
const json = JSON.stringify(sorted);
|
|
221
|
-
if (json === "{}" && !suffix)
|
|
222
|
-
return "";
|
|
237
|
+
if (json === "{}" && !suffix) return "";
|
|
223
238
|
const input = suffix ? json + ":" + suffix : json;
|
|
224
239
|
return "_" + crypto.createHash("md5").update(input).digest("hex").substring(0, 8);
|
|
225
240
|
}
|
|
@@ -245,7 +260,7 @@ async function buildInstance(route, params, pageModule, ctx, routeServerElementP
|
|
|
245
260
|
);
|
|
246
261
|
const contracts = [
|
|
247
262
|
.../* @__PURE__ */ new Set([
|
|
248
|
-
...pageParts.headlessInstanceComponents.map((
|
|
263
|
+
...pageParts.headlessInstanceComponents.map((c2) => c2.contractName),
|
|
249
264
|
...pageParts.parts.filter((p) => p.contractInfo?.contractName).map((p) => p.contractInfo.contractName)
|
|
250
265
|
])
|
|
251
266
|
];
|
|
@@ -401,8 +416,7 @@ async function discoverActions(actionPaths, serverOutputDir, buildDir, projectRo
|
|
|
401
416
|
try {
|
|
402
417
|
const scannedPlugins = await scanPlugins({ projectRoot });
|
|
403
418
|
for (const [packageName, plugin] of scannedPlugins) {
|
|
404
|
-
if (plugin.isLocal)
|
|
405
|
-
continue;
|
|
419
|
+
if (plugin.isLocal) continue;
|
|
406
420
|
plugins.push({ name: plugin.manifest.name, packageName });
|
|
407
421
|
const pluginActions = plugin.manifest.actions;
|
|
408
422
|
if (pluginActions && pluginActions.length > 0) {
|
|
@@ -431,6 +445,47 @@ async function writeRouteManifest(manifest, buildDir) {
|
|
|
431
445
|
`[Build] Route manifest written: ${manifest.routes.length} routes, ${manifest.routes.reduce((n, r) => n + r.instances.length, 0)} instances`
|
|
432
446
|
);
|
|
433
447
|
}
|
|
448
|
+
async function generateSitemap(manifest, baseUrl, outputPath) {
|
|
449
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
450
|
+
const urls = [];
|
|
451
|
+
for (const route of manifest.routes) {
|
|
452
|
+
if (route.devOnly) continue;
|
|
453
|
+
if (route.noIndex) continue;
|
|
454
|
+
if (route.instances.length === 0) {
|
|
455
|
+
const hasDynamic = route.segments.some((s) => s.type !== "static");
|
|
456
|
+
if (!hasDynamic) {
|
|
457
|
+
const urlPath = route.pattern === "/" ? "/" : route.pattern;
|
|
458
|
+
urls.push(`${base}${urlPath}`);
|
|
459
|
+
}
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
for (const instance of route.instances) {
|
|
463
|
+
const urlPath = buildUrlFromManifest(route.pattern, instance.params);
|
|
464
|
+
urls.push(`${base}${urlPath}`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
const tmpPath = outputPath + ".tmp";
|
|
468
|
+
const handle = await fs.open(tmpPath, "w");
|
|
469
|
+
try {
|
|
470
|
+
await handle.write('<?xml version="1.0" encoding="UTF-8"?>\n');
|
|
471
|
+
await handle.write('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n');
|
|
472
|
+
for (const url of urls) {
|
|
473
|
+
await handle.write(` <url><loc>${escapeXml(url)}</loc></url>
|
|
474
|
+
`);
|
|
475
|
+
}
|
|
476
|
+
await handle.write("</urlset>\n");
|
|
477
|
+
} finally {
|
|
478
|
+
await handle.close();
|
|
479
|
+
}
|
|
480
|
+
await fs.rename(tmpPath, outputPath);
|
|
481
|
+
return urls.length;
|
|
482
|
+
}
|
|
483
|
+
function buildUrlFromManifest(pattern, params) {
|
|
484
|
+
return pattern.replace(/\[\[(\w+)\]\]/g, (_, name) => params[name] || "").replace(/\[\.\.\.(\w+)\]/g, (_, name) => params[name] || "").replace(/\[(\w+)\]/g, (_, name) => params[name] || "").replace(/\/\/+/g, "/").replace(/\/$/, "") || "/";
|
|
485
|
+
}
|
|
486
|
+
function escapeXml(str) {
|
|
487
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
488
|
+
}
|
|
434
489
|
createRequire(import.meta.url);
|
|
435
490
|
async function scanPluginRoutes(projectRoot, projectRoutes) {
|
|
436
491
|
const logger = getLogger();
|
|
@@ -438,10 +493,8 @@ async function scanPluginRoutes(projectRoot, projectRoutes) {
|
|
|
438
493
|
const projectPaths = new Set(projectRoutes.map((r) => r.rawRoute));
|
|
439
494
|
const pluginRoutes = [];
|
|
440
495
|
for (const [, plugin] of plugins) {
|
|
441
|
-
if (plugin.isLocal)
|
|
442
|
-
|
|
443
|
-
if (!plugin.manifest.routes)
|
|
444
|
-
continue;
|
|
496
|
+
if (plugin.isLocal) continue;
|
|
497
|
+
if (!plugin.manifest.routes) continue;
|
|
445
498
|
for (const route of plugin.manifest.routes) {
|
|
446
499
|
if (projectPaths.has(route.path)) {
|
|
447
500
|
logger.info(
|
|
@@ -484,8 +537,7 @@ function resolvePluginExport(pluginPath, exportSubpath) {
|
|
|
484
537
|
const exportValue = packageJson.exports[exportKey];
|
|
485
538
|
if (exportValue) {
|
|
486
539
|
const resolved = typeof exportValue === "string" ? exportValue : exportValue.default || exportValue.import || exportValue.require;
|
|
487
|
-
if (resolved)
|
|
488
|
-
return path.join(pluginPath, resolved);
|
|
540
|
+
if (resolved) return path.join(pluginPath, resolved);
|
|
489
541
|
}
|
|
490
542
|
}
|
|
491
543
|
} catch {
|
|
@@ -508,8 +560,7 @@ function resolvePluginModule(pluginPath) {
|
|
|
508
560
|
const mainPath = typeof mainExport === "string" ? mainExport : mainExport?.default || mainExport?.import || pkg.main;
|
|
509
561
|
if (mainPath) {
|
|
510
562
|
const resolved = path.join(pluginPath, mainPath);
|
|
511
|
-
if (fs$1.existsSync(resolved))
|
|
512
|
-
return resolved;
|
|
563
|
+
if (fs$1.existsSync(resolved)) return resolved;
|
|
513
564
|
}
|
|
514
565
|
} catch {
|
|
515
566
|
}
|
|
@@ -633,8 +684,7 @@ async function compileRouteHydrateScript(jayHtmlPath, outputDir, projectRoot, ts
|
|
|
633
684
|
const manifest = JSON.parse(await fs.readFile(manifestPath, "utf-8"));
|
|
634
685
|
await fs.rm(manifestPath, { force: true });
|
|
635
686
|
const entryKey = Object.keys(manifest).find((k) => manifest[k].isEntry);
|
|
636
|
-
if (!entryKey)
|
|
637
|
-
throw new Error("No entry in route hydrate manifest");
|
|
687
|
+
if (!entryKey) throw new Error("No entry in route hydrate manifest");
|
|
638
688
|
const jsFile = manifest[entryKey].file;
|
|
639
689
|
getLogger().info(`[Build] Compiled route hydrate script: ${jsFile}`);
|
|
640
690
|
return { jsFile };
|
|
@@ -649,8 +699,7 @@ function resolveJayHtmlPaths(html, sourceDir, targetDir) {
|
|
|
649
699
|
if (val && (val.startsWith("./") || val.startsWith("../"))) {
|
|
650
700
|
const abs = path.resolve(sourceDir, val);
|
|
651
701
|
let rel = path.relative(targetDir, abs);
|
|
652
|
-
if (!rel.startsWith("."))
|
|
653
|
-
rel = "./" + rel;
|
|
702
|
+
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
654
703
|
el.setAttribute(attr, rel);
|
|
655
704
|
}
|
|
656
705
|
};
|
|
@@ -781,10 +830,8 @@ async function buildInstanceClient(hydrateEntryPath, instanceId, outputDir, proj
|
|
|
781
830
|
return result;
|
|
782
831
|
}
|
|
783
832
|
function crossProductParams(parts) {
|
|
784
|
-
if (parts.length === 0)
|
|
785
|
-
|
|
786
|
-
if (parts.length === 1)
|
|
787
|
-
return parts[0].values;
|
|
833
|
+
if (parts.length === 0) return [];
|
|
834
|
+
if (parts.length === 1) return parts[0].values;
|
|
788
835
|
const logger = getLogger();
|
|
789
836
|
for (let i = 0; i < parts.length; i++) {
|
|
790
837
|
for (let j = i + 1; j < parts.length; j++) {
|
|
@@ -802,8 +849,8 @@ function crossProductParams(parts) {
|
|
|
802
849
|
const next = parts[i].values;
|
|
803
850
|
const combined = [];
|
|
804
851
|
for (const a of result) {
|
|
805
|
-
for (const
|
|
806
|
-
combined.push({ ...a, ...
|
|
852
|
+
for (const b of next) {
|
|
853
|
+
combined.push({ ...a, ...b });
|
|
807
854
|
}
|
|
808
855
|
}
|
|
809
856
|
result = combined;
|
|
@@ -812,8 +859,7 @@ function crossProductParams(parts) {
|
|
|
812
859
|
}
|
|
813
860
|
function paramsMatchInferred(params, inferredParams, optionalSegments) {
|
|
814
861
|
return Object.entries(inferredParams).every(([k, v]) => {
|
|
815
|
-
if (optionalSegments?.has(k))
|
|
816
|
-
return true;
|
|
862
|
+
if (optionalSegments?.has(k)) return true;
|
|
817
863
|
return params[k] === v;
|
|
818
864
|
});
|
|
819
865
|
}
|
|
@@ -826,10 +872,8 @@ function computeSpecificity(route) {
|
|
|
826
872
|
function buildUrl(route, params) {
|
|
827
873
|
return route.rawRoute.replace(/\[\[(\w+)\]\]/g, (_, name) => {
|
|
828
874
|
const value = params[name];
|
|
829
|
-
if (!value)
|
|
830
|
-
|
|
831
|
-
if (route.inferredParams?.[name] === value)
|
|
832
|
-
return "";
|
|
875
|
+
if (!value) return "";
|
|
876
|
+
if (route.inferredParams?.[name] === value) return "";
|
|
833
877
|
return value;
|
|
834
878
|
}).replace(/\[(\w+)\]/g, (_, name) => params[name] || "").replace(/\/\/+/g, "/").replace(/\/$/, "") || "/";
|
|
835
879
|
}
|
|
@@ -886,8 +930,7 @@ async function discoverPluginClientPackages(projectRoot) {
|
|
|
886
930
|
const seen = /* @__PURE__ */ new Set();
|
|
887
931
|
const result = [];
|
|
888
932
|
async function walk(pkgName) {
|
|
889
|
-
if (seen.has(pkgName))
|
|
890
|
-
return;
|
|
933
|
+
if (seen.has(pkgName)) return;
|
|
891
934
|
seen.add(pkgName);
|
|
892
935
|
try {
|
|
893
936
|
const mainPath = projectRequire.resolve(pkgName);
|
|
@@ -991,7 +1034,19 @@ async function buildVersion(options) {
|
|
|
991
1034
|
);
|
|
992
1035
|
for (const pluginInit of pluginsWithInit) {
|
|
993
1036
|
try {
|
|
994
|
-
|
|
1037
|
+
let modulePath;
|
|
1038
|
+
if (pluginInit.isLocal) {
|
|
1039
|
+
const pluginDirName = path.basename(pluginInit.pluginPath);
|
|
1040
|
+
modulePath = path.join(
|
|
1041
|
+
serverOutputDir,
|
|
1042
|
+
"plugins",
|
|
1043
|
+
pluginDirName,
|
|
1044
|
+
`${pluginInit.initModule}.js`
|
|
1045
|
+
);
|
|
1046
|
+
} else {
|
|
1047
|
+
modulePath = pluginInit.packageName;
|
|
1048
|
+
}
|
|
1049
|
+
const pluginModule = await import(modulePath);
|
|
995
1050
|
const init = pluginModule.init || pluginModule[pluginInit.initExport || "init"];
|
|
996
1051
|
if (init?._serverInit) {
|
|
997
1052
|
logger.info(`[Build] Running plugin init: ${pluginInit.name}`);
|
|
@@ -1023,8 +1078,7 @@ async function buildVersion(options) {
|
|
|
1023
1078
|
await discoverPluginsWithInit({ projectRoot: options.projectRoot })
|
|
1024
1079
|
);
|
|
1025
1080
|
for (const pluginInit of allPluginsWithInit) {
|
|
1026
|
-
if (pluginInit.isLocal)
|
|
1027
|
-
continue;
|
|
1081
|
+
if (pluginInit.isLocal) continue;
|
|
1028
1082
|
const clientImportPath = `${pluginInit.packageName}/client`;
|
|
1029
1083
|
try {
|
|
1030
1084
|
const clientModule = await import(clientImportPath);
|
|
@@ -1089,10 +1143,8 @@ async function buildVersion(options) {
|
|
|
1089
1143
|
logger.important(`[Build] ${instanceCount}/${totalExpected} ${routeName}${paramStr}`);
|
|
1090
1144
|
}
|
|
1091
1145
|
async function loadPageModule(entry) {
|
|
1092
|
-
if (!entry.serverModule)
|
|
1093
|
-
|
|
1094
|
-
if (entry.isPlugin)
|
|
1095
|
-
return import(entry.serverModule);
|
|
1146
|
+
if (!entry.serverModule) return {};
|
|
1147
|
+
if (entry.isPlugin) return import(entry.serverModule);
|
|
1096
1148
|
return import(path.join(backendDir, entry.serverModule));
|
|
1097
1149
|
}
|
|
1098
1150
|
const routeInfos = routeEntries.map((re) => {
|
|
@@ -1108,8 +1160,7 @@ async function buildVersion(options) {
|
|
|
1108
1160
|
const loadParamsCache = /* @__PURE__ */ new Map();
|
|
1109
1161
|
const loadParamsResults = /* @__PURE__ */ new Map();
|
|
1110
1162
|
for (const info of routeInfos) {
|
|
1111
|
-
if (!info.hasDynamicParams)
|
|
1112
|
-
continue;
|
|
1163
|
+
if (!info.hasDynamicParams) continue;
|
|
1113
1164
|
const { route, entry } = info.routeEntry;
|
|
1114
1165
|
let pageModule;
|
|
1115
1166
|
try {
|
|
@@ -1127,8 +1178,7 @@ async function buildVersion(options) {
|
|
|
1127
1178
|
serverOutputDir
|
|
1128
1179
|
);
|
|
1129
1180
|
const partsWithLoadParams = pageParts.parts.filter((p) => p.compDefinition?.loadParams);
|
|
1130
|
-
if (partsWithLoadParams.length === 0)
|
|
1131
|
-
continue;
|
|
1181
|
+
if (partsWithLoadParams.length === 0) continue;
|
|
1132
1182
|
const paramParts = [];
|
|
1133
1183
|
for (const part of partsWithLoadParams) {
|
|
1134
1184
|
const propsKey = JSON.stringify(part.headlessProps ?? {});
|
|
@@ -1158,14 +1208,12 @@ async function buildVersion(options) {
|
|
|
1158
1208
|
const byRoute = /* @__PURE__ */ new Map();
|
|
1159
1209
|
for (const materialized2 of deduped) {
|
|
1160
1210
|
const info = materialized2.route;
|
|
1161
|
-
if (!byRoute.has(info))
|
|
1162
|
-
byRoute.set(info, []);
|
|
1211
|
+
if (!byRoute.has(info)) byRoute.set(info, []);
|
|
1163
1212
|
byRoute.get(info).push(materialized2.params);
|
|
1164
1213
|
}
|
|
1165
1214
|
for (const [info] of byRoute) {
|
|
1166
1215
|
const { route, entry } = info.routeEntry;
|
|
1167
|
-
if (!route.jayHtmlPath)
|
|
1168
|
-
continue;
|
|
1216
|
+
if (!route.jayHtmlPath) continue;
|
|
1169
1217
|
const routeDir = route.rawRoute.replace(/^\//, "") || "index";
|
|
1170
1218
|
const frontendSafeRouteDir = routeDir.replace(/\[/g, "%5B").replace(/\]/g, "%5D");
|
|
1171
1219
|
const backendRouteDir = path.join(backendDir, "pre-rendered", routeDir);
|
|
@@ -1198,6 +1246,12 @@ async function buildVersion(options) {
|
|
|
1198
1246
|
}
|
|
1199
1247
|
if (seResult.headMeta) {
|
|
1200
1248
|
entry.headMeta = seResult.headMeta;
|
|
1249
|
+
const robotsMeta = seResult.headMeta.meta?.find(
|
|
1250
|
+
(m) => m.name === "robots" && m.content?.some((p) => p.kind === "static" && p.value.includes("noindex"))
|
|
1251
|
+
);
|
|
1252
|
+
if (robotsMeta) {
|
|
1253
|
+
entry.noIndex = true;
|
|
1254
|
+
}
|
|
1201
1255
|
}
|
|
1202
1256
|
logger.important(`[Build] Route server element: ${routeDir}`);
|
|
1203
1257
|
} catch (err) {
|
|
@@ -1333,6 +1387,11 @@ async function buildVersion(options) {
|
|
|
1333
1387
|
logger.info("[Build] Copied public/ contents to frontend/");
|
|
1334
1388
|
} catch {
|
|
1335
1389
|
}
|
|
1390
|
+
if (options.siteBaseUrl) {
|
|
1391
|
+
const sitemapPath = path.join(frontendDir, "sitemap.xml");
|
|
1392
|
+
const urlCount = await generateSitemap(manifest, options.siteBaseUrl, sitemapPath);
|
|
1393
|
+
logger.important(`[Build] Sitemap generated: ${urlCount} URLs`);
|
|
1394
|
+
}
|
|
1336
1395
|
const sourceHash = await computeBuildHash(buildDir);
|
|
1337
1396
|
const metadata = {
|
|
1338
1397
|
version: options.version,
|
|
@@ -1354,8 +1413,7 @@ function toFetchRequest(req) {
|
|
|
1354
1413
|
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
1355
1414
|
const headers = new Headers();
|
|
1356
1415
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
1357
|
-
if (value)
|
|
1358
|
-
headers.set(key, Array.isArray(value) ? value.join(", ") : value);
|
|
1416
|
+
if (value) headers.set(key, Array.isArray(value) ? value.join(", ") : value);
|
|
1359
1417
|
}
|
|
1360
1418
|
const init = { method: req.method, headers };
|
|
1361
1419
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
@@ -1375,8 +1433,7 @@ async function pipeFetchResponse(response, res) {
|
|
|
1375
1433
|
try {
|
|
1376
1434
|
while (true) {
|
|
1377
1435
|
const { done, value } = await reader.read();
|
|
1378
|
-
if (done)
|
|
1379
|
-
break;
|
|
1436
|
+
if (done) break;
|
|
1380
1437
|
res.write(value);
|
|
1381
1438
|
}
|
|
1382
1439
|
} finally {
|
|
@@ -1456,8 +1513,7 @@ async function startMainServer(options) {
|
|
|
1456
1513
|
await pipeFetchResponse(response, res);
|
|
1457
1514
|
} catch (err) {
|
|
1458
1515
|
logger.error(`[Server] Error handling ${url.pathname}: ${err.message}`);
|
|
1459
|
-
if (err.stack)
|
|
1460
|
-
logger.error(err.stack);
|
|
1516
|
+
if (err.stack) logger.error(err.stack);
|
|
1461
1517
|
if (!res.headersSent) {
|
|
1462
1518
|
res.writeHead(500);
|
|
1463
1519
|
res.end("Internal Server Error");
|
|
@@ -1483,11 +1539,9 @@ async function discoverWebhooks(projectRoot, serverBuildDir) {
|
|
|
1483
1539
|
try {
|
|
1484
1540
|
const plugins = await scanPlugins({ projectRoot });
|
|
1485
1541
|
for (const [packageName, plugin] of plugins) {
|
|
1486
|
-
if (plugin.isLocal)
|
|
1487
|
-
continue;
|
|
1542
|
+
if (plugin.isLocal) continue;
|
|
1488
1543
|
const declaredWebhooks = plugin.manifest.webhooks;
|
|
1489
|
-
if (!declaredWebhooks || declaredWebhooks.length === 0)
|
|
1490
|
-
continue;
|
|
1544
|
+
if (!declaredWebhooks || declaredWebhooks.length === 0) continue;
|
|
1491
1545
|
try {
|
|
1492
1546
|
const pluginModule = await import(packageName);
|
|
1493
1547
|
for (const entry of declaredWebhooks) {
|
|
@@ -1519,11 +1573,9 @@ async function discoverWebhooks(projectRoot, serverBuildDir) {
|
|
|
1519
1573
|
try {
|
|
1520
1574
|
const plugins = await scanPlugins({ projectRoot });
|
|
1521
1575
|
for (const [, plugin] of plugins) {
|
|
1522
|
-
if (!plugin.isLocal)
|
|
1523
|
-
continue;
|
|
1576
|
+
if (!plugin.isLocal) continue;
|
|
1524
1577
|
const declaredWebhooks = plugin.manifest.webhooks;
|
|
1525
|
-
if (!declaredWebhooks || declaredWebhooks.length === 0)
|
|
1526
|
-
continue;
|
|
1578
|
+
if (!declaredWebhooks || declaredWebhooks.length === 0) continue;
|
|
1527
1579
|
const pluginDirName = path.basename(plugin.pluginPath);
|
|
1528
1580
|
for (const entry of declaredWebhooks) {
|
|
1529
1581
|
const exportName = typeof entry === "string" ? entry : entry.name;
|
|
@@ -1554,8 +1606,7 @@ async function discoverWebhooks(projectRoot, serverBuildDir) {
|
|
|
1554
1606
|
try {
|
|
1555
1607
|
const files = await fs.readdir(webhooksDir);
|
|
1556
1608
|
for (const file of files) {
|
|
1557
|
-
if (!file.endsWith(".js"))
|
|
1558
|
-
continue;
|
|
1609
|
+
if (!file.endsWith(".js")) continue;
|
|
1559
1610
|
try {
|
|
1560
1611
|
const mod = await import(path.join(webhooksDir, file));
|
|
1561
1612
|
for (const [, value] of Object.entries(mod)) {
|
|
@@ -1690,6 +1741,11 @@ async function rebuild(options) {
|
|
|
1690
1741
|
);
|
|
1691
1742
|
}
|
|
1692
1743
|
logger.important(`[Rebuild] Manifest and metadata updated`);
|
|
1744
|
+
if (options.siteBaseUrl) {
|
|
1745
|
+
const sitemapPath = path.join(frontendDir, "sitemap.xml");
|
|
1746
|
+
const urlCount = await generateSitemap(manifest, options.siteBaseUrl, sitemapPath);
|
|
1747
|
+
logger.info(`[Rebuild] Sitemap regenerated: ${urlCount} URLs`);
|
|
1748
|
+
}
|
|
1693
1749
|
if (orphanedFiles.length > 0) {
|
|
1694
1750
|
await appendCleanupManifest(buildDir, orphanedFiles);
|
|
1695
1751
|
logger.info(`[Rebuild] ${orphanedFiles.length} orphaned file(s) queued for cleanup`);
|
|
@@ -1738,10 +1794,8 @@ async function rebuildContract(options) {
|
|
|
1738
1794
|
});
|
|
1739
1795
|
}
|
|
1740
1796
|
async function loadRouteModule(route, buildDir) {
|
|
1741
|
-
if (!route.serverModule)
|
|
1742
|
-
|
|
1743
|
-
if (route.isPlugin)
|
|
1744
|
-
return import(route.serverModule);
|
|
1797
|
+
if (!route.serverModule) return {};
|
|
1798
|
+
if (route.isPlugin) return import(route.serverModule);
|
|
1745
1799
|
return import(path.join(buildDir, route.serverModule));
|
|
1746
1800
|
}
|
|
1747
1801
|
async function resolveJayRouteFromManifest(route, options) {
|
|
@@ -1761,8 +1815,7 @@ async function resolveJayRouteFromManifest(route, options) {
|
|
|
1761
1815
|
return {
|
|
1762
1816
|
rawRoute: route.pattern,
|
|
1763
1817
|
segments: route.segments.map((s) => {
|
|
1764
|
-
if (s.type === "static")
|
|
1765
|
-
return s.value;
|
|
1818
|
+
if (s.type === "static") return s.value;
|
|
1766
1819
|
return { name: s.value, type: segmentTypeMap[s.type] };
|
|
1767
1820
|
}),
|
|
1768
1821
|
jayHtmlPath: resolvedJayHtmlPath,
|
|
@@ -1779,11 +1832,9 @@ function paramsMatch(instanceParams, targetParams) {
|
|
|
1779
1832
|
return Object.entries(targetParams).every(([key, value]) => instanceParams[key] === value);
|
|
1780
1833
|
}
|
|
1781
1834
|
function collectInstanceFiles(instance) {
|
|
1782
|
-
if (!instance.cachePath)
|
|
1783
|
-
return [];
|
|
1835
|
+
if (!instance.cachePath) return [];
|
|
1784
1836
|
const files = [instance.cachePath, instance.serverElementPath, instance.clientBundlePath];
|
|
1785
|
-
if (instance.clientCssPath)
|
|
1786
|
-
files.push(instance.clientCssPath);
|
|
1837
|
+
if (instance.clientCssPath) files.push(instance.clientCssPath);
|
|
1787
1838
|
return files.filter(Boolean);
|
|
1788
1839
|
}
|
|
1789
1840
|
async function appendCleanupManifest(buildDir, files) {
|
|
@@ -1843,7 +1894,8 @@ async function startRendererServer(options) {
|
|
|
1843
1894
|
contractName,
|
|
1844
1895
|
params,
|
|
1845
1896
|
tsConfigFilePath: options.tsConfigFilePath,
|
|
1846
|
-
minify: options.minify
|
|
1897
|
+
minify: options.minify,
|
|
1898
|
+
siteBaseUrl: options.siteBaseUrl
|
|
1847
1899
|
});
|
|
1848
1900
|
};
|
|
1849
1901
|
};
|
|
@@ -1902,7 +1954,8 @@ async function startRendererServer(options) {
|
|
|
1902
1954
|
version: options.version,
|
|
1903
1955
|
target,
|
|
1904
1956
|
tsConfigFilePath: options.tsConfigFilePath,
|
|
1905
|
-
minify: options.minify
|
|
1957
|
+
minify: options.minify,
|
|
1958
|
+
siteBaseUrl: options.siteBaseUrl
|
|
1906
1959
|
});
|
|
1907
1960
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1908
1961
|
res.end(JSON.stringify(result));
|
|
@@ -1958,14 +2011,15 @@ export {
|
|
|
1958
2011
|
fetchActionRequest,
|
|
1959
2012
|
fetchPageRequest,
|
|
1960
2013
|
fetchStaticFile,
|
|
2014
|
+
generateSitemap,
|
|
1961
2015
|
initializeServices,
|
|
1962
|
-
|
|
2016
|
+
c as initializeServicesFromModules,
|
|
1963
2017
|
isActionRequest,
|
|
1964
2018
|
matchRequest,
|
|
1965
2019
|
rebuild,
|
|
1966
2020
|
rebuildContract,
|
|
1967
2021
|
registerActionsFromManifest,
|
|
1968
|
-
|
|
2022
|
+
e as registerActionsFromModules,
|
|
1969
2023
|
resolveContractToRoutes,
|
|
1970
2024
|
startMainServer,
|
|
1971
2025
|
startRendererServer
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
-
var __publicField = (obj, key, value) =>
|
|
4
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
-
return value;
|
|
6
|
-
};
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
4
|
import fs from "node:fs/promises";
|
|
8
5
|
import path from "node:path";
|
|
9
6
|
import { renderFastChangingData, headMetaToHeadTags, mergeHeadTags, serializeHeadTags, getClientInitData, actionRegistry, setClientInitData } from "@jay-framework/stack-server-runtime";
|
|
@@ -14,7 +11,7 @@ import { getLogger } from "@jay-framework/logger";
|
|
|
14
11
|
import { parseJayFile, JAY_IMPORT_RESOLVER, injectHeadfullFSTemplates, assignCoordinatesToJayHtml, discoverHeadlessInstances } from "@jay-framework/compiler-jay-html";
|
|
15
12
|
import { checkValidationErrors } from "@jay-framework/compiler-shared";
|
|
16
13
|
import { isJayAction, isJayStreamAction } from "@jay-framework/fullstack-component";
|
|
17
|
-
const
|
|
14
|
+
const require$1 = createRequire(import.meta.url);
|
|
18
15
|
async function loadProductionPageParts(route, pageModule, jayHtmlContent, projectRoot, tsConfigFilePath, serverBuildDir) {
|
|
19
16
|
const exportName = route.componentExport || "page";
|
|
20
17
|
const compDefinition = pageModule[exportName] ?? pageModule.default;
|
|
@@ -68,7 +65,7 @@ async function loadProductionPageParts(route, pageModule, jayHtmlContent, projec
|
|
|
68
65
|
if (headlessImport.structural) {
|
|
69
66
|
continue;
|
|
70
67
|
} else {
|
|
71
|
-
const resolvedModulePath = isLocalModule ? modulePath :
|
|
68
|
+
const resolvedModulePath = isLocalModule ? modulePath : require$1.resolve(module, { paths: [dirName] });
|
|
72
69
|
const headlessModule = await import(resolvedModulePath);
|
|
73
70
|
headlessCompDef = headlessModule[name];
|
|
74
71
|
}
|
|
@@ -221,8 +218,7 @@ async function loadPagePartsFromConfig(configPath, artifacts) {
|
|
|
221
218
|
const serveTimeContract = {
|
|
222
219
|
props: entry.propNames.map((name) => ({ name }))
|
|
223
220
|
};
|
|
224
|
-
if (entry.structural)
|
|
225
|
-
continue;
|
|
221
|
+
if (entry.structural) continue;
|
|
226
222
|
const mod = await importModule(entry);
|
|
227
223
|
headlessInstanceComponents.push({
|
|
228
224
|
contractName: entry.contractName,
|
|
@@ -296,8 +292,7 @@ class FilesystemArtifactStore {
|
|
|
296
292
|
this.moduleCache.set(modulePath, { module: mod, mtime: stat.mtimeMs });
|
|
297
293
|
return mod;
|
|
298
294
|
} catch {
|
|
299
|
-
if (local)
|
|
300
|
-
throw new Error(`Local module not found: ${fullPath}`);
|
|
295
|
+
if (local) throw new Error(`Local module not found: ${fullPath}`);
|
|
301
296
|
}
|
|
302
297
|
}
|
|
303
298
|
return import(modulePath);
|
|
@@ -327,8 +322,7 @@ function matchSegments(routeSegments, urlSegments) {
|
|
|
327
322
|
}
|
|
328
323
|
urlIdx++;
|
|
329
324
|
} else if (seg.type === "param") {
|
|
330
|
-
if (urlIdx >= urlSegments.length)
|
|
331
|
-
return void 0;
|
|
325
|
+
if (urlIdx >= urlSegments.length) return void 0;
|
|
332
326
|
params[seg.value] = urlSegments[urlIdx];
|
|
333
327
|
urlIdx++;
|
|
334
328
|
} else if (seg.type === "optional") {
|
|
@@ -337,8 +331,7 @@ function matchSegments(routeSegments, urlSegments) {
|
|
|
337
331
|
urlIdx++;
|
|
338
332
|
}
|
|
339
333
|
} else if (seg.type === "catchAll") {
|
|
340
|
-
if (urlIdx >= urlSegments.length)
|
|
341
|
-
return void 0;
|
|
334
|
+
if (urlIdx >= urlSegments.length) return void 0;
|
|
342
335
|
params[seg.value] = urlSegments.slice(urlIdx).join("/");
|
|
343
336
|
urlIdx = urlSegments.length;
|
|
344
337
|
} else if (seg.type === "optionalCatchAll") {
|
|
@@ -348,8 +341,7 @@ function matchSegments(routeSegments, urlSegments) {
|
|
|
348
341
|
}
|
|
349
342
|
}
|
|
350
343
|
}
|
|
351
|
-
if (urlIdx !== urlSegments.length)
|
|
352
|
-
return void 0;
|
|
344
|
+
if (urlIdx !== urlSegments.length) return void 0;
|
|
353
345
|
return params;
|
|
354
346
|
}
|
|
355
347
|
function findInstance(route, params) {
|
|
@@ -360,10 +352,8 @@ function findInstance(route, params) {
|
|
|
360
352
|
for (const name of paramNames) {
|
|
361
353
|
const urlVal = params[name];
|
|
362
354
|
const instVal = instance.params[name];
|
|
363
|
-
if (urlVal === void 0 && instVal === void 0)
|
|
364
|
-
|
|
365
|
-
if (urlVal !== instVal)
|
|
366
|
-
return false;
|
|
355
|
+
if (urlVal === void 0 && instVal === void 0) continue;
|
|
356
|
+
if (urlVal !== instVal) return false;
|
|
367
357
|
}
|
|
368
358
|
return true;
|
|
369
359
|
});
|
|
@@ -379,8 +369,7 @@ const pagePartsCache = /* @__PURE__ */ new Map();
|
|
|
379
369
|
async function getPageParts(route, artifacts, cachePath) {
|
|
380
370
|
const cacheKey = route.pattern;
|
|
381
371
|
const cached = pagePartsCache.get(cacheKey);
|
|
382
|
-
if (cached)
|
|
383
|
-
return cached;
|
|
372
|
+
if (cached) return cached;
|
|
384
373
|
const routeDir = path.dirname(cachePath);
|
|
385
374
|
const configRelPath = path.join(routeDir, "page-parts.json");
|
|
386
375
|
const parts = await loadPagePartsFromConfig(configRelPath, artifacts);
|
|
@@ -443,13 +432,10 @@ async function fetchPageRequest(match, manifest, requestUrl, artifacts, staticBa
|
|
|
443
432
|
};
|
|
444
433
|
const headTagSources = [];
|
|
445
434
|
const slowHeadTags = cf.__slowHeadTags;
|
|
446
|
-
if (slowHeadTags)
|
|
447
|
-
|
|
448
|
-
if (fastResult.headTags)
|
|
449
|
-
headTagSources.push(fastResult.headTags);
|
|
435
|
+
if (slowHeadTags) headTagSources.push(...slowHeadTags);
|
|
436
|
+
if (fastResult.headTags) headTagSources.push(fastResult.headTags);
|
|
450
437
|
const templateHeadTags = headMetaToHeadTags(route.headMeta, fullViewState);
|
|
451
|
-
if (templateHeadTags.length > 0)
|
|
452
|
-
headTagSources.push(templateHeadTags);
|
|
438
|
+
if (templateHeadTags.length > 0) headTagSources.push(templateHeadTags);
|
|
453
439
|
const headTags = headTagSources.length > 0 ? mergeHeadTags(headTagSources) : [];
|
|
454
440
|
const hasCustomTitle = headTags.some((t) => t.tag?.toLowerCase() === "title");
|
|
455
441
|
const titleTag = hasCustomTitle ? "" : " <title>Vite + TS</title>\n";
|
|
@@ -509,8 +495,7 @@ ${headParts}
|
|
|
509
495
|
const tSsr = Date.now();
|
|
510
496
|
write("</div>");
|
|
511
497
|
const asyncScripts = (await Promise.all(asyncPromises)).filter((s) => s).join("");
|
|
512
|
-
if (asyncScripts)
|
|
513
|
-
write(asyncScripts);
|
|
498
|
+
if (asyncScripts) write(asyncScripts);
|
|
514
499
|
const clientInitData = getClientInitData();
|
|
515
500
|
const initArgs = route.routeClientBundlePath ? `${JSON.stringify(fullSlowViewState)}, ${JSON.stringify(fastViewState)}, ${JSON.stringify(fastCarryForward)}, ${JSON.stringify(clientInitData)}` : `${JSON.stringify(fastViewState)}, ${JSON.stringify(fastCarryForward)}, ${JSON.stringify(clientInitData)}`;
|
|
516
501
|
const tTotal = Date.now() - t0;
|
|
@@ -518,7 +503,6 @@ ${headParts}
|
|
|
518
503
|
const serverTiming = {
|
|
519
504
|
cache: tCache,
|
|
520
505
|
parts: tParts,
|
|
521
|
-
data: tData - t0,
|
|
522
506
|
fast: tFast - tData,
|
|
523
507
|
load: tLoadMs,
|
|
524
508
|
ssr: tSsr - tSsrStart,
|
|
@@ -697,8 +681,7 @@ async function registerActionsFromModules(modules, registry = actionRegistry) {
|
|
|
697
681
|
logger.info(`[Server] Registered ${count} actions from pre-imported modules`);
|
|
698
682
|
}
|
|
699
683
|
function getStatusCode(code, isActionError) {
|
|
700
|
-
if (isActionError)
|
|
701
|
-
return 422;
|
|
684
|
+
if (isActionError) return 422;
|
|
702
685
|
switch (code) {
|
|
703
686
|
case "ACTION_NOT_FOUND":
|
|
704
687
|
return 404;
|
|
@@ -727,21 +710,22 @@ const MIME_TYPES = {
|
|
|
727
710
|
".woff2": "font/woff2",
|
|
728
711
|
".woff": "font/woff",
|
|
729
712
|
".ttf": "font/ttf",
|
|
730
|
-
".webp": "image/webp"
|
|
713
|
+
".webp": "image/webp",
|
|
714
|
+
".xml": "application/xml",
|
|
715
|
+
".txt": "text/plain"
|
|
731
716
|
};
|
|
732
717
|
async function fetchStaticFile(pathname, frontendDir) {
|
|
733
718
|
const normalizedBase = path.resolve(frontendDir);
|
|
734
719
|
for (const candidate of [path.join(frontendDir, pathname)]) {
|
|
735
720
|
const normalizedFile = path.resolve(candidate);
|
|
736
|
-
if (!normalizedFile.startsWith(normalizedBase))
|
|
737
|
-
continue;
|
|
721
|
+
if (!normalizedFile.startsWith(normalizedBase)) continue;
|
|
738
722
|
try {
|
|
739
723
|
const content = await fs.readFile(candidate);
|
|
740
724
|
const ext = path.extname(candidate);
|
|
741
725
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
742
726
|
const isHashed = /[-][a-zA-Z0-9_-]{6,}\./.test(path.basename(candidate));
|
|
743
727
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "public, max-age=3600";
|
|
744
|
-
return new Response(content, {
|
|
728
|
+
return new Response(new Uint8Array(content), {
|
|
745
729
|
headers: {
|
|
746
730
|
"Content-Type": contentType,
|
|
747
731
|
"Content-Length": String(content.length),
|
|
@@ -760,8 +744,7 @@ async function initializeServicesFromModules(plugins, label) {
|
|
|
760
744
|
if (plugin.init?._serverInit) {
|
|
761
745
|
logger.info(`[${label}] Running plugin init: ${plugin.name}`);
|
|
762
746
|
const data = await plugin.init._serverInit();
|
|
763
|
-
if (data)
|
|
764
|
-
setClientInitData(plugin.name, data);
|
|
747
|
+
if (data) setClientInitData(plugin.name, data);
|
|
765
748
|
}
|
|
766
749
|
} catch (err) {
|
|
767
750
|
logger.warn(`[${label}] Plugin init failed: ${plugin.name}: ${err.message}`);
|
|
@@ -796,8 +779,7 @@ async function initializeServices(buildDir, projectRoot, label) {
|
|
|
796
779
|
if (init?._serverInit) {
|
|
797
780
|
logger.info(`[${label}] Running plugin init: ${pluginInit.name}`);
|
|
798
781
|
const data = await init._serverInit();
|
|
799
|
-
if (data)
|
|
800
|
-
setClientInitData(pluginInit.name, data);
|
|
782
|
+
if (data) setClientInitData(pluginInit.name, data);
|
|
801
783
|
}
|
|
802
784
|
} catch (err) {
|
|
803
785
|
logger.warn(`[${label}] Plugin init failed: ${pluginInit.name}: ${err.message}`);
|
|
@@ -812,22 +794,21 @@ async function initializeServices(buildDir, projectRoot, label) {
|
|
|
812
794
|
if (init?._serverInit) {
|
|
813
795
|
logger.info(`[${label}] Running server init...`);
|
|
814
796
|
const data = await init._serverInit();
|
|
815
|
-
if (data)
|
|
816
|
-
setClientInitData("project", data);
|
|
797
|
+
if (data) setClientInitData("project", data);
|
|
817
798
|
}
|
|
818
799
|
} catch {
|
|
819
800
|
}
|
|
820
801
|
}
|
|
821
802
|
export {
|
|
822
803
|
FilesystemArtifactStore as F,
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
804
|
+
fetchPageRequest as a,
|
|
805
|
+
fetchStaticFile as b,
|
|
806
|
+
initializeServicesFromModules as c,
|
|
807
|
+
isActionRequest as d,
|
|
808
|
+
registerActionsFromModules as e,
|
|
809
|
+
fetchActionRequest as f,
|
|
829
810
|
buildPagePartsConfig as g,
|
|
830
|
-
|
|
811
|
+
initializeServices as i,
|
|
831
812
|
loadProductionPageParts as l,
|
|
832
813
|
matchRequest as m,
|
|
833
814
|
registerActionsFromManifest as r
|
|
@@ -33,6 +33,8 @@ interface RouteEntry {
|
|
|
33
33
|
cssImports?: string[];
|
|
34
34
|
/** Head metadata from jay-html <head> (title, meta tags). */
|
|
35
35
|
headMeta?: JayHtmlHeadMeta;
|
|
36
|
+
/** True when page has static <meta name="robots" content="noindex"> */
|
|
37
|
+
noIndex?: boolean;
|
|
36
38
|
instances: InstanceEntry[];
|
|
37
39
|
isPlugin?: boolean;
|
|
38
40
|
pluginName?: string;
|
|
@@ -75,6 +77,8 @@ interface BuildOptions {
|
|
|
75
77
|
concurrency: number;
|
|
76
78
|
tsConfigFilePath: string;
|
|
77
79
|
minify?: boolean;
|
|
80
|
+
/** Site base URL for sitemap generation (e.g. "https://example.com"). */
|
|
81
|
+
siteBaseUrl?: string;
|
|
78
82
|
}
|
|
79
83
|
interface ServerElementModule {
|
|
80
84
|
renderToStream: (vs: object, ctx: _jay_framework_ssr_runtime.ServerRenderContext) => void;
|
|
@@ -183,4 +187,4 @@ interface PreImportedPlugin {
|
|
|
183
187
|
declare function initializeServicesFromModules(plugins: PreImportedPlugin[], label: string): Promise<void>;
|
|
184
188
|
declare function initializeServices(buildDir: string, projectRoot: string, label: string): Promise<void>;
|
|
185
189
|
|
|
186
|
-
export { type ActionEntry as A, type BuildOptions as B, type CacheEntry as C, FilesystemArtifactStore as F, type InstanceEntry as I, type MatchResult as M, type
|
|
190
|
+
export { type ActionEntry as A, type BuildOptions as B, type CacheEntry as C, FilesystemArtifactStore as F, type InstanceEntry as I, type MatchResult as M, type PageModule as P, type RouteManifest as R, type ServerElementModule as S, type RouteEntry as a, type ArtifactStore as b, type BuildMetadata as c, type PluginEntry as d, type PreImportedPlugin as e, type RouteSegment as f, fetchActionRequest as g, fetchPageRequest as h, fetchStaticFile as i, initializeServices as j, initializeServicesFromModules as k, isActionRequest as l, matchRequest as m, registerActionsFromModules as n, registerActionsFromManifest as r };
|
package/dist/serve-index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { b as ArtifactStore, C as CacheEntry, F as FilesystemArtifactStore, I as InstanceEntry, M as MatchResult, e as PreImportedPlugin, a as RouteEntry, R as RouteManifest, S as ServerElementModule, g as fetchActionRequest, h as fetchPageRequest, i as fetchStaticFile, j as initializeServices, k as initializeServicesFromModules, l as isActionRequest, m as matchRequest, r as registerActionsFromManifest, n as registerActionsFromModules } from './serve-index-cRXZm8vQ.js';
|
|
2
2
|
import '@jay-framework/ssr-runtime';
|
|
3
3
|
import '@jay-framework/compiler-shared';
|
|
4
4
|
import '@jay-framework/stack-server-runtime';
|
package/dist/serve-index.js
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
|
-
import { F,
|
|
2
|
-
import "node:fs/promises";
|
|
3
|
-
import "node:path";
|
|
4
|
-
import "@jay-framework/stack-server-runtime";
|
|
5
|
-
import "@jay-framework/view-state-merge";
|
|
6
|
-
import "@jay-framework/ssr-runtime";
|
|
7
|
-
import "node:module";
|
|
8
|
-
import "@jay-framework/logger";
|
|
9
|
-
import "@jay-framework/compiler-jay-html";
|
|
10
|
-
import "@jay-framework/compiler-shared";
|
|
11
|
-
import "@jay-framework/fullstack-component";
|
|
1
|
+
import { F, f, a, b, i, c, d, m, r, e } from "./init-services-Dy2SiHzw.js";
|
|
12
2
|
export {
|
|
13
3
|
F as FilesystemArtifactStore,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
4
|
+
f as fetchActionRequest,
|
|
5
|
+
a as fetchPageRequest,
|
|
6
|
+
b as fetchStaticFile,
|
|
7
|
+
i as initializeServices,
|
|
8
|
+
c as initializeServicesFromModules,
|
|
9
|
+
d as isActionRequest,
|
|
20
10
|
m as matchRequest,
|
|
21
11
|
r as registerActionsFromManifest,
|
|
22
|
-
|
|
12
|
+
e as registerActionsFromModules
|
|
23
13
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/production-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,20 +30,20 @@
|
|
|
30
30
|
"test:watch": "vitest"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@jay-framework/compiler-jay-html": "^0.
|
|
34
|
-
"@jay-framework/compiler-jay-stack": "^0.
|
|
35
|
-
"@jay-framework/compiler-shared": "^0.
|
|
36
|
-
"@jay-framework/fullstack-component": "^0.
|
|
37
|
-
"@jay-framework/logger": "^0.
|
|
38
|
-
"@jay-framework/ssr-runtime": "^0.
|
|
39
|
-
"@jay-framework/stack-route-scanner": "^0.
|
|
40
|
-
"@jay-framework/stack-server-runtime": "^0.
|
|
41
|
-
"@jay-framework/view-state-merge": "^0.
|
|
42
|
-
"@jay-framework/vite-plugin": "^0.
|
|
33
|
+
"@jay-framework/compiler-jay-html": "^0.24.0",
|
|
34
|
+
"@jay-framework/compiler-jay-stack": "^0.24.0",
|
|
35
|
+
"@jay-framework/compiler-shared": "^0.24.0",
|
|
36
|
+
"@jay-framework/fullstack-component": "^0.24.0",
|
|
37
|
+
"@jay-framework/logger": "^0.24.0",
|
|
38
|
+
"@jay-framework/ssr-runtime": "^0.24.0",
|
|
39
|
+
"@jay-framework/stack-route-scanner": "^0.24.0",
|
|
40
|
+
"@jay-framework/stack-server-runtime": "^0.24.0",
|
|
41
|
+
"@jay-framework/view-state-merge": "^0.24.0",
|
|
42
|
+
"@jay-framework/vite-plugin": "^0.24.0",
|
|
43
43
|
"vite": "^5.0.11"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@jay-framework/dev-environment": "^0.
|
|
46
|
+
"@jay-framework/dev-environment": "^0.24.0",
|
|
47
47
|
"@types/node": "^22.15.21",
|
|
48
48
|
"rimraf": "^5.0.5",
|
|
49
49
|
"tsup": "^8.0.1",
|