@noego/forge 0.0.26 → 0.1.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/bin/forge.js +98 -0
- package/dist/plugins-cjs/routing/html_render/html_render.js +2 -2
- package/dist/plugins-cjs/routing/html_render/html_render.js.map +1 -1
- package/dist/plugins-es/routing/html_render/html_render.js +3 -3
- package/dist/plugins-es/routing/html_render/html_render.js.map +1 -1
- package/dist/routing/html_render/html_render.js +3 -3
- package/dist/routing/html_render/html_render.js.map +1 -1
- package/dist-ssr/server.cjs +24 -381
- package/dist-ssr/server.cjs.map +1 -1
- package/dist-ssr/server.js +42 -399
- package/dist-ssr/server.js.map +1 -1
- package/dist-ssr/static.cjs +107 -0
- package/dist-ssr/static.cjs.map +1 -0
- package/dist-ssr/static.d.ts +151 -0
- package/dist-ssr/static.js +107 -0
- package/dist-ssr/static.js.map +1 -0
- package/dist-ssr/test.cjs +223 -0
- package/dist-ssr/test.cjs.map +1 -0
- package/dist-ssr/test.d.ts +239 -0
- package/dist-ssr/test.js +184 -0
- package/dist-ssr/test.js.map +1 -0
- package/dist-ssr/url_parser-CsBTlLeJ.cjs +418 -0
- package/dist-ssr/url_parser-CsBTlLeJ.cjs.map +1 -0
- package/dist-ssr/url_parser-DRWHePkU.js +398 -0
- package/dist-ssr/url_parser-DRWHePkU.js.map +1 -0
- package/package.json +39 -2
package/dist-ssr/server.js
CHANGED
|
@@ -2,122 +2,15 @@ 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
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import express from "express";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import path__default from "path";
|
|
6
|
+
import fs__default from "fs";
|
|
7
7
|
import deepmerge from "deepmerge";
|
|
8
|
-
import {
|
|
8
|
+
import { p as parse_openapi_config, i as initialize_route_matchers, C as ComponentManager, V as ViteComponentLoader, P as ProdComponentLoader } from "./url_parser-DRWHePkU.js";
|
|
9
9
|
import Handlebars from "handlebars";
|
|
10
|
-
import fs
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import "clone-deep";
|
|
14
|
-
import join from "url-join";
|
|
15
|
-
import { p as parsePathConfig } from "./path-BqcF5dbs.js";
|
|
10
|
+
import fs from "fs/promises";
|
|
11
|
+
import { uneval } from "devalue";
|
|
12
|
+
import { pathToFileURL } from "url";
|
|
16
13
|
import { render } from "svelte/server";
|
|
17
|
-
import pathToRegex from "path-to-regex";
|
|
18
|
-
class ViteComponentLoader {
|
|
19
|
-
constructor(basePath, vite) {
|
|
20
|
-
this.basePath = basePath;
|
|
21
|
-
this.vite = vite;
|
|
22
|
-
}
|
|
23
|
-
async load(componentPath, options = { use_base_path: true }) {
|
|
24
|
-
const absoluteComponentPath = this.getComponentFullPath(componentPath, options);
|
|
25
|
-
console.log(`[ViteComponentLoader] Loading component from path: ${absoluteComponentPath}`);
|
|
26
|
-
const jsPath = absoluteComponentPath.replace(/\.svelte$/, ".js");
|
|
27
|
-
fs.existsSync(jsPath);
|
|
28
|
-
let vitePath = path.relative(process.cwd(), absoluteComponentPath);
|
|
29
|
-
vitePath = vitePath.replace(/\\/g, "/");
|
|
30
|
-
if (!vitePath.startsWith("/")) {
|
|
31
|
-
vitePath = "/" + vitePath;
|
|
32
|
-
}
|
|
33
|
-
console.log(`[ViteComponentLoader] Resolved Vite path: ${vitePath} from componentPath: ${componentPath}`);
|
|
34
|
-
try {
|
|
35
|
-
console.log(`[ViteComponentLoader] Loading module for vitePath: ${vitePath}`);
|
|
36
|
-
const module = await this.vite.ssrLoadModule(vitePath);
|
|
37
|
-
console.log(`[ViteComponentLoader] Module loaded successfully for: ${vitePath}`);
|
|
38
|
-
if (!module || !module.default) {
|
|
39
|
-
console.error(`[ViteComponentLoader] Loaded module for ${vitePath} is invalid or missing a default export. Module content:`, module);
|
|
40
|
-
throw new Error(`Module ${vitePath} loaded successfully but is invalid or missing default export.`);
|
|
41
|
-
}
|
|
42
|
-
return module;
|
|
43
|
-
} catch (error) {
|
|
44
|
-
console.error(`[ViteComponentLoader] Error loading module for vitePath: ${vitePath} (derived from componentPath: ${componentPath})`, error);
|
|
45
|
-
try {
|
|
46
|
-
await fs.promises.access(absoluteComponentPath);
|
|
47
|
-
} catch (fsError) {
|
|
48
|
-
}
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
getComponentFullPath(componentPath, options = { use_base_path: true }) {
|
|
53
|
-
const use_base_path = options.use_base_path || false;
|
|
54
|
-
if (use_base_path) {
|
|
55
|
-
return path.join(this.basePath, componentPath);
|
|
56
|
-
}
|
|
57
|
-
if (path.isAbsolute(componentPath)) {
|
|
58
|
-
return componentPath;
|
|
59
|
-
}
|
|
60
|
-
return componentPath;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
class ProdComponentLoader {
|
|
64
|
-
constructor(base_path) {
|
|
65
|
-
__publicField(this, "componentMapPromise", null);
|
|
66
|
-
this.base_path = base_path;
|
|
67
|
-
}
|
|
68
|
-
async load(componentPath) {
|
|
69
|
-
const normalized = this.normalizeKey(componentPath);
|
|
70
|
-
try {
|
|
71
|
-
const map = await this.loadComponentMap();
|
|
72
|
-
const module2 = map[normalized];
|
|
73
|
-
if (module2) {
|
|
74
|
-
return module2;
|
|
75
|
-
}
|
|
76
|
-
} catch (error) {
|
|
77
|
-
console.warn(`[Forge] Failed to load component "${componentPath}" from entry manifest:`, error);
|
|
78
|
-
}
|
|
79
|
-
const component_path = this.getComponentFullPath(componentPath);
|
|
80
|
-
const fallbackPath = component_path.endsWith(".js") ? component_path : component_path.replace(/\.svelte$/, ".js");
|
|
81
|
-
const module = await import(pathToFileURL(fallbackPath).href);
|
|
82
|
-
return module;
|
|
83
|
-
}
|
|
84
|
-
getComponentFullPath(componentPath) {
|
|
85
|
-
return path.join(this.base_path, componentPath);
|
|
86
|
-
}
|
|
87
|
-
normalizeKey(componentPath) {
|
|
88
|
-
const trimmed = componentPath.replace(/^\.\//, "");
|
|
89
|
-
if (trimmed.endsWith(".svelte")) {
|
|
90
|
-
return trimmed.replace(/\.svelte$/, ".js");
|
|
91
|
-
}
|
|
92
|
-
return trimmed;
|
|
93
|
-
}
|
|
94
|
-
async loadComponentMap() {
|
|
95
|
-
if (!this.componentMapPromise) {
|
|
96
|
-
const entryPath = path.join(this.base_path, "entry-ssr.js");
|
|
97
|
-
const entryUrl = pathToFileURL(entryPath).href;
|
|
98
|
-
this.componentMapPromise = import(entryUrl).then((mod) => {
|
|
99
|
-
const source = mod.components ?? mod.default ?? {};
|
|
100
|
-
const normalized = {};
|
|
101
|
-
for (const [key, value] of Object.entries(source)) {
|
|
102
|
-
const cleanKey = key.replace(/^\.\//, "");
|
|
103
|
-
normalized[cleanKey] = value;
|
|
104
|
-
if (cleanKey.startsWith("ui/")) {
|
|
105
|
-
normalized[cleanKey.slice(3)] = value;
|
|
106
|
-
}
|
|
107
|
-
if (cleanKey.endsWith(".svelte")) {
|
|
108
|
-
const jsKey = cleanKey.replace(/\.svelte$/, ".js");
|
|
109
|
-
normalized[jsKey] = value;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return normalized;
|
|
113
|
-
}).catch((error) => {
|
|
114
|
-
this.componentMapPromise = null;
|
|
115
|
-
throw error;
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
return this.componentMapPromise;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
14
|
const default_template = `
|
|
122
15
|
<!DOCTYPE html>
|
|
123
16
|
<html lang="en">
|
|
@@ -152,7 +45,7 @@ class BaseHTMLRender {
|
|
|
152
45
|
if (configJson) {
|
|
153
46
|
try {
|
|
154
47
|
const configData = JSON.parse(configJson);
|
|
155
|
-
const safeConfigJson =
|
|
48
|
+
const safeConfigJson = uneval(configData);
|
|
156
49
|
const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};<\/script>`;
|
|
157
50
|
if (html.includes("</head>")) {
|
|
158
51
|
html = html.replace("</head>", `${configScript}
|
|
@@ -212,7 +105,7 @@ class LiveHTMLRender {
|
|
|
212
105
|
if (configJson) {
|
|
213
106
|
try {
|
|
214
107
|
const configData = JSON.parse(configJson);
|
|
215
|
-
const safeConfigJson =
|
|
108
|
+
const safeConfigJson = uneval(configData);
|
|
216
109
|
const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};<\/script>`;
|
|
217
110
|
if (html.includes("</head>")) {
|
|
218
111
|
html = html.replace("</head>", `${configScript}
|
|
@@ -256,146 +149,10 @@ if (document.readyState === 'loading') {
|
|
|
256
149
|
return html;
|
|
257
150
|
}
|
|
258
151
|
async getTemplate() {
|
|
259
|
-
const file_content = await fs
|
|
152
|
+
const file_content = await fs.readFile(this.html_path, "utf8");
|
|
260
153
|
return file_content;
|
|
261
154
|
}
|
|
262
155
|
}
|
|
263
|
-
const HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
264
|
-
"get",
|
|
265
|
-
"post",
|
|
266
|
-
"put",
|
|
267
|
-
"delete",
|
|
268
|
-
"patch",
|
|
269
|
-
"head",
|
|
270
|
-
"options",
|
|
271
|
-
"trace"
|
|
272
|
-
]);
|
|
273
|
-
function getGlobalPathsMiddleware(openapi) {
|
|
274
|
-
if (!openapi || !openapi.paths) {
|
|
275
|
-
return [];
|
|
276
|
-
}
|
|
277
|
-
const value = openapi.paths["x-middleware"];
|
|
278
|
-
return Array.isArray(value) ? [...value] : [];
|
|
279
|
-
}
|
|
280
|
-
function parseConfigfile(file_content) {
|
|
281
|
-
let config = null;
|
|
282
|
-
try {
|
|
283
|
-
config = yaml.load(file_content);
|
|
284
|
-
} catch (e) {
|
|
285
|
-
console.log(e);
|
|
286
|
-
}
|
|
287
|
-
return config;
|
|
288
|
-
}
|
|
289
|
-
function parse_modules(openapi, inheritedMiddleware = []) {
|
|
290
|
-
const modules_config = openapi.modules || openapi.module;
|
|
291
|
-
if (!modules_config) {
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
const modules = Object.entries(modules_config).map(([_, module]) => {
|
|
295
|
-
return module;
|
|
296
|
-
});
|
|
297
|
-
const globalMiddleware = [...inheritedMiddleware, ...getGlobalPathsMiddleware(openapi)];
|
|
298
|
-
const modules_path = modules.map((module) => {
|
|
299
|
-
const basePath = module.basePath || "";
|
|
300
|
-
const baseLayouts = module.baseLayouts || [];
|
|
301
|
-
const moduleMiddleware = Array.isArray(module["x-middleware"]) ? module["x-middleware"] : [];
|
|
302
|
-
const inherited = [...globalMiddleware, ...moduleMiddleware];
|
|
303
|
-
const paths = module.paths;
|
|
304
|
-
if (!paths) {
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
const configurations = Object.entries(paths).filter(([path2]) => typeof path2 === "string" && path2.startsWith("/")).map(([path2, method_config]) => {
|
|
308
|
-
return Object.entries(method_config).filter(([method]) => HTTP_METHODS.has(String(method).toLowerCase())).map(([method, config]) => {
|
|
309
|
-
const methodName = String(method);
|
|
310
|
-
return parsePathConfig(path2, methodName, config, inherited);
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
const routes = configurations.reduce((flat_config, config) => {
|
|
314
|
-
return flat_config.concat(config);
|
|
315
|
-
}, []);
|
|
316
|
-
routes.forEach((route) => {
|
|
317
|
-
route.path = join(basePath, route.path);
|
|
318
|
-
route.layout = baseLayouts.concat(route.layout || []);
|
|
319
|
-
});
|
|
320
|
-
return routes;
|
|
321
|
-
});
|
|
322
|
-
return modules_path.reduce(
|
|
323
|
-
(flat_config, config) => {
|
|
324
|
-
if (!config) {
|
|
325
|
-
return flat_config;
|
|
326
|
-
}
|
|
327
|
-
return flat_config.concat(config);
|
|
328
|
-
},
|
|
329
|
-
[]
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
function parse_paths(openapi, inheritedMiddleware = []) {
|
|
333
|
-
const paths = openapi.paths;
|
|
334
|
-
if (!paths) {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
const globalMiddleware = [...inheritedMiddleware, ...getGlobalPathsMiddleware(openapi)];
|
|
338
|
-
const configurations = Object.entries(paths).filter(([path2]) => typeof path2 === "string" && path2.startsWith("/")).map(([path2, method_config]) => {
|
|
339
|
-
return Object.entries(method_config).filter(([method]) => HTTP_METHODS.has(String(method).toLowerCase())).map(([method, config]) => {
|
|
340
|
-
const methodName = String(method);
|
|
341
|
-
return parsePathConfig(path2, methodName, config, globalMiddleware);
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
const routes = configurations.reduce((flat_config, config) => {
|
|
345
|
-
return flat_config.concat(config);
|
|
346
|
-
}, []);
|
|
347
|
-
return routes;
|
|
348
|
-
}
|
|
349
|
-
function isStitchConfig(document) {
|
|
350
|
-
return document && typeof document === "object" && "stitch" in document;
|
|
351
|
-
}
|
|
352
|
-
function isOpenAPIConfig(document) {
|
|
353
|
-
return document && typeof document === "object" && ("paths" in document || "module" in document || "modules" in document);
|
|
354
|
-
}
|
|
355
|
-
async function parse_openapi_config(openapi_config_path) {
|
|
356
|
-
const content = fs.readFileSync(openapi_config_path, "utf8");
|
|
357
|
-
const parsed_config = parseConfigfile(content);
|
|
358
|
-
let openapi_config;
|
|
359
|
-
if (isStitchConfig(parsed_config)) {
|
|
360
|
-
console.log("Detected stitch configuration, building with Node.js stitch engine...");
|
|
361
|
-
try {
|
|
362
|
-
const { StitchEngine } = await import("@noego/stitch");
|
|
363
|
-
const startTime = Date.now();
|
|
364
|
-
const engine = new StitchEngine();
|
|
365
|
-
const result = engine.buildSync(openapi_config_path, { format: "json" });
|
|
366
|
-
if (!result.success) {
|
|
367
|
-
throw new Error(`Stitch build failed: ${result.error}`);
|
|
368
|
-
}
|
|
369
|
-
const buildTime = Date.now() - startTime;
|
|
370
|
-
console.log(`INFO Stitch build completed in ${buildTime} ms – ${parsed_config.stitch ? parsed_config.stitch.length : 0} modules processed`);
|
|
371
|
-
openapi_config = typeof result.data === "string" ? JSON.parse(result.data) : result.data;
|
|
372
|
-
} catch (error) {
|
|
373
|
-
throw new Error(`Failed to process stitch configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
374
|
-
}
|
|
375
|
-
} else if (isOpenAPIConfig(parsed_config)) {
|
|
376
|
-
console.log("Detected regular OpenAPI configuration");
|
|
377
|
-
openapi_config = parsed_config;
|
|
378
|
-
} else {
|
|
379
|
-
throw new Error(`Invalid OpenAPI or stitch configuration file: ${openapi_config_path}. File must contain either 'stitch', 'paths', 'module', or 'modules' at the root level.`);
|
|
380
|
-
}
|
|
381
|
-
const globalPathsMiddleware = getGlobalPathsMiddleware(openapi_config);
|
|
382
|
-
let modules = parse_modules(openapi_config) || [];
|
|
383
|
-
let paths = parse_paths(openapi_config) || [];
|
|
384
|
-
let fallback_layout = openapi_config["x-fallback-layout"] || null;
|
|
385
|
-
let fallback_view = openapi_config["x-fallback-view"] || null;
|
|
386
|
-
const fallback_middleware = Array.isArray(openapi_config["x-fallback-middleware"]) ? [...openapi_config["x-fallback-middleware"]] : [...globalPathsMiddleware];
|
|
387
|
-
let fallback = {
|
|
388
|
-
layout: fallback_layout ? [fallback_layout] : [],
|
|
389
|
-
view: fallback_view,
|
|
390
|
-
middleware: fallback_middleware
|
|
391
|
-
};
|
|
392
|
-
const routes = [...modules, ...paths];
|
|
393
|
-
let config = {
|
|
394
|
-
fallback,
|
|
395
|
-
routes
|
|
396
|
-
};
|
|
397
|
-
return config;
|
|
398
|
-
}
|
|
399
156
|
const defaultViteOptions = {
|
|
400
157
|
appType: "custom",
|
|
401
158
|
root: process.cwd(),
|
|
@@ -410,7 +167,7 @@ const defaultOptions = {
|
|
|
410
167
|
component_dir: "/",
|
|
411
168
|
build_dir: "dist_ssr",
|
|
412
169
|
renderer: "default",
|
|
413
|
-
open_api_path:
|
|
170
|
+
open_api_path: path__default.join(process.cwd(), "openapi.yaml"),
|
|
414
171
|
manifest_endpoint: "/manifest.json",
|
|
415
172
|
middleware_path: void 0
|
|
416
173
|
};
|
|
@@ -459,12 +216,12 @@ async function layout_requires_server(route, loader) {
|
|
|
459
216
|
}
|
|
460
217
|
const load_required = await Promise.all(layout.map(async (layoutPath) => {
|
|
461
218
|
const fullPath = loader.getComponentFullPath(layoutPath);
|
|
462
|
-
const { dir, name } =
|
|
219
|
+
const { dir, name } = path__default.parse(fullPath);
|
|
463
220
|
const extensions = [".js", ".ts"];
|
|
464
221
|
for (const ext of extensions) {
|
|
465
|
-
const loaderFilePath =
|
|
222
|
+
const loaderFilePath = path__default.join(dir, `${name}.load${ext}`);
|
|
466
223
|
try {
|
|
467
|
-
if (
|
|
224
|
+
if (fs__default.existsSync(loaderFilePath)) {
|
|
468
225
|
const module = await import(pathToFileURL(loaderFilePath).href);
|
|
469
226
|
if (typeof (module == null ? void 0 : module.default) === "function") {
|
|
470
227
|
return true;
|
|
@@ -488,12 +245,12 @@ async function view_requires_server(route, loader) {
|
|
|
488
245
|
return false;
|
|
489
246
|
}
|
|
490
247
|
const fullPath = loader.getComponentFullPath(view);
|
|
491
|
-
const { dir, name } =
|
|
248
|
+
const { dir, name } = path__default.parse(fullPath);
|
|
492
249
|
const extensions = [".js", ".ts"];
|
|
493
250
|
for (const ext of extensions) {
|
|
494
|
-
const loaderFilePath =
|
|
251
|
+
const loaderFilePath = path__default.join(dir, `${name}.load${ext}`);
|
|
495
252
|
try {
|
|
496
|
-
if (
|
|
253
|
+
if (fs__default.existsSync(loaderFilePath)) {
|
|
497
254
|
const module = await import(pathToFileURL(loaderFilePath).href);
|
|
498
255
|
if (typeof (module == null ? void 0 : module.default) === "function") {
|
|
499
256
|
return true;
|
|
@@ -605,106 +362,6 @@ class ApiAdapter {
|
|
|
605
362
|
};
|
|
606
363
|
}
|
|
607
364
|
}
|
|
608
|
-
class ComponentManager {
|
|
609
|
-
constructor(componentLoader) {
|
|
610
|
-
this.componentLoader = componentLoader;
|
|
611
|
-
}
|
|
612
|
-
async getLayoutComponents(route) {
|
|
613
|
-
const layout_paths = route.layout || [];
|
|
614
|
-
const layouts_components = await Promise.all(layout_paths.map((layout) => {
|
|
615
|
-
console.log("layout path", layout);
|
|
616
|
-
return this.componentLoader.load(layout);
|
|
617
|
-
}));
|
|
618
|
-
return layouts_components;
|
|
619
|
-
}
|
|
620
|
-
async getLayouts(route) {
|
|
621
|
-
const layout_paths = route.layout || [];
|
|
622
|
-
const layouts_components = await Promise.all(layout_paths.map(async (layout_path) => {
|
|
623
|
-
const layout = await this.componentLoader.load(layout_path);
|
|
624
|
-
return layout.default;
|
|
625
|
-
}));
|
|
626
|
-
return layouts_components;
|
|
627
|
-
}
|
|
628
|
-
async getLayoutLoaders(route) {
|
|
629
|
-
const layout_paths = route.layout || [];
|
|
630
|
-
const loaders_from_files = await Promise.all(
|
|
631
|
-
layout_paths.map((layoutPath) => this.resolveLoader(layoutPath))
|
|
632
|
-
);
|
|
633
|
-
const needs_fallback = loaders_from_files.some((loader) => !loader);
|
|
634
|
-
if (needs_fallback) {
|
|
635
|
-
const layout_components = await this.getLayoutComponents(route);
|
|
636
|
-
const old_style_loaders = layout_components.map((layout) => layout.load);
|
|
637
|
-
return loaders_from_files.map(
|
|
638
|
-
(loader, index) => loader || old_style_loaders[index] || null
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
return loaders_from_files;
|
|
642
|
-
}
|
|
643
|
-
async getViewComponent(route) {
|
|
644
|
-
return await this.componentLoader.load(route.view);
|
|
645
|
-
}
|
|
646
|
-
async hasLoaders(route) {
|
|
647
|
-
const componentPaths = [...route.layout || [], route.view];
|
|
648
|
-
for (const componentPath of componentPaths) {
|
|
649
|
-
const loader = await this.resolveLoader(componentPath);
|
|
650
|
-
if (loader) {
|
|
651
|
-
return true;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
return false;
|
|
655
|
-
}
|
|
656
|
-
async getLoaders(route) {
|
|
657
|
-
const layoutPaths = route.layout || [];
|
|
658
|
-
const layouts = await Promise.all(layoutPaths.map((layoutPath) => this.resolveLoader(layoutPath)));
|
|
659
|
-
const view = await this.resolveLoader(route.view);
|
|
660
|
-
return {
|
|
661
|
-
layouts,
|
|
662
|
-
view
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
getLoaderFilePath(componentPath, extension = ".js") {
|
|
666
|
-
if (!componentPath) {
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
|
-
const fullPath = this.componentLoader.getComponentFullPath(componentPath);
|
|
670
|
-
const { dir, name } = path.parse(fullPath);
|
|
671
|
-
return path.join(dir, `${name}.load${extension}`);
|
|
672
|
-
}
|
|
673
|
-
async resolveLoader(componentPath) {
|
|
674
|
-
if (!componentPath) {
|
|
675
|
-
return null;
|
|
676
|
-
}
|
|
677
|
-
const extensions = [".js", ".ts"];
|
|
678
|
-
for (const ext of extensions) {
|
|
679
|
-
const loaderFilePath = this.getLoaderFilePath(componentPath, ext);
|
|
680
|
-
if (!loaderFilePath) {
|
|
681
|
-
continue;
|
|
682
|
-
}
|
|
683
|
-
try {
|
|
684
|
-
console.log(`[ComponentManager] Trying loader path: ${loaderFilePath}`);
|
|
685
|
-
const module = await import(pathToFileURL(loaderFilePath).href);
|
|
686
|
-
const loader = module == null ? void 0 : module.default;
|
|
687
|
-
console.log(`[ComponentManager] Imported loader module: default=${typeof loader}`);
|
|
688
|
-
if (typeof loader === "function") {
|
|
689
|
-
console.log(`[ComponentManager] Loaded loader function from: ${loaderFilePath}`);
|
|
690
|
-
return loader;
|
|
691
|
-
}
|
|
692
|
-
} catch (error) {
|
|
693
|
-
const code = (error == null ? void 0 : error.code) || (error == null ? void 0 : error.name) || "UNKNOWN_ERROR";
|
|
694
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
695
|
-
console.warn(`[ComponentManager] Loader not found at ${loaderFilePath} (${ext}): ${(error == null ? void 0 : error.message) || code}`);
|
|
696
|
-
continue;
|
|
697
|
-
}
|
|
698
|
-
console.error(`[ComponentManager] Failed to load loader for ${componentPath} (${ext}) at ${loaderFilePath}:`, error);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
return null;
|
|
702
|
-
}
|
|
703
|
-
async getView(route) {
|
|
704
|
-
const view = await this.componentLoader.load(route.view);
|
|
705
|
-
return view.default;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
365
|
const EXTENSION_CANDIDATES = [".js", ".mjs", ".cjs", ".ts", ".tsx"];
|
|
709
366
|
class MiddlewareAdapter {
|
|
710
367
|
constructor(middlewarePath, fallbackPath) {
|
|
@@ -770,7 +427,7 @@ class MiddlewareAdapter {
|
|
|
770
427
|
resolveMiddlewareFilePath(filePath) {
|
|
771
428
|
const basePath = this.middlewarePath || this.fallbackPath || process.cwd();
|
|
772
429
|
const transformed = this.middlewareFileTransform(filePath);
|
|
773
|
-
const baseCandidate =
|
|
430
|
+
const baseCandidate = path__default.resolve(process.cwd(), path__default.join(basePath, transformed));
|
|
774
431
|
const resolvedWithExt = this.findExistingFile(baseCandidate);
|
|
775
432
|
if (resolvedWithExt) {
|
|
776
433
|
return resolvedWithExt;
|
|
@@ -778,22 +435,22 @@ class MiddlewareAdapter {
|
|
|
778
435
|
throw new Error(`Middleware file not found: ${transformed}`);
|
|
779
436
|
}
|
|
780
437
|
middlewareFileTransform(filePath) {
|
|
781
|
-
return filePath.split(".").join(
|
|
438
|
+
return filePath.split(".").join(path__default.sep);
|
|
782
439
|
}
|
|
783
440
|
findExistingFile(basePathWithoutExt) {
|
|
784
|
-
const ext =
|
|
441
|
+
const ext = path__default.extname(basePathWithoutExt);
|
|
785
442
|
if (ext) {
|
|
786
|
-
return
|
|
443
|
+
return fs__default.existsSync(basePathWithoutExt) ? basePathWithoutExt : null;
|
|
787
444
|
}
|
|
788
445
|
const directCandidates = EXTENSION_CANDIDATES.map((extCandidate) => `${basePathWithoutExt}${extCandidate}`);
|
|
789
446
|
for (const candidate of directCandidates) {
|
|
790
|
-
if (
|
|
447
|
+
if (fs__default.existsSync(candidate)) {
|
|
791
448
|
return candidate;
|
|
792
449
|
}
|
|
793
450
|
}
|
|
794
|
-
const indexCandidates = EXTENSION_CANDIDATES.map((extCandidate) =>
|
|
451
|
+
const indexCandidates = EXTENSION_CANDIDATES.map((extCandidate) => path__default.join(basePathWithoutExt, `index${extCandidate}`));
|
|
795
452
|
for (const candidate of indexCandidates) {
|
|
796
|
-
if (
|
|
453
|
+
if (fs__default.existsSync(candidate)) {
|
|
797
454
|
return candidate;
|
|
798
455
|
}
|
|
799
456
|
}
|
|
@@ -887,20 +544,6 @@ class MiddlewareAdapter {
|
|
|
887
544
|
return ordered;
|
|
888
545
|
}
|
|
889
546
|
}
|
|
890
|
-
function makeUrlParser(pattern) {
|
|
891
|
-
const parser = new pathToRegex(pattern);
|
|
892
|
-
return (pathname) => {
|
|
893
|
-
const result = parser.match(pathname);
|
|
894
|
-
return result || null;
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
function initialize_route_matchers(routes) {
|
|
898
|
-
return routes.map((route) => {
|
|
899
|
-
const pattern = route.path;
|
|
900
|
-
const parser = makeUrlParser(pattern);
|
|
901
|
-
return { pattern, parser };
|
|
902
|
-
});
|
|
903
|
-
}
|
|
904
547
|
class ServerAdapter {
|
|
905
548
|
}
|
|
906
549
|
class ExpressServerAdapter extends ServerAdapter {
|
|
@@ -930,8 +573,8 @@ class ExpressServerAdapter extends ServerAdapter {
|
|
|
930
573
|
return mod.default ?? mod;
|
|
931
574
|
}
|
|
932
575
|
const candidates = [
|
|
933
|
-
|
|
934
|
-
|
|
576
|
+
path__default.join(componentRoot, "RecursiveRender.js"),
|
|
577
|
+
path__default.join(componentRoot, "ssr", "RecursiveRender.js")
|
|
935
578
|
];
|
|
936
579
|
let lastError;
|
|
937
580
|
for (const fp of candidates) {
|
|
@@ -1126,20 +769,20 @@ ${e.stack}</pre>
|
|
|
1126
769
|
const clientComponentDir = this.isProd ? deriveClientBase(this.componentDir || "") : this.componentDir || "/assets";
|
|
1127
770
|
const head_routing = `
|
|
1128
771
|
<script type='text/javascript'>
|
|
1129
|
-
window.__ROUTING__ = ${
|
|
772
|
+
window.__ROUTING__ = ${uneval(this.clientRoutes)}
|
|
1130
773
|
<\/script>
|
|
1131
774
|
|
|
1132
775
|
<script type='text/javascript'>
|
|
1133
|
-
window.__MANIFEST__ = ${
|
|
776
|
+
window.__MANIFEST__ = ${uneval(manifest)}
|
|
1134
777
|
console.log('[MANIFEST INJECTED]', window.__MANIFEST__);
|
|
1135
778
|
<\/script>
|
|
1136
779
|
|
|
1137
780
|
<script type='text/javascript'>
|
|
1138
|
-
window.__INITIAL_DATA__ = ${
|
|
781
|
+
window.__INITIAL_DATA__ = ${uneval(server_data || {})}
|
|
1139
782
|
<\/script>
|
|
1140
783
|
|
|
1141
784
|
<script type='text/javascript'>
|
|
1142
|
-
window.__COMPONENT_DIR__ = ${
|
|
785
|
+
window.__COMPONENT_DIR__ = ${uneval(clientComponentDir)}
|
|
1143
786
|
<\/script>
|
|
1144
787
|
`;
|
|
1145
788
|
console.log("[SSR DEBUG] About to render HTML with APP length:", (body_render == null ? void 0 : body_render.length) || 0);
|
|
@@ -1229,7 +872,7 @@ view: ${route.view}</pre>`;
|
|
|
1229
872
|
}
|
|
1230
873
|
function pathExistsSync(p) {
|
|
1231
874
|
try {
|
|
1232
|
-
return
|
|
875
|
+
return fs__default.existsSync(p);
|
|
1233
876
|
} catch {
|
|
1234
877
|
return false;
|
|
1235
878
|
}
|
|
@@ -1237,15 +880,15 @@ function pathExistsSync(p) {
|
|
|
1237
880
|
function resolveRuntimeRoot(candidate) {
|
|
1238
881
|
var _a;
|
|
1239
882
|
const envRoot = process.env.FORGE_ROOT;
|
|
1240
|
-
if (envRoot &&
|
|
1241
|
-
return
|
|
883
|
+
if (envRoot && path__default.isAbsolute(envRoot) && pathExistsSync(envRoot)) {
|
|
884
|
+
return path__default.normalize(envRoot);
|
|
1242
885
|
}
|
|
1243
|
-
if (candidate &&
|
|
1244
|
-
return
|
|
886
|
+
if (candidate && path__default.isAbsolute(candidate) && pathExistsSync(candidate)) {
|
|
887
|
+
return path__default.normalize(candidate);
|
|
1245
888
|
}
|
|
1246
889
|
const entry = (_a = process.argv) == null ? void 0 : _a[1];
|
|
1247
890
|
if (entry) {
|
|
1248
|
-
const entryDir =
|
|
891
|
+
const entryDir = path__default.dirname(path__default.resolve(entry));
|
|
1249
892
|
if (pathExistsSync(entryDir)) return entryDir;
|
|
1250
893
|
}
|
|
1251
894
|
return process.cwd();
|
|
@@ -1257,7 +900,7 @@ async function createServer(app, options) {
|
|
|
1257
900
|
const root = resolveRuntimeRoot((_a = full_options.viteOptions) == null ? void 0 : _a.root);
|
|
1258
901
|
full_options.viteOptions.root = root;
|
|
1259
902
|
full_options.open_api_path = ensureFullPath(full_options.viteOptions.root, full_options.open_api_path);
|
|
1260
|
-
const COMPONENT_DIR = !full_options.component_dir ? root :
|
|
903
|
+
const COMPONENT_DIR = !full_options.component_dir ? root : path__default.join(root, full_options.component_dir);
|
|
1261
904
|
const isBuiltEnvironment = process.env.FORGE_BUILT === "true";
|
|
1262
905
|
const isProd = isBuiltEnvironment || full_options.development === false;
|
|
1263
906
|
console.log(`Running in ${isProd ? "production" : "development"} mode (built environment: ${isBuiltEnvironment}, development flag: ${full_options.development}, NODE_ENV: ${process.env.NODE_ENV})`);
|
|
@@ -1270,7 +913,7 @@ async function createServer(app, options) {
|
|
|
1270
913
|
}
|
|
1271
914
|
if (!entry || typeof entry !== "string") return root;
|
|
1272
915
|
const cleaned = entry.replace(/^\/+/, "");
|
|
1273
|
-
return
|
|
916
|
+
return path__default.resolve(root, cleaned);
|
|
1274
917
|
};
|
|
1275
918
|
if (full_options.assets) {
|
|
1276
919
|
for (const [asset_path, asset_dir] of Object.entries(full_options.assets)) {
|
|
@@ -1299,7 +942,7 @@ ${JSON.stringify(options, null, 2)}`);
|
|
|
1299
942
|
componentLoader = new ViteComponentLoader(COMPONENT_DIR, vite);
|
|
1300
943
|
} else {
|
|
1301
944
|
console.log("Starting Vite in production mode...");
|
|
1302
|
-
const staticDir =
|
|
945
|
+
const staticDir = path__default.join(full_options.viteOptions.root, full_options.build_dir);
|
|
1303
946
|
if (pathExistsSync(staticDir)) {
|
|
1304
947
|
app.use("/", express.static(staticDir));
|
|
1305
948
|
console.log(`Serving static files from ${staticDir} at /`);
|
|
@@ -1323,7 +966,7 @@ ${JSON.stringify(options, null, 2)}`);
|
|
|
1323
966
|
const api_adapter = new ApiAdapter(manager);
|
|
1324
967
|
let middlewareRoot;
|
|
1325
968
|
if (full_options.middleware_path) {
|
|
1326
|
-
middlewareRoot =
|
|
969
|
+
middlewareRoot = path__default.isAbsolute(full_options.middleware_path) ? full_options.middleware_path : path__default.resolve(full_options.viteOptions.root, full_options.middleware_path);
|
|
1327
970
|
}
|
|
1328
971
|
const middleware_adapter = MiddlewareAdapter.build(middlewareRoot, COMPONENT_DIR);
|
|
1329
972
|
const adapter = new ExpressServerAdapter(
|
|
@@ -1351,7 +994,7 @@ function getRenderer(root, renderer, isProd) {
|
|
|
1351
994
|
return new LiveHTMLRender(ensureFullPath(root, renderer));
|
|
1352
995
|
} else if (typeof renderer === "string" && isProd) {
|
|
1353
996
|
const html = ensureFullPath(root, renderer);
|
|
1354
|
-
const template =
|
|
997
|
+
const template = fs__default.readFileSync(html, "utf8");
|
|
1355
998
|
return new BaseHTMLRender(template);
|
|
1356
999
|
} else if (renderer instanceof BaseHTMLRender) {
|
|
1357
1000
|
return renderer;
|
|
@@ -1360,12 +1003,12 @@ function getRenderer(root, renderer, isProd) {
|
|
|
1360
1003
|
}
|
|
1361
1004
|
}
|
|
1362
1005
|
function ensureFullPath(root, renderer) {
|
|
1363
|
-
if (
|
|
1006
|
+
if (path__default.isAbsolute(renderer)) {
|
|
1364
1007
|
console.log(`Renderer path is absolute: ${renderer}`);
|
|
1365
1008
|
return urlJoin(root, renderer);
|
|
1366
1009
|
} else {
|
|
1367
1010
|
console.log(`Renderer path is relative: ${renderer}`);
|
|
1368
|
-
return
|
|
1011
|
+
return path__default.resolve(root, renderer);
|
|
1369
1012
|
}
|
|
1370
1013
|
}
|
|
1371
1014
|
function urlJoin(base, path2) {
|