@noego/forge 0.0.27 → 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-ssr/server.cjs +18 -375
- package/dist-ssr/server.cjs.map +1 -1
- package/dist-ssr/server.js +35 -392
- 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/bin/forge.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import { glob } from 'fs/promises';
|
|
5
|
+
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
|
|
8
|
+
if (args.length === 0) {
|
|
9
|
+
console.log('Usage: forge <pattern|files...>');
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log('Runs TypeScript files with Svelte support.');
|
|
12
|
+
console.log('');
|
|
13
|
+
console.log('Examples:');
|
|
14
|
+
console.log(' forge test/ui/auth.test.ts');
|
|
15
|
+
console.log(' forge test/ui/*.test.ts');
|
|
16
|
+
console.log(' forge "test/ui/**/*.test.ts"');
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function runFile(file) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const child = spawn(
|
|
23
|
+
'npx',
|
|
24
|
+
['tsx', '--loader', '@noego/forge/loader', file],
|
|
25
|
+
{
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
shell: true,
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
child.on('close', (code) => {
|
|
32
|
+
resolve({ file, code: code ?? 0 });
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
child.on('error', (err) => {
|
|
36
|
+
console.error(`Error running ${file}:`, err.message);
|
|
37
|
+
resolve({ file, code: 1 });
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function main() {
|
|
43
|
+
const files = [];
|
|
44
|
+
|
|
45
|
+
// Support both shell expansion (multiple args) and glob patterns
|
|
46
|
+
for (const arg of args) {
|
|
47
|
+
if (arg.includes('*')) {
|
|
48
|
+
// Glob pattern - expand it
|
|
49
|
+
for await (const file of glob(arg)) {
|
|
50
|
+
files.push(file);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
// Direct file path
|
|
54
|
+
files.push(arg);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (files.length === 0) {
|
|
59
|
+
console.error(`No files found matching: ${args.join(' ')}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Sort for consistent ordering
|
|
64
|
+
files.sort();
|
|
65
|
+
|
|
66
|
+
const results = [];
|
|
67
|
+
|
|
68
|
+
for (const file of files) {
|
|
69
|
+
if (files.length > 1) {
|
|
70
|
+
console.log(`\n━━━ ${file} ━━━\n`);
|
|
71
|
+
}
|
|
72
|
+
const result = await runFile(file);
|
|
73
|
+
results.push(result);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Summary if multiple files
|
|
77
|
+
if (files.length > 1) {
|
|
78
|
+
const passed = results.filter(r => r.code === 0);
|
|
79
|
+
const failed = results.filter(r => r.code !== 0);
|
|
80
|
+
|
|
81
|
+
console.log('\n━━━ Summary ━━━\n');
|
|
82
|
+
console.log(`Passed: ${passed.length}/${results.length}`);
|
|
83
|
+
|
|
84
|
+
if (failed.length > 0) {
|
|
85
|
+
console.log('\nFailed:');
|
|
86
|
+
failed.forEach(r => console.log(` - ${r.file}`));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
process.exit(failed.length > 0 ? 1 : 0);
|
|
90
|
+
} else {
|
|
91
|
+
process.exit(results[0].code);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
main().catch(err => {
|
|
96
|
+
console.error('Error:', err);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
});
|
package/dist-ssr/server.cjs
CHANGED
|
@@ -26,121 +26,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
26
26
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
27
27
|
const express = require("express");
|
|
28
28
|
const path = require("path");
|
|
29
|
-
const fs = require("fs");
|
|
29
|
+
const fs$1 = require("fs");
|
|
30
30
|
const deepmerge = require("deepmerge");
|
|
31
|
-
const
|
|
31
|
+
const url_parser = require("./url_parser-CsBTlLeJ.cjs");
|
|
32
32
|
const Handlebars = require("handlebars");
|
|
33
|
-
const fs
|
|
33
|
+
const fs = require("fs/promises");
|
|
34
34
|
const devalue = require("devalue");
|
|
35
|
-
const
|
|
36
|
-
require("clone-deep");
|
|
37
|
-
const join = require("url-join");
|
|
38
|
-
const path$1 = require("./path-sxXxpB6R.cjs");
|
|
35
|
+
const url = require("url");
|
|
39
36
|
const server = require("svelte/server");
|
|
40
|
-
const pathToRegex = require("path-to-regex");
|
|
41
|
-
class ViteComponentLoader {
|
|
42
|
-
constructor(basePath, vite) {
|
|
43
|
-
this.basePath = basePath;
|
|
44
|
-
this.vite = vite;
|
|
45
|
-
}
|
|
46
|
-
async load(componentPath, options = { use_base_path: true }) {
|
|
47
|
-
const absoluteComponentPath = this.getComponentFullPath(componentPath, options);
|
|
48
|
-
console.log(`[ViteComponentLoader] Loading component from path: ${absoluteComponentPath}`);
|
|
49
|
-
const jsPath = absoluteComponentPath.replace(/\.svelte$/, ".js");
|
|
50
|
-
fs.existsSync(jsPath);
|
|
51
|
-
let vitePath = path.relative(process.cwd(), absoluteComponentPath);
|
|
52
|
-
vitePath = vitePath.replace(/\\/g, "/");
|
|
53
|
-
if (!vitePath.startsWith("/")) {
|
|
54
|
-
vitePath = "/" + vitePath;
|
|
55
|
-
}
|
|
56
|
-
console.log(`[ViteComponentLoader] Resolved Vite path: ${vitePath} from componentPath: ${componentPath}`);
|
|
57
|
-
try {
|
|
58
|
-
console.log(`[ViteComponentLoader] Loading module for vitePath: ${vitePath}`);
|
|
59
|
-
const module2 = await this.vite.ssrLoadModule(vitePath);
|
|
60
|
-
console.log(`[ViteComponentLoader] Module loaded successfully for: ${vitePath}`);
|
|
61
|
-
if (!module2 || !module2.default) {
|
|
62
|
-
console.error(`[ViteComponentLoader] Loaded module for ${vitePath} is invalid or missing a default export. Module content:`, module2);
|
|
63
|
-
throw new Error(`Module ${vitePath} loaded successfully but is invalid or missing default export.`);
|
|
64
|
-
}
|
|
65
|
-
return module2;
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error(`[ViteComponentLoader] Error loading module for vitePath: ${vitePath} (derived from componentPath: ${componentPath})`, error);
|
|
68
|
-
try {
|
|
69
|
-
await fs.promises.access(absoluteComponentPath);
|
|
70
|
-
} catch (fsError) {
|
|
71
|
-
}
|
|
72
|
-
throw error;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
getComponentFullPath(componentPath, options = { use_base_path: true }) {
|
|
76
|
-
const use_base_path = options.use_base_path || false;
|
|
77
|
-
if (use_base_path) {
|
|
78
|
-
return path.join(this.basePath, componentPath);
|
|
79
|
-
}
|
|
80
|
-
if (path.isAbsolute(componentPath)) {
|
|
81
|
-
return componentPath;
|
|
82
|
-
}
|
|
83
|
-
return componentPath;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
class ProdComponentLoader {
|
|
87
|
-
constructor(base_path) {
|
|
88
|
-
__publicField(this, "componentMapPromise", null);
|
|
89
|
-
this.base_path = base_path;
|
|
90
|
-
}
|
|
91
|
-
async load(componentPath) {
|
|
92
|
-
const normalized = this.normalizeKey(componentPath);
|
|
93
|
-
try {
|
|
94
|
-
const map = await this.loadComponentMap();
|
|
95
|
-
const module22 = map[normalized];
|
|
96
|
-
if (module22) {
|
|
97
|
-
return module22;
|
|
98
|
-
}
|
|
99
|
-
} catch (error) {
|
|
100
|
-
console.warn(`[Forge] Failed to load component "${componentPath}" from entry manifest:`, error);
|
|
101
|
-
}
|
|
102
|
-
const component_path = this.getComponentFullPath(componentPath);
|
|
103
|
-
const fallbackPath = component_path.endsWith(".js") ? component_path : component_path.replace(/\.svelte$/, ".js");
|
|
104
|
-
const module2 = await import(url.pathToFileURL(fallbackPath).href);
|
|
105
|
-
return module2;
|
|
106
|
-
}
|
|
107
|
-
getComponentFullPath(componentPath) {
|
|
108
|
-
return path.join(this.base_path, componentPath);
|
|
109
|
-
}
|
|
110
|
-
normalizeKey(componentPath) {
|
|
111
|
-
const trimmed = componentPath.replace(/^\.\//, "");
|
|
112
|
-
if (trimmed.endsWith(".svelte")) {
|
|
113
|
-
return trimmed.replace(/\.svelte$/, ".js");
|
|
114
|
-
}
|
|
115
|
-
return trimmed;
|
|
116
|
-
}
|
|
117
|
-
async loadComponentMap() {
|
|
118
|
-
if (!this.componentMapPromise) {
|
|
119
|
-
const entryPath = path.join(this.base_path, "entry-ssr.js");
|
|
120
|
-
const entryUrl = url.pathToFileURL(entryPath).href;
|
|
121
|
-
this.componentMapPromise = import(entryUrl).then((mod) => {
|
|
122
|
-
const source = mod.components ?? mod.default ?? {};
|
|
123
|
-
const normalized = {};
|
|
124
|
-
for (const [key, value] of Object.entries(source)) {
|
|
125
|
-
const cleanKey = key.replace(/^\.\//, "");
|
|
126
|
-
normalized[cleanKey] = value;
|
|
127
|
-
if (cleanKey.startsWith("ui/")) {
|
|
128
|
-
normalized[cleanKey.slice(3)] = value;
|
|
129
|
-
}
|
|
130
|
-
if (cleanKey.endsWith(".svelte")) {
|
|
131
|
-
const jsKey = cleanKey.replace(/\.svelte$/, ".js");
|
|
132
|
-
normalized[jsKey] = value;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return normalized;
|
|
136
|
-
}).catch((error) => {
|
|
137
|
-
this.componentMapPromise = null;
|
|
138
|
-
throw error;
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
return this.componentMapPromise;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
37
|
const default_template = `
|
|
145
38
|
<!DOCTYPE html>
|
|
146
39
|
<html lang="en">
|
|
@@ -279,146 +172,10 @@ if (document.readyState === 'loading') {
|
|
|
279
172
|
return html;
|
|
280
173
|
}
|
|
281
174
|
async getTemplate() {
|
|
282
|
-
const file_content = await fs
|
|
175
|
+
const file_content = await fs.readFile(this.html_path, "utf8");
|
|
283
176
|
return file_content;
|
|
284
177
|
}
|
|
285
178
|
}
|
|
286
|
-
const HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
287
|
-
"get",
|
|
288
|
-
"post",
|
|
289
|
-
"put",
|
|
290
|
-
"delete",
|
|
291
|
-
"patch",
|
|
292
|
-
"head",
|
|
293
|
-
"options",
|
|
294
|
-
"trace"
|
|
295
|
-
]);
|
|
296
|
-
function getGlobalPathsMiddleware(openapi) {
|
|
297
|
-
if (!openapi || !openapi.paths) {
|
|
298
|
-
return [];
|
|
299
|
-
}
|
|
300
|
-
const value = openapi.paths["x-middleware"];
|
|
301
|
-
return Array.isArray(value) ? [...value] : [];
|
|
302
|
-
}
|
|
303
|
-
function parseConfigfile(file_content) {
|
|
304
|
-
let config = null;
|
|
305
|
-
try {
|
|
306
|
-
config = yaml.load(file_content);
|
|
307
|
-
} catch (e) {
|
|
308
|
-
console.log(e);
|
|
309
|
-
}
|
|
310
|
-
return config;
|
|
311
|
-
}
|
|
312
|
-
function parse_modules(openapi, inheritedMiddleware = []) {
|
|
313
|
-
const modules_config = openapi.modules || openapi.module;
|
|
314
|
-
if (!modules_config) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
const modules = Object.entries(modules_config).map(([_, module2]) => {
|
|
318
|
-
return module2;
|
|
319
|
-
});
|
|
320
|
-
const globalMiddleware = [...inheritedMiddleware, ...getGlobalPathsMiddleware(openapi)];
|
|
321
|
-
const modules_path = modules.map((module2) => {
|
|
322
|
-
const basePath = module2.basePath || "";
|
|
323
|
-
const baseLayouts = module2.baseLayouts || [];
|
|
324
|
-
const moduleMiddleware = Array.isArray(module2["x-middleware"]) ? module2["x-middleware"] : [];
|
|
325
|
-
const inherited = [...globalMiddleware, ...moduleMiddleware];
|
|
326
|
-
const paths = module2.paths;
|
|
327
|
-
if (!paths) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
const configurations = Object.entries(paths).filter(([path2]) => typeof path2 === "string" && path2.startsWith("/")).map(([path2, method_config]) => {
|
|
331
|
-
return Object.entries(method_config).filter(([method]) => HTTP_METHODS.has(String(method).toLowerCase())).map(([method, config]) => {
|
|
332
|
-
const methodName = String(method);
|
|
333
|
-
return path$1.parsePathConfig(path2, methodName, config, inherited);
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
const routes = configurations.reduce((flat_config, config) => {
|
|
337
|
-
return flat_config.concat(config);
|
|
338
|
-
}, []);
|
|
339
|
-
routes.forEach((route) => {
|
|
340
|
-
route.path = join(basePath, route.path);
|
|
341
|
-
route.layout = baseLayouts.concat(route.layout || []);
|
|
342
|
-
});
|
|
343
|
-
return routes;
|
|
344
|
-
});
|
|
345
|
-
return modules_path.reduce(
|
|
346
|
-
(flat_config, config) => {
|
|
347
|
-
if (!config) {
|
|
348
|
-
return flat_config;
|
|
349
|
-
}
|
|
350
|
-
return flat_config.concat(config);
|
|
351
|
-
},
|
|
352
|
-
[]
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
function parse_paths(openapi, inheritedMiddleware = []) {
|
|
356
|
-
const paths = openapi.paths;
|
|
357
|
-
if (!paths) {
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
const globalMiddleware = [...inheritedMiddleware, ...getGlobalPathsMiddleware(openapi)];
|
|
361
|
-
const configurations = Object.entries(paths).filter(([path2]) => typeof path2 === "string" && path2.startsWith("/")).map(([path2, method_config]) => {
|
|
362
|
-
return Object.entries(method_config).filter(([method]) => HTTP_METHODS.has(String(method).toLowerCase())).map(([method, config]) => {
|
|
363
|
-
const methodName = String(method);
|
|
364
|
-
return path$1.parsePathConfig(path2, methodName, config, globalMiddleware);
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
const routes = configurations.reduce((flat_config, config) => {
|
|
368
|
-
return flat_config.concat(config);
|
|
369
|
-
}, []);
|
|
370
|
-
return routes;
|
|
371
|
-
}
|
|
372
|
-
function isStitchConfig(document) {
|
|
373
|
-
return document && typeof document === "object" && "stitch" in document;
|
|
374
|
-
}
|
|
375
|
-
function isOpenAPIConfig(document) {
|
|
376
|
-
return document && typeof document === "object" && ("paths" in document || "module" in document || "modules" in document);
|
|
377
|
-
}
|
|
378
|
-
async function parse_openapi_config(openapi_config_path) {
|
|
379
|
-
const content = fs.readFileSync(openapi_config_path, "utf8");
|
|
380
|
-
const parsed_config = parseConfigfile(content);
|
|
381
|
-
let openapi_config;
|
|
382
|
-
if (isStitchConfig(parsed_config)) {
|
|
383
|
-
console.log("Detected stitch configuration, building with Node.js stitch engine...");
|
|
384
|
-
try {
|
|
385
|
-
const { StitchEngine } = await import("@noego/stitch");
|
|
386
|
-
const startTime = Date.now();
|
|
387
|
-
const engine = new StitchEngine();
|
|
388
|
-
const result = engine.buildSync(openapi_config_path, { format: "json" });
|
|
389
|
-
if (!result.success) {
|
|
390
|
-
throw new Error(`Stitch build failed: ${result.error}`);
|
|
391
|
-
}
|
|
392
|
-
const buildTime = Date.now() - startTime;
|
|
393
|
-
console.log(`INFO Stitch build completed in ${buildTime} ms – ${parsed_config.stitch ? parsed_config.stitch.length : 0} modules processed`);
|
|
394
|
-
openapi_config = typeof result.data === "string" ? JSON.parse(result.data) : result.data;
|
|
395
|
-
} catch (error) {
|
|
396
|
-
throw new Error(`Failed to process stitch configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
397
|
-
}
|
|
398
|
-
} else if (isOpenAPIConfig(parsed_config)) {
|
|
399
|
-
console.log("Detected regular OpenAPI configuration");
|
|
400
|
-
openapi_config = parsed_config;
|
|
401
|
-
} else {
|
|
402
|
-
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.`);
|
|
403
|
-
}
|
|
404
|
-
const globalPathsMiddleware = getGlobalPathsMiddleware(openapi_config);
|
|
405
|
-
let modules = parse_modules(openapi_config) || [];
|
|
406
|
-
let paths = parse_paths(openapi_config) || [];
|
|
407
|
-
let fallback_layout = openapi_config["x-fallback-layout"] || null;
|
|
408
|
-
let fallback_view = openapi_config["x-fallback-view"] || null;
|
|
409
|
-
const fallback_middleware = Array.isArray(openapi_config["x-fallback-middleware"]) ? [...openapi_config["x-fallback-middleware"]] : [...globalPathsMiddleware];
|
|
410
|
-
let fallback = {
|
|
411
|
-
layout: fallback_layout ? [fallback_layout] : [],
|
|
412
|
-
view: fallback_view,
|
|
413
|
-
middleware: fallback_middleware
|
|
414
|
-
};
|
|
415
|
-
const routes = [...modules, ...paths];
|
|
416
|
-
let config = {
|
|
417
|
-
fallback,
|
|
418
|
-
routes
|
|
419
|
-
};
|
|
420
|
-
return config;
|
|
421
|
-
}
|
|
422
179
|
const defaultViteOptions = {
|
|
423
180
|
appType: "custom",
|
|
424
181
|
root: process.cwd(),
|
|
@@ -446,7 +203,7 @@ class ManifestBuilder {
|
|
|
446
203
|
this.full_options = deepmerge(defaultOptions, this.options);
|
|
447
204
|
}
|
|
448
205
|
async buildManifest() {
|
|
449
|
-
const configuration = await parse_openapi_config(this.openapi_path);
|
|
206
|
+
const configuration = await url_parser.parse_openapi_config(this.openapi_path);
|
|
450
207
|
const component_path = this.full_options.component_dir;
|
|
451
208
|
if (!component_path) {
|
|
452
209
|
throw new Error("Component path is not defined");
|
|
@@ -487,7 +244,7 @@ async function layout_requires_server(route, loader) {
|
|
|
487
244
|
for (const ext of extensions) {
|
|
488
245
|
const loaderFilePath = path.join(dir, `${name}.load${ext}`);
|
|
489
246
|
try {
|
|
490
|
-
if (fs.existsSync(loaderFilePath)) {
|
|
247
|
+
if (fs$1.existsSync(loaderFilePath)) {
|
|
491
248
|
const module2 = await import(url.pathToFileURL(loaderFilePath).href);
|
|
492
249
|
if (typeof (module2 == null ? void 0 : module2.default) === "function") {
|
|
493
250
|
return true;
|
|
@@ -516,7 +273,7 @@ async function view_requires_server(route, loader) {
|
|
|
516
273
|
for (const ext of extensions) {
|
|
517
274
|
const loaderFilePath = path.join(dir, `${name}.load${ext}`);
|
|
518
275
|
try {
|
|
519
|
-
if (fs.existsSync(loaderFilePath)) {
|
|
276
|
+
if (fs$1.existsSync(loaderFilePath)) {
|
|
520
277
|
const module2 = await import(url.pathToFileURL(loaderFilePath).href);
|
|
521
278
|
if (typeof (module2 == null ? void 0 : module2.default) === "function") {
|
|
522
279
|
return true;
|
|
@@ -628,106 +385,6 @@ class ApiAdapter {
|
|
|
628
385
|
};
|
|
629
386
|
}
|
|
630
387
|
}
|
|
631
|
-
class ComponentManager {
|
|
632
|
-
constructor(componentLoader) {
|
|
633
|
-
this.componentLoader = componentLoader;
|
|
634
|
-
}
|
|
635
|
-
async getLayoutComponents(route) {
|
|
636
|
-
const layout_paths = route.layout || [];
|
|
637
|
-
const layouts_components = await Promise.all(layout_paths.map((layout) => {
|
|
638
|
-
console.log("layout path", layout);
|
|
639
|
-
return this.componentLoader.load(layout);
|
|
640
|
-
}));
|
|
641
|
-
return layouts_components;
|
|
642
|
-
}
|
|
643
|
-
async getLayouts(route) {
|
|
644
|
-
const layout_paths = route.layout || [];
|
|
645
|
-
const layouts_components = await Promise.all(layout_paths.map(async (layout_path) => {
|
|
646
|
-
const layout = await this.componentLoader.load(layout_path);
|
|
647
|
-
return layout.default;
|
|
648
|
-
}));
|
|
649
|
-
return layouts_components;
|
|
650
|
-
}
|
|
651
|
-
async getLayoutLoaders(route) {
|
|
652
|
-
const layout_paths = route.layout || [];
|
|
653
|
-
const loaders_from_files = await Promise.all(
|
|
654
|
-
layout_paths.map((layoutPath) => this.resolveLoader(layoutPath))
|
|
655
|
-
);
|
|
656
|
-
const needs_fallback = loaders_from_files.some((loader) => !loader);
|
|
657
|
-
if (needs_fallback) {
|
|
658
|
-
const layout_components = await this.getLayoutComponents(route);
|
|
659
|
-
const old_style_loaders = layout_components.map((layout) => layout.load);
|
|
660
|
-
return loaders_from_files.map(
|
|
661
|
-
(loader, index) => loader || old_style_loaders[index] || null
|
|
662
|
-
);
|
|
663
|
-
}
|
|
664
|
-
return loaders_from_files;
|
|
665
|
-
}
|
|
666
|
-
async getViewComponent(route) {
|
|
667
|
-
return await this.componentLoader.load(route.view);
|
|
668
|
-
}
|
|
669
|
-
async hasLoaders(route) {
|
|
670
|
-
const componentPaths = [...route.layout || [], route.view];
|
|
671
|
-
for (const componentPath of componentPaths) {
|
|
672
|
-
const loader = await this.resolveLoader(componentPath);
|
|
673
|
-
if (loader) {
|
|
674
|
-
return true;
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
return false;
|
|
678
|
-
}
|
|
679
|
-
async getLoaders(route) {
|
|
680
|
-
const layoutPaths = route.layout || [];
|
|
681
|
-
const layouts = await Promise.all(layoutPaths.map((layoutPath) => this.resolveLoader(layoutPath)));
|
|
682
|
-
const view = await this.resolveLoader(route.view);
|
|
683
|
-
return {
|
|
684
|
-
layouts,
|
|
685
|
-
view
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
getLoaderFilePath(componentPath, extension = ".js") {
|
|
689
|
-
if (!componentPath) {
|
|
690
|
-
return null;
|
|
691
|
-
}
|
|
692
|
-
const fullPath = this.componentLoader.getComponentFullPath(componentPath);
|
|
693
|
-
const { dir, name } = path.parse(fullPath);
|
|
694
|
-
return path.join(dir, `${name}.load${extension}`);
|
|
695
|
-
}
|
|
696
|
-
async resolveLoader(componentPath) {
|
|
697
|
-
if (!componentPath) {
|
|
698
|
-
return null;
|
|
699
|
-
}
|
|
700
|
-
const extensions = [".js", ".ts"];
|
|
701
|
-
for (const ext of extensions) {
|
|
702
|
-
const loaderFilePath = this.getLoaderFilePath(componentPath, ext);
|
|
703
|
-
if (!loaderFilePath) {
|
|
704
|
-
continue;
|
|
705
|
-
}
|
|
706
|
-
try {
|
|
707
|
-
console.log(`[ComponentManager] Trying loader path: ${loaderFilePath}`);
|
|
708
|
-
const module2 = await import(url.pathToFileURL(loaderFilePath).href);
|
|
709
|
-
const loader = module2 == null ? void 0 : module2.default;
|
|
710
|
-
console.log(`[ComponentManager] Imported loader module: default=${typeof loader}`);
|
|
711
|
-
if (typeof loader === "function") {
|
|
712
|
-
console.log(`[ComponentManager] Loaded loader function from: ${loaderFilePath}`);
|
|
713
|
-
return loader;
|
|
714
|
-
}
|
|
715
|
-
} catch (error) {
|
|
716
|
-
const code = (error == null ? void 0 : error.code) || (error == null ? void 0 : error.name) || "UNKNOWN_ERROR";
|
|
717
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
718
|
-
console.warn(`[ComponentManager] Loader not found at ${loaderFilePath} (${ext}): ${(error == null ? void 0 : error.message) || code}`);
|
|
719
|
-
continue;
|
|
720
|
-
}
|
|
721
|
-
console.error(`[ComponentManager] Failed to load loader for ${componentPath} (${ext}) at ${loaderFilePath}:`, error);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
return null;
|
|
725
|
-
}
|
|
726
|
-
async getView(route) {
|
|
727
|
-
const view = await this.componentLoader.load(route.view);
|
|
728
|
-
return view.default;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
388
|
const EXTENSION_CANDIDATES = [".js", ".mjs", ".cjs", ".ts", ".tsx"];
|
|
732
389
|
class MiddlewareAdapter {
|
|
733
390
|
constructor(middlewarePath, fallbackPath) {
|
|
@@ -806,17 +463,17 @@ class MiddlewareAdapter {
|
|
|
806
463
|
findExistingFile(basePathWithoutExt) {
|
|
807
464
|
const ext = path.extname(basePathWithoutExt);
|
|
808
465
|
if (ext) {
|
|
809
|
-
return fs.existsSync(basePathWithoutExt) ? basePathWithoutExt : null;
|
|
466
|
+
return fs$1.existsSync(basePathWithoutExt) ? basePathWithoutExt : null;
|
|
810
467
|
}
|
|
811
468
|
const directCandidates = EXTENSION_CANDIDATES.map((extCandidate) => `${basePathWithoutExt}${extCandidate}`);
|
|
812
469
|
for (const candidate of directCandidates) {
|
|
813
|
-
if (fs.existsSync(candidate)) {
|
|
470
|
+
if (fs$1.existsSync(candidate)) {
|
|
814
471
|
return candidate;
|
|
815
472
|
}
|
|
816
473
|
}
|
|
817
474
|
const indexCandidates = EXTENSION_CANDIDATES.map((extCandidate) => path.join(basePathWithoutExt, `index${extCandidate}`));
|
|
818
475
|
for (const candidate of indexCandidates) {
|
|
819
|
-
if (fs.existsSync(candidate)) {
|
|
476
|
+
if (fs$1.existsSync(candidate)) {
|
|
820
477
|
return candidate;
|
|
821
478
|
}
|
|
822
479
|
}
|
|
@@ -910,20 +567,6 @@ class MiddlewareAdapter {
|
|
|
910
567
|
return ordered;
|
|
911
568
|
}
|
|
912
569
|
}
|
|
913
|
-
function makeUrlParser(pattern) {
|
|
914
|
-
const parser = new pathToRegex(pattern);
|
|
915
|
-
return (pathname) => {
|
|
916
|
-
const result = parser.match(pathname);
|
|
917
|
-
return result || null;
|
|
918
|
-
};
|
|
919
|
-
}
|
|
920
|
-
function initialize_route_matchers(routes) {
|
|
921
|
-
return routes.map((route) => {
|
|
922
|
-
const pattern = route.path;
|
|
923
|
-
const parser = makeUrlParser(pattern);
|
|
924
|
-
return { pattern, parser };
|
|
925
|
-
});
|
|
926
|
-
}
|
|
927
570
|
class ServerAdapter {
|
|
928
571
|
}
|
|
929
572
|
class ExpressServerAdapter extends ServerAdapter {
|
|
@@ -985,7 +628,7 @@ class ExpressServerAdapter extends ServerAdapter {
|
|
|
985
628
|
async handleRoutes(routes, manifest) {
|
|
986
629
|
const transformedRoutes = this.transformRoutesForClient(routes);
|
|
987
630
|
this.clientRoutes = transformedRoutes;
|
|
988
|
-
const matchers = initialize_route_matchers(transformedRoutes);
|
|
631
|
+
const matchers = url_parser.initialize_route_matchers(transformedRoutes);
|
|
989
632
|
this.server.use((req, res, next) => {
|
|
990
633
|
(async () => {
|
|
991
634
|
if (res.headersSent) {
|
|
@@ -1252,7 +895,7 @@ view: ${route.view}</pre>`;
|
|
|
1252
895
|
}
|
|
1253
896
|
function pathExistsSync(p) {
|
|
1254
897
|
try {
|
|
1255
|
-
return fs.existsSync(p);
|
|
898
|
+
return fs$1.existsSync(p);
|
|
1256
899
|
} catch {
|
|
1257
900
|
return false;
|
|
1258
901
|
}
|
|
@@ -1319,7 +962,7 @@ async function createServer(app, options) {
|
|
|
1319
962
|
vite = await createViteServer(options.viteOptions || full_options.viteOptions);
|
|
1320
963
|
console.log(`Vite server created options
|
|
1321
964
|
${JSON.stringify(options, null, 2)}`);
|
|
1322
|
-
componentLoader = new ViteComponentLoader(COMPONENT_DIR, vite);
|
|
965
|
+
componentLoader = new url_parser.ViteComponentLoader(COMPONENT_DIR, vite);
|
|
1323
966
|
} else {
|
|
1324
967
|
console.log("Starting Vite in production mode...");
|
|
1325
968
|
const staticDir = path.join(full_options.viteOptions.root, full_options.build_dir);
|
|
@@ -1332,7 +975,7 @@ ${JSON.stringify(options, null, 2)}`);
|
|
|
1332
975
|
const componentPath = `/${full_options.component_dir}`;
|
|
1333
976
|
app.use(componentPath, express.static(COMPONENT_DIR));
|
|
1334
977
|
console.log(`Serving components at ${componentPath} from ${COMPONENT_DIR}`);
|
|
1335
|
-
componentLoader = new ProdComponentLoader(COMPONENT_DIR);
|
|
978
|
+
componentLoader = new url_parser.ProdComponentLoader(COMPONENT_DIR);
|
|
1336
979
|
}
|
|
1337
980
|
const manifest = await new ManifestBuilder(
|
|
1338
981
|
full_options.open_api_path,
|
|
@@ -1340,9 +983,9 @@ ${JSON.stringify(options, null, 2)}`);
|
|
|
1340
983
|
full_options
|
|
1341
984
|
).buildManifest();
|
|
1342
985
|
const htmlRenderer = getRenderer(root, full_options.renderer, isProd);
|
|
1343
|
-
const server_config = await parse_openapi_config(full_options.open_api_path);
|
|
986
|
+
const server_config = await url_parser.parse_openapi_config(full_options.open_api_path);
|
|
1344
987
|
const routeDefs = server_config.routes;
|
|
1345
|
-
const manager = new ComponentManager(componentLoader);
|
|
988
|
+
const manager = new url_parser.ComponentManager(componentLoader);
|
|
1346
989
|
const api_adapter = new ApiAdapter(manager);
|
|
1347
990
|
let middlewareRoot;
|
|
1348
991
|
if (full_options.middleware_path) {
|
|
@@ -1374,7 +1017,7 @@ function getRenderer(root, renderer, isProd) {
|
|
|
1374
1017
|
return new LiveHTMLRender(ensureFullPath(root, renderer));
|
|
1375
1018
|
} else if (typeof renderer === "string" && isProd) {
|
|
1376
1019
|
const html = ensureFullPath(root, renderer);
|
|
1377
|
-
const template = fs.readFileSync(html, "utf8");
|
|
1020
|
+
const template = fs$1.readFileSync(html, "utf8");
|
|
1378
1021
|
return new BaseHTMLRender(template);
|
|
1379
1022
|
} else if (renderer instanceof BaseHTMLRender) {
|
|
1380
1023
|
return renderer;
|