reroute-js 0.5.0 → 0.7.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/README.md +142 -0
- package/_/basic/package.json +4 -4
- package/_/basic/src/client/index.html +1 -1
- package/_/basic/src/index.ts +1 -3
- package/_/blog/package.json +4 -4
- package/_/blog/src/client/App.tsx +1 -0
- package/_/blog/src/client/index.html +1 -1
- package/_/blog/src/client/routes/blog/content/1-hello-world.tsx +1 -1
- package/_/blog/src/client/routes/blog/content/3-markdown-with-syntax-highlighting.mdx +213 -0
- package/_/blog/src/client/routes/blog/content/4-content-in-markdown.md +143 -0
- package/_/blog/src/client/routes/blog/content/5-mdx-with-components.mdx +267 -0
- package/_/blog/src/client/routes/blog/index.tsx +59 -0
- package/_/blog/src/client/routes/client.tsx +564 -0
- package/_/blog/src/client/routes/docs.tsx +670 -0
- package/_/blog/src/client/routes/index.tsx +37 -0
- package/_/blog/src/client/routes/markdown-demo.md +169 -0
- package/_/blog/src/client/routes/markdown.tsx +160 -0
- package/_/blog/src/index.ts +5 -2
- package/_/store/package.json +4 -4
- package/_/store/src/client/index.html +1 -1
- package/_/store/src/index.ts +1 -1
- package/cli/bin.d.ts +1 -1
- package/cli/bin.js +1313 -74
- package/cli/bin.js.map +13 -7
- package/cli/index.d.ts +1 -1
- package/cli/index.js +428 -17
- package/cli/index.js.map +6 -3
- package/cli/src/cli.d.ts +1 -1
- package/cli/src/commands/boot.d.ts +1 -1
- package/cli/src/commands/build.d.ts +19 -0
- package/cli/src/commands/build.d.ts.map +1 -0
- package/cli/src/commands/dev.d.ts +18 -0
- package/cli/src/commands/dev.d.ts.map +1 -0
- package/cli/src/commands/gen.d.ts +1 -1
- package/cli/src/commands/gen.d.ts.map +1 -1
- package/cli/src/commands/init.d.ts +1 -1
- package/cli/src/commands/start.d.ts +19 -0
- package/cli/src/commands/start.d.ts.map +1 -0
- package/cli/src/libs/index.d.ts +4 -1
- package/cli/src/libs/index.d.ts.map +1 -1
- package/cli/src/libs/log.d.ts +46 -0
- package/cli/src/libs/log.d.ts.map +1 -0
- package/cli/src/libs/markdown-processor.d.ts +59 -0
- package/cli/src/libs/markdown-processor.d.ts.map +1 -0
- package/cli/src/libs/markdown.d.ts +33 -0
- package/cli/src/libs/markdown.d.ts.map +1 -0
- package/cli/src/libs/tailwind.d.ts +1 -1
- package/cli/src/libs/version.d.ts +1 -1
- package/core/index.d.ts +1 -1
- package/core/index.js +4 -4
- package/core/index.js.map +2 -2
- package/core/src/bundler/hash.d.ts +1 -1
- package/core/src/bundler/index.d.ts +1 -1
- package/core/src/bundler/transpile.d.ts +1 -1
- package/core/src/content/discovery.d.ts +1 -1
- package/core/src/content/index.d.ts +1 -1
- package/core/src/content/metadata.d.ts +1 -1
- package/core/src/content/registry.d.ts +1 -1
- package/core/src/index.d.ts +1 -1
- package/core/src/ssr/data.d.ts +1 -1
- package/core/src/ssr/index.d.ts +1 -1
- package/core/src/ssr/modules.d.ts +1 -1
- package/core/src/ssr/render.d.ts +1 -1
- package/core/src/ssr/seed.d.ts +1 -1
- package/core/src/template/html.d.ts +1 -1
- package/core/src/template/index.d.ts +1 -1
- package/core/src/types.d.ts +1 -1
- package/core/src/utils/cache.d.ts +1 -1
- package/core/src/utils/compression.d.ts +1 -1
- package/core/src/utils/index.d.ts +1 -1
- package/core/src/utils/mime.d.ts +1 -1
- package/core/src/utils/path.d.ts +1 -1
- package/elysia/index.d.ts +1 -1
- package/elysia/index.js +4 -4
- package/elysia/index.js.map +2 -2
- package/elysia/src/index.d.ts +1 -1
- package/elysia/src/libs/http.d.ts +1 -1
- package/elysia/src/libs/image.d.ts +1 -1
- package/elysia/src/plugin.d.ts +1 -1
- package/elysia/src/routes/artifacts.d.ts +1 -1
- package/elysia/src/routes/content.d.ts +1 -1
- package/elysia/src/routes/dev.d.ts +1 -1
- package/elysia/src/routes/image.d.ts +1 -1
- package/elysia/src/routes/ssr.d.ts +1 -1
- package/elysia/src/routes/static.d.ts +1 -1
- package/elysia/src/types.d.ts +1 -1
- package/package.json +22 -9
- package/react/index.d.ts +1 -1
- package/react/index.js +141 -36
- package/react/index.js.map +7 -6
- package/react/src/components/ClientOnly.d.ts +1 -1
- package/react/src/components/ContentRoute.d.ts +1 -1
- package/react/src/components/ContentRoute.d.ts.map +1 -1
- package/react/src/components/Image.d.ts +1 -1
- package/react/src/components/Link.d.ts +1 -1
- package/react/src/components/Link.d.ts.map +1 -1
- package/react/src/components/Markdown.d.ts +89 -0
- package/react/src/components/Markdown.d.ts.map +1 -0
- package/react/src/components/Outlet.d.ts +1 -1
- package/react/src/components/index.d.ts +2 -1
- package/react/src/components/index.d.ts.map +1 -1
- package/react/src/hooks/index.d.ts +1 -1
- package/react/src/hooks/useContent.d.ts +1 -1
- package/react/src/hooks/useData.d.ts +1 -1
- package/react/src/hooks/useNavigate.d.ts +1 -1
- package/react/src/hooks/useParams.d.ts +1 -1
- package/react/src/hooks/useRouter.d.ts +1 -1
- package/react/src/hooks/useSearchParams.d.ts +1 -1
- package/react/src/index.d.ts +1 -1
- package/react/src/providers/ContentProvider.d.ts +1 -1
- package/react/src/providers/RerouteProvider.d.ts +1 -1
- package/react/src/providers/RouterProvider.d.ts +1 -1
- package/react/src/providers/RouterProvider.d.ts.map +1 -1
- package/react/src/providers/index.d.ts +1 -1
- package/react/src/types/any.d.ts +1 -1
- package/react/src/types/index.d.ts +1 -1
- package/react/src/types/router.d.ts +1 -1
- package/react/src/utils/content.d.ts +1 -1
- package/react/src/utils/head.d.ts +1 -1
- package/react/src/utils/index.d.ts +1 -1
- package/_/blog/src/client/components/Counter.tsx +0 -14
package/cli/bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
3
|
/**
|
|
4
|
-
* reroute-js v0.
|
|
4
|
+
* reroute-js v0.7.0
|
|
5
5
|
*
|
|
6
6
|
* @license MIT
|
|
7
7
|
* @copyright 2025 stewones <hi@stewan.io>
|
|
@@ -9,7 +9,23 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Built with Bun <3
|
|
11
11
|
*/
|
|
12
|
+
import { createRequire } from "node:module";
|
|
13
|
+
var __create = Object.create;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
12
15
|
var __defProp = Object.defineProperty;
|
|
16
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
17
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
19
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
20
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
21
|
+
for (let key of __getOwnPropNames(mod))
|
|
22
|
+
if (!__hasOwnProp.call(to, key))
|
|
23
|
+
__defProp(to, key, {
|
|
24
|
+
get: () => mod[key],
|
|
25
|
+
enumerable: true
|
|
26
|
+
});
|
|
27
|
+
return to;
|
|
28
|
+
};
|
|
13
29
|
var __export = (target, all) => {
|
|
14
30
|
for (var name in all)
|
|
15
31
|
__defProp(target, name, {
|
|
@@ -20,6 +36,7 @@ var __export = (target, all) => {
|
|
|
20
36
|
});
|
|
21
37
|
};
|
|
22
38
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
39
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
23
40
|
|
|
24
41
|
// packages/cli/src/libs/version.ts
|
|
25
42
|
import path from "node:path";
|
|
@@ -30,7 +47,7 @@ async function getVersionString() {
|
|
|
30
47
|
}
|
|
31
48
|
async function getVersion() {
|
|
32
49
|
if (true) {
|
|
33
|
-
return "0.
|
|
50
|
+
return "0.7.0";
|
|
34
51
|
}
|
|
35
52
|
const possiblePaths = [
|
|
36
53
|
path.join(import.meta.dir, "../../../../package.json"),
|
|
@@ -48,7 +65,7 @@ async function getVersion() {
|
|
|
48
65
|
}
|
|
49
66
|
async function getCommit() {
|
|
50
67
|
if (true) {
|
|
51
|
-
return "
|
|
68
|
+
return "4b119c0";
|
|
52
69
|
}
|
|
53
70
|
return "dev";
|
|
54
71
|
}
|
|
@@ -113,15 +130,53 @@ async function scaffoldProject(options) {
|
|
|
113
130
|
console.log(`
|
|
114
131
|
\uD83D\uDCE6 Template: ${template}
|
|
115
132
|
`);
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
133
|
+
const possibleTemplatePaths = [
|
|
134
|
+
join(import.meta.dir, "..", "_", template),
|
|
135
|
+
join(import.meta.dir, "..", "..", "..", "_", template)
|
|
136
|
+
];
|
|
137
|
+
let templatePath;
|
|
138
|
+
for (const path2 of possibleTemplatePaths) {
|
|
139
|
+
if (existsSync(path2)) {
|
|
140
|
+
templatePath = path2;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!templatePath) {
|
|
145
|
+
console.error(`Error: Template directory not found for template "${template}"`);
|
|
146
|
+
console.error(`Tried paths: ${possibleTemplatePaths.join(", ")}`);
|
|
119
147
|
process.exit(1);
|
|
120
148
|
}
|
|
149
|
+
const possibleExamplesPaths = [
|
|
150
|
+
join(import.meta.dir, "..", "..", "..", "..", "examples", template, "src"),
|
|
151
|
+
join(import.meta.dir, "..", "..", "..", "..", "..", "examples", template, "src")
|
|
152
|
+
];
|
|
153
|
+
let examplesPath;
|
|
154
|
+
for (const path2 of possibleExamplesPaths) {
|
|
155
|
+
if (existsSync(path2)) {
|
|
156
|
+
examplesPath = path2;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
121
160
|
await mkdir(projectPath, { recursive: true });
|
|
122
161
|
await copyTemplateFiles(templatePath, projectPath, {
|
|
123
162
|
PROJECT_NAME: projectName
|
|
124
163
|
});
|
|
164
|
+
const sourceVariables = {
|
|
165
|
+
PROJECT_NAME: projectName
|
|
166
|
+
};
|
|
167
|
+
if (examplesPath) {
|
|
168
|
+
await copySourceFiles(examplesPath, join(projectPath, "src"), sourceVariables);
|
|
169
|
+
} else {
|
|
170
|
+
const templateSrcPath = join(templatePath, "src");
|
|
171
|
+
if (existsSync(templateSrcPath)) {
|
|
172
|
+
await copySourceFiles(templateSrcPath, join(projectPath, "src"), sourceVariables);
|
|
173
|
+
} else {
|
|
174
|
+
console.error(`Error: No src directory found for template "${template}"`);
|
|
175
|
+
console.error(`Tried examples paths: ${possibleExamplesPaths.join(", ")}`);
|
|
176
|
+
console.error(`Tried template path: ${templateSrcPath}`);
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
125
180
|
console.log(`\uD83D\uDCE5 Installing dependencies...
|
|
126
181
|
`);
|
|
127
182
|
const proc = Bun.spawn(["bun", "install"], {
|
|
@@ -135,6 +190,9 @@ async function scaffoldProject(options) {
|
|
|
135
190
|
async function copyTemplateFiles(templatePath, targetPath, variables) {
|
|
136
191
|
const entries = await readdir(templatePath, { withFileTypes: true });
|
|
137
192
|
for (const entry of entries) {
|
|
193
|
+
if (entry.isDirectory() && entry.name === "src") {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
138
196
|
const sourcePath = join(templatePath, entry.name);
|
|
139
197
|
const destPath = join(targetPath, entry.name);
|
|
140
198
|
if (entry.isDirectory()) {
|
|
@@ -151,6 +209,34 @@ async function copyTemplateFiles(templatePath, targetPath, variables) {
|
|
|
151
209
|
}
|
|
152
210
|
}
|
|
153
211
|
}
|
|
212
|
+
function applyVariableReplacements(content, fileName, variables) {
|
|
213
|
+
const shouldReplaceVariables = VARIABLE_REPLACEMENT_PATTERNS.some((pattern) => pattern.test(fileName));
|
|
214
|
+
if (!shouldReplaceVariables) {
|
|
215
|
+
return content;
|
|
216
|
+
}
|
|
217
|
+
let processedContent = content;
|
|
218
|
+
if (/\.html$/i.test(fileName)) {
|
|
219
|
+
if (variables.PROJECT_NAME) {
|
|
220
|
+
processedContent = processedContent.replace(/<title>.*?<\/title>/i, `<title>${variables.PROJECT_NAME}</title>`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return processedContent;
|
|
224
|
+
}
|
|
225
|
+
async function copySourceFiles(sourcePath, targetPath, variables) {
|
|
226
|
+
const entries = await readdir(sourcePath, { withFileTypes: true });
|
|
227
|
+
await mkdir(targetPath, { recursive: true });
|
|
228
|
+
for (const entry of entries) {
|
|
229
|
+
const sourceEntryPath = join(sourcePath, entry.name);
|
|
230
|
+
const targetEntryPath = join(targetPath, entry.name);
|
|
231
|
+
if (entry.isDirectory()) {
|
|
232
|
+
await copySourceFiles(sourceEntryPath, targetEntryPath, variables);
|
|
233
|
+
} else if (entry.isFile()) {
|
|
234
|
+
const content = await readFile(sourceEntryPath, "utf-8");
|
|
235
|
+
const processedContent = variables ? applyVariableReplacements(content, entry.name, variables) : content;
|
|
236
|
+
await writeFile(targetEntryPath, processedContent);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
154
240
|
function printSuccess(projectName, template) {
|
|
155
241
|
console.log(`
|
|
156
242
|
\uD83C\uDFCE️ Project created successfully!
|
|
@@ -203,21 +289,377 @@ async function printHelp() {
|
|
|
203
289
|
console.log(" reroute init my-blog --template blog");
|
|
204
290
|
console.log(" reroute init my-store --template store");
|
|
205
291
|
}
|
|
292
|
+
var VARIABLE_REPLACEMENT_PATTERNS;
|
|
206
293
|
var init_init = __esm(() => {
|
|
207
294
|
init_version();
|
|
295
|
+
VARIABLE_REPLACEMENT_PATTERNS = [
|
|
296
|
+
/\.html$/i
|
|
297
|
+
];
|
|
208
298
|
});
|
|
209
299
|
|
|
300
|
+
// packages/cli/src/libs/markdown.ts
|
|
301
|
+
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
302
|
+
import { dirname, join as join2 } from "node:path";
|
|
303
|
+
function isPackageAvailable(cwd, packageName) {
|
|
304
|
+
let currentDir = cwd;
|
|
305
|
+
for (let i = 0;i < 5; i++) {
|
|
306
|
+
const packageJsonPath = join2(currentDir, "package.json");
|
|
307
|
+
if (existsSync2(packageJsonPath)) {
|
|
308
|
+
try {
|
|
309
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
310
|
+
const deps = {
|
|
311
|
+
...packageJson.dependencies,
|
|
312
|
+
...packageJson.devDependencies,
|
|
313
|
+
...packageJson.peerDependencies
|
|
314
|
+
};
|
|
315
|
+
if (packageName in deps) {
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
} catch {}
|
|
319
|
+
}
|
|
320
|
+
const parentDir = dirname(currentDir);
|
|
321
|
+
if (parentDir === currentDir) {
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
currentDir = parentDir;
|
|
325
|
+
}
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
function isReactMarkdownAvailable(cwd) {
|
|
329
|
+
return isPackageAvailable(cwd, "react-markdown");
|
|
330
|
+
}
|
|
331
|
+
function isShikiAvailable(cwd) {
|
|
332
|
+
return isPackageAvailable(cwd, "@shikijs/rehype");
|
|
333
|
+
}
|
|
334
|
+
function isRemarkGfmAvailable(cwd) {
|
|
335
|
+
return isPackageAvailable(cwd, "remark-gfm");
|
|
336
|
+
}
|
|
337
|
+
function isMdxAvailable(cwd) {
|
|
338
|
+
return isPackageAvailable(cwd, "@mdx-js/mdx");
|
|
339
|
+
}
|
|
340
|
+
function getMarkdownConfig(cwd) {
|
|
341
|
+
const hasReactMarkdown = isReactMarkdownAvailable(cwd);
|
|
342
|
+
const hasShiki = isShikiAvailable(cwd);
|
|
343
|
+
const hasRemarkGfm = isRemarkGfmAvailable(cwd);
|
|
344
|
+
const hasMdx = isMdxAvailable(cwd);
|
|
345
|
+
return {
|
|
346
|
+
hasReactMarkdown,
|
|
347
|
+
hasShiki,
|
|
348
|
+
hasRemarkGfm,
|
|
349
|
+
hasMdx,
|
|
350
|
+
isConfigured: hasReactMarkdown
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function logMarkdownStatus(cwd) {
|
|
354
|
+
const config = getMarkdownConfig(cwd);
|
|
355
|
+
if (config.isConfigured) {
|
|
356
|
+
console.log("[reroute/markdown] Markdown rendering available");
|
|
357
|
+
if (config.hasShiki) {
|
|
358
|
+
console.log("[reroute/markdown] ✓ Shiki syntax highlighting enabled");
|
|
359
|
+
}
|
|
360
|
+
if (config.hasRemarkGfm) {
|
|
361
|
+
console.log("[reroute/markdown] ✓ GitHub Flavored Markdown enabled");
|
|
362
|
+
}
|
|
363
|
+
if (config.hasMdx) {
|
|
364
|
+
console.log("[reroute/markdown] ✓ MDX compiler enabled (JSX in markdown)");
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function checkMarkdownIfConfigured(cwd) {
|
|
369
|
+
try {
|
|
370
|
+
const config = getMarkdownConfig(cwd);
|
|
371
|
+
if (config.isConfigured) {
|
|
372
|
+
logMarkdownStatus(cwd);
|
|
373
|
+
}
|
|
374
|
+
return config.isConfigured;
|
|
375
|
+
} catch (e) {
|
|
376
|
+
console.warn("[reroute/markdown] check failed:", e);
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
var init_markdown = () => {};
|
|
381
|
+
|
|
382
|
+
// packages/cli/src/libs/markdown-processor.ts
|
|
383
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
384
|
+
import { basename, dirname as dirname2, extname, join as join3 } from "node:path";
|
|
385
|
+
function parseFrontmatter(content) {
|
|
386
|
+
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
|
|
387
|
+
const match = content.match(frontmatterRegex);
|
|
388
|
+
if (!match) {
|
|
389
|
+
return { data: {}, content };
|
|
390
|
+
}
|
|
391
|
+
const [, frontmatterText, markdownContent] = match;
|
|
392
|
+
const data = {};
|
|
393
|
+
const lines = frontmatterText.split(`
|
|
394
|
+
`);
|
|
395
|
+
for (const line of lines) {
|
|
396
|
+
const colonIndex = line.indexOf(":");
|
|
397
|
+
if (colonIndex === -1)
|
|
398
|
+
continue;
|
|
399
|
+
const key = line.slice(0, colonIndex).trim();
|
|
400
|
+
let value = line.slice(colonIndex + 1).trim();
|
|
401
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
402
|
+
value = value.slice(1, -1);
|
|
403
|
+
}
|
|
404
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
405
|
+
data[key] = value.slice(1, -1).split(",").map((v) => v.trim().replace(/^["']|["']$/g, ""));
|
|
406
|
+
} else if (value === "true" || value === "false") {
|
|
407
|
+
data[key] = value === "true";
|
|
408
|
+
} else if (!Number.isNaN(Number(value))) {
|
|
409
|
+
data[key] = Number(value);
|
|
410
|
+
} else {
|
|
411
|
+
data[key] = value;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return { data, content: markdownContent };
|
|
415
|
+
}
|
|
416
|
+
function hasJSXSyntax(content) {
|
|
417
|
+
const jsxPatterns = [
|
|
418
|
+
/<[A-Z][a-zA-Z0-9]*/,
|
|
419
|
+
/import\s+{[^}]+}\s+from/,
|
|
420
|
+
/import\s+\w+\s+from/,
|
|
421
|
+
/export\s+(default|const|function)/,
|
|
422
|
+
/<\w+\s+\w+={/
|
|
423
|
+
];
|
|
424
|
+
return jsxPatterns.some((pattern) => pattern.test(content));
|
|
425
|
+
}
|
|
426
|
+
function processMarkdownFile(filePath) {
|
|
427
|
+
const rawContent = readFileSync2(filePath, "utf-8");
|
|
428
|
+
const { data, content } = parseFrontmatter(rawContent);
|
|
429
|
+
const hasJSX = hasJSXSyntax(content);
|
|
430
|
+
return {
|
|
431
|
+
frontmatter: data,
|
|
432
|
+
content,
|
|
433
|
+
rawContent,
|
|
434
|
+
hasJSX
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
function isMdxAvailable2(cwd) {
|
|
438
|
+
let currentDir = cwd;
|
|
439
|
+
for (let i = 0;i < 5; i++) {
|
|
440
|
+
const packageJsonPath = join3(currentDir, "package.json");
|
|
441
|
+
if (existsSync3(packageJsonPath)) {
|
|
442
|
+
try {
|
|
443
|
+
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
444
|
+
const deps = {
|
|
445
|
+
...packageJson.dependencies,
|
|
446
|
+
...packageJson.devDependencies,
|
|
447
|
+
...packageJson.peerDependencies
|
|
448
|
+
};
|
|
449
|
+
if ("@mdx-js/mdx" in deps) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
} catch {}
|
|
453
|
+
}
|
|
454
|
+
const parentDir = dirname2(currentDir);
|
|
455
|
+
if (parentDir === currentDir) {
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
currentDir = parentDir;
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
async function compileMdx(content, cwd, options = {}) {
|
|
463
|
+
if (!isMdxAvailable2(cwd)) {
|
|
464
|
+
console.warn("[reroute/mdx] @mdx-js/mdx not installed. Install with: bun add @mdx-js/mdx");
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
try {
|
|
468
|
+
let compile;
|
|
469
|
+
const pathsToTry = [
|
|
470
|
+
join3(cwd, "node_modules/@mdx-js/mdx"),
|
|
471
|
+
join3(cwd, "../node_modules/@mdx-js/mdx"),
|
|
472
|
+
join3(cwd, "../../node_modules/@mdx-js/mdx"),
|
|
473
|
+
join3(cwd, "../../../node_modules/@mdx-js/mdx")
|
|
474
|
+
];
|
|
475
|
+
for (const mdxPath of pathsToTry) {
|
|
476
|
+
try {
|
|
477
|
+
const mdxModule = __require(mdxPath);
|
|
478
|
+
compile = mdxModule.compile;
|
|
479
|
+
break;
|
|
480
|
+
} catch {}
|
|
481
|
+
}
|
|
482
|
+
if (!compile) {
|
|
483
|
+
console.error("[reroute/mdx] Could not load @mdx-js/mdx from any path");
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
const { enableGfm = true, theme = "github-dark" } = options;
|
|
487
|
+
const remarkPlugins = [];
|
|
488
|
+
const rehypePlugins = [];
|
|
489
|
+
if (enableGfm) {
|
|
490
|
+
const gfmPathsToTry = [
|
|
491
|
+
join3(cwd, "node_modules/remark-gfm"),
|
|
492
|
+
join3(cwd, "../node_modules/remark-gfm"),
|
|
493
|
+
join3(cwd, "../../node_modules/remark-gfm"),
|
|
494
|
+
join3(cwd, "../../../node_modules/remark-gfm")
|
|
495
|
+
];
|
|
496
|
+
let remarkGfm = null;
|
|
497
|
+
for (const gfmPath of gfmPathsToTry) {
|
|
498
|
+
try {
|
|
499
|
+
remarkGfm = __require(gfmPath);
|
|
500
|
+
break;
|
|
501
|
+
} catch {}
|
|
502
|
+
}
|
|
503
|
+
if (remarkGfm) {
|
|
504
|
+
remarkPlugins.push(remarkGfm.default || remarkGfm);
|
|
505
|
+
} else {
|
|
506
|
+
console.warn("[reroute/mdx] remark-gfm not available, skipping");
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
const shikiPathsToTry = [
|
|
510
|
+
join3(cwd, "node_modules/@shikijs/rehype"),
|
|
511
|
+
join3(cwd, "../node_modules/@shikijs/rehype"),
|
|
512
|
+
join3(cwd, "../../node_modules/@shikijs/rehype"),
|
|
513
|
+
join3(cwd, "../../../node_modules/@shikijs/rehype")
|
|
514
|
+
];
|
|
515
|
+
let rehypeShiki = null;
|
|
516
|
+
for (const shikiPath of shikiPathsToTry) {
|
|
517
|
+
try {
|
|
518
|
+
rehypeShiki = __require(shikiPath);
|
|
519
|
+
break;
|
|
520
|
+
} catch {}
|
|
521
|
+
}
|
|
522
|
+
if (rehypeShiki) {
|
|
523
|
+
rehypePlugins.push([rehypeShiki.default || rehypeShiki, { theme }]);
|
|
524
|
+
} else {
|
|
525
|
+
console.warn("[reroute/mdx] @shikijs/rehype not available, skipping highlighting");
|
|
526
|
+
}
|
|
527
|
+
const result = await compile(content, {
|
|
528
|
+
remarkPlugins,
|
|
529
|
+
rehypePlugins,
|
|
530
|
+
outputFormat: "program",
|
|
531
|
+
development: false
|
|
532
|
+
});
|
|
533
|
+
return String(result);
|
|
534
|
+
} catch (error) {
|
|
535
|
+
console.error("[reroute/mdx] Compilation failed:", error);
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
async function generateMarkdownModule(processed, cwd, options = {}) {
|
|
540
|
+
const { frontmatter, content } = processed;
|
|
541
|
+
const { enableGfm = true, theme = "github-dark", isMdx = false } = options;
|
|
542
|
+
const compiledMdx = await compileMdx(content, cwd, { enableGfm, theme });
|
|
543
|
+
if (compiledMdx) {
|
|
544
|
+
return `// Generated from ${isMdx ? "MDX" : "Markdown"} file with @mdx-js/mdx
|
|
545
|
+
|
|
546
|
+
// MDX compiled content with imports and component
|
|
547
|
+
${compiledMdx}
|
|
548
|
+
|
|
549
|
+
// Add metadata exports
|
|
550
|
+
export const meta = ${JSON.stringify(frontmatter, null, 2)};
|
|
551
|
+
|
|
552
|
+
export const ssr = {
|
|
553
|
+
head: [
|
|
554
|
+
'<meta property="og:type" content="article" />',
|
|
555
|
+
'<meta name="twitter:card" content="summary_large_image" />',
|
|
556
|
+
],
|
|
557
|
+
};
|
|
558
|
+
`;
|
|
559
|
+
}
|
|
560
|
+
console.warn("[reroute/mdx] MDX compile unavailable; falling back to react-markdown");
|
|
561
|
+
const escapedContent = content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
562
|
+
const pluginImports = [];
|
|
563
|
+
const remarkPluginsList = [];
|
|
564
|
+
const rehypePluginsList = [];
|
|
565
|
+
if (enableGfm) {
|
|
566
|
+
pluginImports.push("import remarkGfm from 'remark-gfm';");
|
|
567
|
+
remarkPluginsList.push("remarkGfm");
|
|
568
|
+
}
|
|
569
|
+
const pluginImportsStr = pluginImports.length > 0 ? `${pluginImports.join(`
|
|
570
|
+
`)}
|
|
571
|
+
` : "";
|
|
572
|
+
const remarkPluginsStr = remarkPluginsList.length > 0 ? `remarkPlugins={[${remarkPluginsList.join(", ")}]}` : "";
|
|
573
|
+
const rehypePluginsStr = rehypePluginsList.length > 0 ? `rehypePlugins={[${rehypePluginsList.join(", ")}]}` : "";
|
|
574
|
+
const pluginsPropsStr = [remarkPluginsStr, rehypePluginsStr].filter(Boolean).join(`
|
|
575
|
+
`);
|
|
576
|
+
return `// Generated from markdown file
|
|
577
|
+
import { Markdown } from 'reroute-js/react';
|
|
578
|
+
${pluginImportsStr}
|
|
579
|
+
const meta = ${JSON.stringify(frontmatter, null, 2)};
|
|
580
|
+
|
|
581
|
+
const ssr = {
|
|
582
|
+
head: [
|
|
583
|
+
'<meta property="og:type" content="article" />',
|
|
584
|
+
'<meta name="twitter:card" content="summary_large_image" />',
|
|
585
|
+
],
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
const markdownContent = \`${escapedContent}\`;
|
|
589
|
+
|
|
590
|
+
function MarkdownRoute() {
|
|
591
|
+
return (
|
|
592
|
+
<div>
|
|
593
|
+
<Markdown
|
|
594
|
+
${pluginsPropsStr}
|
|
595
|
+
>
|
|
596
|
+
{markdownContent}
|
|
597
|
+
</Markdown>
|
|
598
|
+
</div>
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export { meta, ssr };
|
|
603
|
+
export default MarkdownRoute;
|
|
604
|
+
`;
|
|
605
|
+
}
|
|
606
|
+
function generatePlainMarkdownModule(processed) {
|
|
607
|
+
const { frontmatter, content } = processed;
|
|
608
|
+
const escapedContent = content.replace(/\\/g, "\\\\").split(String.fromCharCode(96)).join(`\\${String.fromCharCode(96)}`).split("$").join("\\$");
|
|
609
|
+
return `// Generated from markdown file (plain fallback)
|
|
610
|
+
// No markdown renderer detected; showing raw content.
|
|
611
|
+
export const meta = ${JSON.stringify(frontmatter, null, 2)};
|
|
612
|
+
|
|
613
|
+
export const ssr = {
|
|
614
|
+
head: [
|
|
615
|
+
'<meta property="og:type" content="article" />',
|
|
616
|
+
'<meta name="twitter:card" content="summary_large_image" />',
|
|
617
|
+
],
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
const markdownContent = \`${escapedContent}\`;
|
|
621
|
+
|
|
622
|
+
export default function MarkdownFallback() {
|
|
623
|
+
return (
|
|
624
|
+
<div style={{ padding: '1rem' }}>
|
|
625
|
+
{meta?.title && (
|
|
626
|
+
<h1 style={{ fontSize: '1.5rem', fontWeight: 600 }}>{meta.title}</h1>
|
|
627
|
+
)}
|
|
628
|
+
<div style={{
|
|
629
|
+
margin: '0.75rem 0',
|
|
630
|
+
padding: '0.75rem',
|
|
631
|
+
borderLeft: '4px solid #eab308',
|
|
632
|
+
background: '#fefce8',
|
|
633
|
+
color: '#713f12'
|
|
634
|
+
}}>
|
|
635
|
+
<strong>Markdown rendering not configured.</strong>
|
|
636
|
+
<div style={{ marginTop: '0.25rem' }}>
|
|
637
|
+
Install: react-markdown (required), remark-gfm (optional), @mdx-js/mdx (optional), @shikijs/rehype (optional).
|
|
638
|
+
</div>
|
|
639
|
+
</div>
|
|
640
|
+
<pre style={{ whiteSpace: 'pre-wrap', lineHeight: 1.6 }}>{markdownContent}</pre>
|
|
641
|
+
</div>
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
`;
|
|
645
|
+
}
|
|
646
|
+
function isMarkdownFile(filePath) {
|
|
647
|
+
const ext = extname(filePath).toLowerCase();
|
|
648
|
+
return ext === ".md" || ext === ".mdx";
|
|
649
|
+
}
|
|
650
|
+
var init_markdown_processor = () => {};
|
|
651
|
+
|
|
210
652
|
// packages/cli/src/libs/tailwind.ts
|
|
211
653
|
import { spawn } from "node:child_process";
|
|
212
|
-
import { existsSync as
|
|
213
|
-
import { join as
|
|
654
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
|
|
655
|
+
import { join as join4 } from "node:path";
|
|
214
656
|
function isTailwindAvailable(cwd) {
|
|
215
|
-
const packageJsonPath =
|
|
216
|
-
if (!
|
|
657
|
+
const packageJsonPath = join4(cwd, "package.json");
|
|
658
|
+
if (!existsSync4(packageJsonPath)) {
|
|
217
659
|
return false;
|
|
218
660
|
}
|
|
219
661
|
try {
|
|
220
|
-
const packageJson = JSON.parse(
|
|
662
|
+
const packageJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
221
663
|
const deps = {
|
|
222
664
|
...packageJson.dependencies,
|
|
223
665
|
...packageJson.devDependencies
|
|
@@ -228,17 +670,17 @@ function isTailwindAvailable(cwd) {
|
|
|
228
670
|
}
|
|
229
671
|
}
|
|
230
672
|
function getTailwindPaths(cwd) {
|
|
231
|
-
const input =
|
|
232
|
-
const output =
|
|
673
|
+
const input = join4(cwd, "src/client/theme.css");
|
|
674
|
+
const output = join4(cwd, ".reroute/theme.css");
|
|
233
675
|
return { input, output };
|
|
234
676
|
}
|
|
235
677
|
function hasTailwindInput(cwd) {
|
|
236
678
|
const { input } = getTailwindPaths(cwd);
|
|
237
|
-
if (!
|
|
679
|
+
if (!existsSync4(input)) {
|
|
238
680
|
return false;
|
|
239
681
|
}
|
|
240
682
|
try {
|
|
241
|
-
const content =
|
|
683
|
+
const content = readFileSync3(input, "utf-8");
|
|
242
684
|
return content.includes("tailwindcss");
|
|
243
685
|
} catch {
|
|
244
686
|
return false;
|
|
@@ -246,16 +688,16 @@ function hasTailwindInput(cwd) {
|
|
|
246
688
|
}
|
|
247
689
|
function resolveTailwindBin(cwd) {
|
|
248
690
|
const pathsToTry = [
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
691
|
+
join4(cwd, "../node_modules/.bin/tailwindcss"),
|
|
692
|
+
join4(cwd, "../../node_modules/.bin/tailwindcss"),
|
|
693
|
+
join4(cwd, "../../../node_modules/.bin/tailwindcss")
|
|
252
694
|
];
|
|
253
695
|
for (const binPath of pathsToTry) {
|
|
254
|
-
if (
|
|
696
|
+
if (existsSync4(binPath)) {
|
|
255
697
|
return binPath;
|
|
256
698
|
}
|
|
257
699
|
}
|
|
258
|
-
return
|
|
700
|
+
return join4(cwd, "node_modules/.bin/tailwindcss");
|
|
259
701
|
}
|
|
260
702
|
async function buildTailwind(cwd) {
|
|
261
703
|
const { input, output } = getTailwindPaths(cwd);
|
|
@@ -313,12 +755,12 @@ __export(exports_gen, {
|
|
|
313
755
|
});
|
|
314
756
|
import { watch } from "node:fs";
|
|
315
757
|
import { mkdir as mkdir2, readdir as readdir2, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
316
|
-
import { join as
|
|
758
|
+
import { join as join5 } from "node:path";
|
|
317
759
|
import { pathToFileURL } from "node:url";
|
|
318
760
|
async function cleanupOutputDir(cwd) {
|
|
319
761
|
try {
|
|
320
|
-
await rm(
|
|
321
|
-
await mkdir2(
|
|
762
|
+
await rm(join5(cwd, OUTPUT_DIR), { force: true });
|
|
763
|
+
await mkdir2(join5(cwd, OUTPUT_DIR), { recursive: true });
|
|
322
764
|
console.log("[reroute/gen] Cleaned up generated artifacts in .reroute");
|
|
323
765
|
} catch {}
|
|
324
766
|
}
|
|
@@ -326,14 +768,14 @@ async function scanDirectory(dir, base = "") {
|
|
|
326
768
|
const files = [];
|
|
327
769
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
328
770
|
for (const entry of entries) {
|
|
329
|
-
const fullPath =
|
|
330
|
-
const relativePath =
|
|
771
|
+
const fullPath = join5(dir, entry.name);
|
|
772
|
+
const relativePath = join5(base, entry.name);
|
|
331
773
|
if (entry.isDirectory()) {
|
|
332
774
|
if (entry.name === "content")
|
|
333
775
|
continue;
|
|
334
776
|
const nested = await scanDirectory(fullPath, relativePath);
|
|
335
777
|
files.push(...nested);
|
|
336
|
-
} else if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts"))) {
|
|
778
|
+
} else if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts") || entry.name.endsWith(".md") || entry.name.endsWith(".mdx"))) {
|
|
337
779
|
if (relativePath.includes("/content/") || relativePath.startsWith("content/")) {
|
|
338
780
|
continue;
|
|
339
781
|
}
|
|
@@ -348,8 +790,8 @@ async function scan404Files(dir, base = "") {
|
|
|
348
790
|
const files = [];
|
|
349
791
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
350
792
|
for (const entry of entries) {
|
|
351
|
-
const fullPath =
|
|
352
|
-
const relativePath =
|
|
793
|
+
const fullPath = join5(dir, entry.name);
|
|
794
|
+
const relativePath = join5(base, entry.name);
|
|
353
795
|
if (entry.isDirectory()) {
|
|
354
796
|
const nested = await scan404Files(fullPath, relativePath);
|
|
355
797
|
files.push(...nested);
|
|
@@ -361,8 +803,8 @@ async function scan404Files(dir, base = "") {
|
|
|
361
803
|
return files;
|
|
362
804
|
}
|
|
363
805
|
function fileToRoute(filePath) {
|
|
364
|
-
const isLayout = filePath.endsWith("[layout].tsx") || filePath.endsWith("[layout].ts");
|
|
365
|
-
let routePath = filePath.replace(/\.(tsx|ts)$/, "");
|
|
806
|
+
const isLayout = filePath.endsWith("[layout].tsx") || filePath.endsWith("[layout].ts") || filePath.endsWith("[layout].md") || filePath.endsWith("[layout].mdx");
|
|
807
|
+
let routePath = filePath.replace(/\.(tsx|ts|md|mdx)$/, "");
|
|
366
808
|
if (isLayout) {
|
|
367
809
|
routePath = routePath.replace(/[layout]$/, "").replace(/\/$/, "");
|
|
368
810
|
}
|
|
@@ -423,11 +865,20 @@ function generateRouteTree(files) {
|
|
|
423
865
|
notFoundRoutes
|
|
424
866
|
};
|
|
425
867
|
}
|
|
868
|
+
function getImportPath(filePath) {
|
|
869
|
+
const isMarkdown = /\.(md|mdx)$/.test(filePath);
|
|
870
|
+
if (isMarkdown) {
|
|
871
|
+
const pathWithoutExt2 = filePath.replace(/\.(md|mdx)$/, "");
|
|
872
|
+
return `./markdown/${pathWithoutExt2}`;
|
|
873
|
+
}
|
|
874
|
+
const pathWithoutExt = filePath.replace(/\.(tsx|ts)$/, "");
|
|
875
|
+
return `../src/client/routes/${pathWithoutExt}`;
|
|
876
|
+
}
|
|
426
877
|
function generateTypeScript(tree) {
|
|
427
878
|
const imports = [
|
|
428
|
-
...tree.routes.map((r, i) => `import Route${i} from '
|
|
429
|
-
...tree.layouts.map((l, i) => `import Layout${i} from '
|
|
430
|
-
...tree.notFoundRoutes.map((nf, i) => `import NotFound${i} from '
|
|
879
|
+
...tree.routes.map((r, i) => `import Route${i} from '${getImportPath(r.filePath)}';`),
|
|
880
|
+
...tree.layouts.map((l, i) => `import Layout${i} from '${getImportPath(l.filePath)}';`),
|
|
881
|
+
...tree.notFoundRoutes.map((nf, i) => `import NotFound${i} from '${getImportPath(nf.filePath)}';`)
|
|
431
882
|
].join(`
|
|
432
883
|
`);
|
|
433
884
|
const routesArray = tree.routes.map((r, i) => {
|
|
@@ -534,7 +985,7 @@ function matchPattern(pattern: string, pathname: string): Record<string, string>
|
|
|
534
985
|
async function listContentFiles(collectionDir) {
|
|
535
986
|
try {
|
|
536
987
|
const entries = await readdir2(collectionDir, { withFileTypes: true });
|
|
537
|
-
return entries.filter((e) => e.isFile() && /\.(tsx|ts)$/.test(e.name) && !e.name.startsWith("_")).map((e) => e.name);
|
|
988
|
+
return entries.filter((e) => e.isFile() && /\.(tsx|ts|md|mdx)$/.test(e.name) && !e.name.startsWith("_")).map((e) => e.name);
|
|
538
989
|
} catch {
|
|
539
990
|
return [];
|
|
540
991
|
}
|
|
@@ -548,7 +999,7 @@ async function sha8(text) {
|
|
|
548
999
|
return hex.slice(0, 8);
|
|
549
1000
|
}
|
|
550
1001
|
async function buildContentChunks(cwd) {
|
|
551
|
-
const routesRoot =
|
|
1002
|
+
const routesRoot = join5(cwd, ROUTES_DIR);
|
|
552
1003
|
console.log(`[reroute/content] scan ${routesRoot}`);
|
|
553
1004
|
const collections = await readdir2(routesRoot, { withFileTypes: true });
|
|
554
1005
|
const results = [];
|
|
@@ -556,20 +1007,31 @@ async function buildContentChunks(cwd) {
|
|
|
556
1007
|
if (!c.isDirectory())
|
|
557
1008
|
continue;
|
|
558
1009
|
const collection = c.name;
|
|
559
|
-
const contentDir =
|
|
1010
|
+
const contentDir = join5(routesRoot, collection, "content");
|
|
560
1011
|
console.log(`[reroute/content] collection ${collection} dir ${contentDir}`);
|
|
561
1012
|
const files = await listContentFiles(contentDir);
|
|
562
1013
|
console.log(`[reroute/content] files ${files.join(",")}`);
|
|
563
1014
|
if (!files.length)
|
|
564
1015
|
continue;
|
|
565
1016
|
for (const file of files) {
|
|
566
|
-
const name = file.replace(/\.(tsx|ts)$/, "");
|
|
567
|
-
const absSrc =
|
|
1017
|
+
const name = file.replace(/\.(tsx|ts|md|mdx)$/, "");
|
|
1018
|
+
const absSrc = join5(contentDir, file);
|
|
1019
|
+
const isMarkdown = /\.(md|mdx)$/.test(file);
|
|
1020
|
+
const buildSrc = isMarkdown ? join5(cwd, ".reroute", "markdown", collection, "content", `${name}.tsx`) : absSrc;
|
|
1021
|
+
if (isMarkdown) {
|
|
1022
|
+
try {
|
|
1023
|
+
const exists = await Bun.file(buildSrc).exists();
|
|
1024
|
+
if (!exists) {
|
|
1025
|
+
console.warn(`[reroute/content] Converted markdown missing, skipping: ${buildSrc}`);
|
|
1026
|
+
continue;
|
|
1027
|
+
}
|
|
1028
|
+
} catch {}
|
|
1029
|
+
}
|
|
568
1030
|
let code = "";
|
|
569
1031
|
try {
|
|
570
|
-
console.log(`[reroute/content] build ${
|
|
1032
|
+
console.log(`[reroute/content] build ${buildSrc}`);
|
|
571
1033
|
const result = await Bun.build({
|
|
572
|
-
entrypoints: [
|
|
1034
|
+
entrypoints: [buildSrc],
|
|
573
1035
|
target: "browser",
|
|
574
1036
|
format: "esm",
|
|
575
1037
|
splitting: false,
|
|
@@ -587,10 +1049,10 @@ async function buildContentChunks(cwd) {
|
|
|
587
1049
|
continue;
|
|
588
1050
|
}
|
|
589
1051
|
const hash = await sha8(code);
|
|
590
|
-
const chunkRelDir =
|
|
591
|
-
const chunkAbsDir =
|
|
1052
|
+
const chunkRelDir = join5(".reroute", "chunks", collection);
|
|
1053
|
+
const chunkAbsDir = join5(cwd, chunkRelDir);
|
|
592
1054
|
const outFile = `${name}.${hash}.js`;
|
|
593
|
-
const absOut =
|
|
1055
|
+
const absOut = join5(chunkAbsDir, outFile);
|
|
594
1056
|
await mkdir2(chunkAbsDir, { recursive: true });
|
|
595
1057
|
try {
|
|
596
1058
|
const exists = await Bun.file(absOut).exists();
|
|
@@ -599,8 +1061,8 @@ async function buildContentChunks(cwd) {
|
|
|
599
1061
|
} catch {}
|
|
600
1062
|
let meta = {};
|
|
601
1063
|
try {
|
|
602
|
-
console.log(`[reroute/content] meta ${
|
|
603
|
-
const url = `${pathToFileURL(
|
|
1064
|
+
console.log(`[reroute/content] meta ${buildSrc}`);
|
|
1065
|
+
const url = `${pathToFileURL(buildSrc).href}?t=${Date.now()}`;
|
|
604
1066
|
const m = await import(url);
|
|
605
1067
|
meta = m.meta || {};
|
|
606
1068
|
} catch {}
|
|
@@ -640,12 +1102,12 @@ async function buildContentChunks(cwd) {
|
|
|
640
1102
|
lines.push(" return m ? (m as Record<string, any>)[name] : undefined;");
|
|
641
1103
|
lines.push("}");
|
|
642
1104
|
lines.push("");
|
|
643
|
-
await mkdir2(
|
|
644
|
-
await writeFile2(
|
|
1105
|
+
await mkdir2(join5(cwd, ".reroute"), { recursive: true });
|
|
1106
|
+
await writeFile2(join5(cwd, OUTPUT_CONTENT_TS), lines.join(`
|
|
645
1107
|
`), "utf-8");
|
|
646
|
-
console.log(`[reroute/content] wrote ${
|
|
1108
|
+
console.log(`[reroute/content] wrote ${join5(cwd, OUTPUT_CONTENT_TS)}`);
|
|
647
1109
|
const collectionsSet = new Set(results.map((r) => r.collection));
|
|
648
|
-
await mkdir2(
|
|
1110
|
+
await mkdir2(join5(cwd, OUTPUT_COLLECTIONS_DIR), { recursive: true });
|
|
649
1111
|
for (const collection of collectionsSet) {
|
|
650
1112
|
const items = results.filter((r) => r.collection === collection);
|
|
651
1113
|
const js = [];
|
|
@@ -665,31 +1127,100 @@ async function buildContentChunks(cwd) {
|
|
|
665
1127
|
js.push(" return byName[name];");
|
|
666
1128
|
js.push("}");
|
|
667
1129
|
js.push("");
|
|
668
|
-
await writeFile2(
|
|
1130
|
+
await writeFile2(join5(cwd, OUTPUT_COLLECTIONS_DIR, `${collection}.js`), js.join(`
|
|
669
1131
|
`), "utf-8");
|
|
670
|
-
console.log(`[reroute/content] wrote ${
|
|
1132
|
+
console.log(`[reroute/content] wrote ${join5(cwd, OUTPUT_COLLECTIONS_DIR, `${collection}.js`)}`);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
async function preprocessMarkdownFiles(cwd) {
|
|
1136
|
+
console.log("[reroute/markdown] Starting markdown preprocessing...");
|
|
1137
|
+
const routesPath = join5(cwd, ROUTES_DIR);
|
|
1138
|
+
const markdownDir = join5(cwd, ".reroute", "markdown");
|
|
1139
|
+
try {
|
|
1140
|
+
await rm(markdownDir, { force: true, recursive: true });
|
|
1141
|
+
} catch {}
|
|
1142
|
+
const markdownConfig = getMarkdownConfig(cwd);
|
|
1143
|
+
console.log("[reroute/markdown] Config:", markdownConfig);
|
|
1144
|
+
try {
|
|
1145
|
+
await mkdir2(markdownDir, { recursive: true });
|
|
1146
|
+
} catch {}
|
|
1147
|
+
async function scanMarkdown(dir, base = "") {
|
|
1148
|
+
const files = [];
|
|
1149
|
+
try {
|
|
1150
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
1151
|
+
for (const entry of entries) {
|
|
1152
|
+
const fullPath = join5(dir, entry.name);
|
|
1153
|
+
const relativePath = join5(base, entry.name);
|
|
1154
|
+
if (entry.isDirectory()) {
|
|
1155
|
+
const nested = await scanMarkdown(fullPath, relativePath);
|
|
1156
|
+
files.push(...nested);
|
|
1157
|
+
} else if (entry.isFile() && isMarkdownFile(entry.name)) {
|
|
1158
|
+
console.log(`[reroute/markdown] Found markdown file: ${relativePath}`);
|
|
1159
|
+
files.push(relativePath);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
} catch (err) {
|
|
1163
|
+
console.error(`[reroute/markdown] Error scanning ${dir}:`, err);
|
|
1164
|
+
}
|
|
1165
|
+
return files;
|
|
1166
|
+
}
|
|
1167
|
+
console.log(`[reroute/markdown] Scanning ${routesPath} for markdown files...`);
|
|
1168
|
+
const markdownFiles = await scanMarkdown(routesPath);
|
|
1169
|
+
console.log(`[reroute/markdown] Scan complete. Found files:`, markdownFiles);
|
|
1170
|
+
if (markdownFiles.length === 0) {
|
|
1171
|
+
console.log("[reroute/markdown] No markdown files found, skipping preprocessing");
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
console.log(`[reroute/markdown] Found ${markdownFiles.length} markdown file(s)`);
|
|
1175
|
+
await mkdir2(markdownDir, { recursive: true });
|
|
1176
|
+
for (const file of markdownFiles) {
|
|
1177
|
+
const sourcePath = join5(routesPath, file);
|
|
1178
|
+
const targetPath = join5(markdownDir, file.replace(/\.mdx?$/, ".tsx"));
|
|
1179
|
+
try {
|
|
1180
|
+
const processed = processMarkdownFile(sourcePath);
|
|
1181
|
+
const isMdx = file.endsWith(".mdx");
|
|
1182
|
+
let moduleCode;
|
|
1183
|
+
if (markdownConfig.isConfigured) {
|
|
1184
|
+
moduleCode = await generateMarkdownModule(processed, cwd, {
|
|
1185
|
+
enableGfm: markdownConfig.hasRemarkGfm,
|
|
1186
|
+
theme: "github-dark",
|
|
1187
|
+
isMdx
|
|
1188
|
+
});
|
|
1189
|
+
} else {
|
|
1190
|
+
moduleCode = generatePlainMarkdownModule(processed);
|
|
1191
|
+
}
|
|
1192
|
+
const targetDir = join5(markdownDir, file.split("/").slice(0, -1).join("/"));
|
|
1193
|
+
if (targetDir !== markdownDir) {
|
|
1194
|
+
await mkdir2(targetDir, { recursive: true });
|
|
1195
|
+
}
|
|
1196
|
+
await writeFile2(targetPath, moduleCode, "utf-8");
|
|
1197
|
+
console.log(`[reroute/markdown] Processed ${file} -> ${targetPath}`);
|
|
1198
|
+
} catch (error) {
|
|
1199
|
+
console.error(`[reroute/markdown] Failed to process ${file}:`, error);
|
|
1200
|
+
}
|
|
671
1201
|
}
|
|
672
1202
|
}
|
|
673
1203
|
async function generate(cwd) {
|
|
674
1204
|
console.log("[reroute/gen] Starting generation...");
|
|
675
1205
|
await cleanupOutputDir(cwd);
|
|
676
|
-
|
|
1206
|
+
await preprocessMarkdownFiles(cwd);
|
|
1207
|
+
const routesPath = join5(cwd, ROUTES_DIR);
|
|
677
1208
|
try {
|
|
678
1209
|
const files = await scanDirectory(routesPath);
|
|
679
1210
|
const nfFiles = await scan404Files(routesPath);
|
|
680
1211
|
const all = Array.from(new Set([...files, ...nfFiles]));
|
|
681
1212
|
const tree = generateRouteTree(all.map((f) => f.replace(/\\/g, "/")));
|
|
682
1213
|
const ts = generateTypeScript(tree);
|
|
683
|
-
await mkdir2(
|
|
684
|
-
await writeFile2(
|
|
685
|
-
console.log(`[reroute/gen] Generated routes: ${
|
|
1214
|
+
await mkdir2(join5(cwd, ".reroute"), { recursive: true });
|
|
1215
|
+
await writeFile2(join5(cwd, OUTPUT_ROUTES), ts, "utf-8");
|
|
1216
|
+
console.log(`[reroute/gen] Generated routes: ${join5(cwd, OUTPUT_ROUTES)}`);
|
|
686
1217
|
} catch (error) {
|
|
687
1218
|
console.error("[reroute/gen] Failed to generate routes:", error);
|
|
688
1219
|
throw error;
|
|
689
1220
|
}
|
|
690
1221
|
try {
|
|
691
1222
|
await buildContentChunks(cwd);
|
|
692
|
-
console.log(`[reroute/gen] Generated content: ${
|
|
1223
|
+
console.log(`[reroute/gen] Generated content: ${join5(cwd, OUTPUT_CONTENT_TS)} + collections/*.js`);
|
|
693
1224
|
} catch (error) {
|
|
694
1225
|
console.error("[reroute/gen] Failed to generate content:", error);
|
|
695
1226
|
throw error;
|
|
@@ -709,10 +1240,10 @@ async function generate(cwd) {
|
|
|
709
1240
|
indexLines.push("} as const;");
|
|
710
1241
|
indexLines.push("");
|
|
711
1242
|
indexLines.push("export type RerouteArtifacts = typeof artifacts;");
|
|
712
|
-
await writeFile2(
|
|
1243
|
+
await writeFile2(join5(cwd, OUTPUT_INDEX), indexLines.join(`
|
|
713
1244
|
`), "utf-8");
|
|
714
|
-
console.log(`[reroute/gen] Generated index: ${
|
|
715
|
-
console.log("[reroute/gen]
|
|
1245
|
+
console.log(`[reroute/gen] Generated index: ${join5(cwd, OUTPUT_INDEX)}`);
|
|
1246
|
+
console.log("[reroute/gen] Generation complete");
|
|
716
1247
|
}
|
|
717
1248
|
async function gen(args) {
|
|
718
1249
|
const cwd = process.cwd();
|
|
@@ -720,6 +1251,7 @@ async function gen(args) {
|
|
|
720
1251
|
if (!watchMode) {
|
|
721
1252
|
await generate(cwd);
|
|
722
1253
|
await buildTailwindIfConfigured(cwd);
|
|
1254
|
+
checkMarkdownIfConfigured(cwd);
|
|
723
1255
|
return;
|
|
724
1256
|
}
|
|
725
1257
|
console.log("[reroute/gen] Watch mode enabled");
|
|
@@ -727,6 +1259,7 @@ async function gen(args) {
|
|
|
727
1259
|
await generate(cwd);
|
|
728
1260
|
try {
|
|
729
1261
|
await buildTailwindIfConfigured(cwd);
|
|
1262
|
+
checkMarkdownIfConfigured(cwd);
|
|
730
1263
|
} catch {}
|
|
731
1264
|
const notifyReload = async (reason) => {
|
|
732
1265
|
const ports = [
|
|
@@ -745,7 +1278,7 @@ async function gen(args) {
|
|
|
745
1278
|
} catch {}
|
|
746
1279
|
}
|
|
747
1280
|
};
|
|
748
|
-
const routesPath =
|
|
1281
|
+
const routesPath = join5(cwd, ROUTES_DIR);
|
|
749
1282
|
console.log(`[reroute/gen] Watching ${routesPath} for changes...`);
|
|
750
1283
|
let debounce = null;
|
|
751
1284
|
const routesWatcher = watch(routesPath, { recursive: true }, (_ev, filename) => {
|
|
@@ -764,7 +1297,7 @@ async function gen(args) {
|
|
|
764
1297
|
}
|
|
765
1298
|
}, 120);
|
|
766
1299
|
});
|
|
767
|
-
const clientPath =
|
|
1300
|
+
const clientPath = join5(cwd, "src", "client");
|
|
768
1301
|
console.log(`[reroute/gen] Watching ${clientPath} for Tailwind class changes...`);
|
|
769
1302
|
let twDebounce = null;
|
|
770
1303
|
const twWatcher = watch(clientPath, { recursive: true }, (_ev, filename) => {
|
|
@@ -800,6 +1333,8 @@ async function gen(args) {
|
|
|
800
1333
|
}
|
|
801
1334
|
var ROUTES_DIR = "src/client/routes", OUTPUT_DIR = ".reroute", OUTPUT_ROUTES = ".reroute/routes.ts", OUTPUT_CONTENT_TS = ".reroute/content.ts", OUTPUT_COLLECTIONS_DIR = ".reroute/collections", OUTPUT_INDEX = ".reroute/index.ts";
|
|
802
1335
|
var init_gen = __esm(() => {
|
|
1336
|
+
init_markdown();
|
|
1337
|
+
init_markdown_processor();
|
|
803
1338
|
init_tailwind();
|
|
804
1339
|
});
|
|
805
1340
|
|
|
@@ -809,20 +1344,20 @@ __export(exports_boot, {
|
|
|
809
1344
|
default: () => boot
|
|
810
1345
|
});
|
|
811
1346
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
812
|
-
import { join as
|
|
1347
|
+
import { join as join6 } from "node:path";
|
|
813
1348
|
async function boot(_) {
|
|
814
1349
|
const cwd = process.cwd();
|
|
815
1350
|
try {
|
|
816
1351
|
console.log("[reroute/boot] Initializing .reroute directory...");
|
|
817
|
-
await mkdir3(
|
|
818
|
-
await mkdir3(
|
|
819
|
-
await writeFile3(
|
|
1352
|
+
await mkdir3(join6(cwd, OUTPUT_DIR2), { recursive: true });
|
|
1353
|
+
await mkdir3(join6(cwd, OUTPUT_COLLECTIONS_DIR2), { recursive: true });
|
|
1354
|
+
await writeFile3(join6(cwd, OUTPUT_ROUTES2), STUB_ROUTES, "utf-8");
|
|
820
1355
|
console.log(`[reroute/boot] Created stub: ${OUTPUT_ROUTES2}`);
|
|
821
|
-
await writeFile3(
|
|
1356
|
+
await writeFile3(join6(cwd, OUTPUT_CONTENT_TS2), STUB_CONTENT, "utf-8");
|
|
822
1357
|
console.log(`[reroute/boot] Created stub: ${OUTPUT_CONTENT_TS2}`);
|
|
823
|
-
await writeFile3(
|
|
1358
|
+
await writeFile3(join6(cwd, OUTPUT_INDEX2), STUB_INDEX, "utf-8");
|
|
824
1359
|
console.log(`[reroute/boot] Created stub: ${OUTPUT_INDEX2}`);
|
|
825
|
-
console.log("[reroute/boot]
|
|
1360
|
+
console.log("[reroute/boot] Initialization complete");
|
|
826
1361
|
console.log('[reroute/boot] Run "reroute gen" to generate actual routes and content.');
|
|
827
1362
|
} catch (error) {
|
|
828
1363
|
console.error("[reroute/boot] Failed to initialize:", error);
|
|
@@ -866,12 +1401,692 @@ export type RerouteArtifacts = typeof artifacts;
|
|
|
866
1401
|
`;
|
|
867
1402
|
var init_boot = () => {};
|
|
868
1403
|
|
|
1404
|
+
// packages/cli/src/libs/log.ts
|
|
1405
|
+
function colorizeLogPrefix(text) {
|
|
1406
|
+
let colored = text;
|
|
1407
|
+
const sortedPrefixes = Object.entries(PREFIX_COLORS).sort(([a], [b]) => b.length - a.length);
|
|
1408
|
+
for (const [prefix, colorTag] of sortedPrefixes) {
|
|
1409
|
+
colored = colored.replace(new RegExp(`(${prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, "g"), `${colorTag}$1{/}`);
|
|
1410
|
+
}
|
|
1411
|
+
return colored;
|
|
1412
|
+
}
|
|
1413
|
+
function blessedToAnsi(text) {
|
|
1414
|
+
return text.replace(/\{cyan-fg\}/g, "\x1B[36m").replace(/\{blue-fg\}/g, "\x1B[34m").replace(/\{magenta-fg\}/g, "\x1B[35m").replace(/\{yellow-fg\}/g, "\x1B[33m").replace(/\{green-fg\}/g, "\x1B[32m").replace(/\{red-fg\}/g, "\x1B[31m").replace(/\{bright-cyan-fg\}/g, "\x1B[96m").replace(/\{bright-blue-fg\}/g, "\x1B[94m").replace(/\{bright-magenta-fg\}/g, "\x1B[95m").replace(/\{bright-yellow-fg\}/g, "\x1B[93m").replace(/\{bright-green-fg\}/g, "\x1B[92m").replace(/\{bright-red-fg\}/g, "\x1B[91m").replace(/\{\/\}/g, "\x1B[0m");
|
|
1415
|
+
}
|
|
1416
|
+
function colorizeLogPrefixAnsi(text) {
|
|
1417
|
+
return blessedToAnsi(colorizeLogPrefix(text));
|
|
1418
|
+
}
|
|
1419
|
+
function createServerOutputHandler(buffer) {
|
|
1420
|
+
return (data) => {
|
|
1421
|
+
const text = buffer.current + data.toString();
|
|
1422
|
+
const lines = text.split(`
|
|
1423
|
+
`);
|
|
1424
|
+
buffer.current = lines.pop() || "";
|
|
1425
|
+
for (const line of lines) {
|
|
1426
|
+
const trimmedLine = line.trim();
|
|
1427
|
+
if (!trimmedLine) {
|
|
1428
|
+
continue;
|
|
1429
|
+
}
|
|
1430
|
+
const ansiColored = colorizeLogPrefixAnsi(line);
|
|
1431
|
+
console.log(ansiColored);
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
var PREFIX_COLORS;
|
|
1436
|
+
var init_log = __esm(() => {
|
|
1437
|
+
PREFIX_COLORS = {
|
|
1438
|
+
"[reroute]": "{cyan-fg}",
|
|
1439
|
+
"[reroute/gen]": "{bright-blue-fg}",
|
|
1440
|
+
"[reroute/content]": "{magenta-fg}",
|
|
1441
|
+
"[reroute/markdown]": "{yellow-fg}",
|
|
1442
|
+
"[reroute/tailwind]": "{red-fg}",
|
|
1443
|
+
"[reroute/mdx]": "{bright-red-fg}",
|
|
1444
|
+
"[reroute/boot]": "{bright-yellow-fg}",
|
|
1445
|
+
"[reroute/dev]": "{green-fg}",
|
|
1446
|
+
"[reroute/start]": "{bright-cyan-fg}",
|
|
1447
|
+
"[reroute/build]": "{bright-magenta-fg}",
|
|
1448
|
+
"[api]": "{blue-fg}",
|
|
1449
|
+
"[app]": "{bright-green-fg}"
|
|
1450
|
+
};
|
|
1451
|
+
});
|
|
1452
|
+
|
|
1453
|
+
// packages/cli/src/commands/dev.ts
|
|
1454
|
+
var exports_dev = {};
|
|
1455
|
+
__export(exports_dev, {
|
|
1456
|
+
default: () => dev
|
|
1457
|
+
});
|
|
1458
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
1459
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
1460
|
+
import { join as join7 } from "node:path";
|
|
1461
|
+
function getRerouteCommand() {
|
|
1462
|
+
const binPath = join7(import.meta.dir, "..", "..", "bin.ts");
|
|
1463
|
+
const isBunDev = existsSync5(binPath);
|
|
1464
|
+
if (isBunDev) {
|
|
1465
|
+
return `bun ${binPath}`;
|
|
1466
|
+
}
|
|
1467
|
+
const cwd = process.cwd();
|
|
1468
|
+
const nodeModulesPaths = [
|
|
1469
|
+
join7(cwd, "node_modules", ".bin", "reroute"),
|
|
1470
|
+
join7(cwd, "..", "node_modules", ".bin", "reroute"),
|
|
1471
|
+
join7(cwd, "..", "..", "node_modules", ".bin", "reroute"),
|
|
1472
|
+
join7(cwd, "..", "..", "..", "node_modules", ".bin", "reroute")
|
|
1473
|
+
];
|
|
1474
|
+
for (const binPath2 of nodeModulesPaths) {
|
|
1475
|
+
if (existsSync5(binPath2)) {
|
|
1476
|
+
return binPath2;
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
return "reroute";
|
|
1480
|
+
}
|
|
1481
|
+
async function dev(args) {
|
|
1482
|
+
const singleColumn = args.includes("--single") || args.includes("-s");
|
|
1483
|
+
try {
|
|
1484
|
+
console.log("[reroute/dev] Running boot...");
|
|
1485
|
+
await boot([]);
|
|
1486
|
+
console.log(`[reroute/dev] Boot complete
|
|
1487
|
+
`);
|
|
1488
|
+
console.log("[reroute/dev] Starting development servers...");
|
|
1489
|
+
console.log(`[reroute/dev] Press Ctrl+C to stop
|
|
1490
|
+
`);
|
|
1491
|
+
const rerouteCmd = getRerouteCommand();
|
|
1492
|
+
const useShell = rerouteCmd.includes(" ");
|
|
1493
|
+
const genCommand = useShell ? `${rerouteCmd} gen --watch` : rerouteCmd;
|
|
1494
|
+
const genArgs = useShell ? [] : ["gen", "--watch"];
|
|
1495
|
+
const genProcess = spawn2(genCommand, genArgs, {
|
|
1496
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1497
|
+
shell: useShell
|
|
1498
|
+
});
|
|
1499
|
+
const serverProcess = spawn2("bun", ["--watch", "src/index.ts"], {
|
|
1500
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
1501
|
+
});
|
|
1502
|
+
if (singleColumn) {
|
|
1503
|
+
const genBuffer = { current: "" };
|
|
1504
|
+
const serverBuffer = { current: "" };
|
|
1505
|
+
const handleGenOutput = (data) => {
|
|
1506
|
+
const text = genBuffer.current + data.toString();
|
|
1507
|
+
const lines = text.split(`
|
|
1508
|
+
`);
|
|
1509
|
+
genBuffer.current = lines.pop() || "";
|
|
1510
|
+
for (const line of lines) {
|
|
1511
|
+
if (!line.trim()) {
|
|
1512
|
+
continue;
|
|
1513
|
+
}
|
|
1514
|
+
const ansiColored = colorizeLogPrefixAnsi(line);
|
|
1515
|
+
console.log(ansiColored);
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
const handleServerOutput = createServerOutputHandler(serverBuffer);
|
|
1519
|
+
genProcess.stdout?.on("data", handleGenOutput);
|
|
1520
|
+
genProcess.stderr?.on("data", handleGenOutput);
|
|
1521
|
+
serverProcess.stdout?.on("data", handleServerOutput);
|
|
1522
|
+
serverProcess.stderr?.on("data", handleServerOutput);
|
|
1523
|
+
genProcess.on("exit", (code) => {
|
|
1524
|
+
console.log(`
|
|
1525
|
+
[reroute/gen] Process exited with code ${code}`);
|
|
1526
|
+
});
|
|
1527
|
+
serverProcess.on("exit", (code) => {
|
|
1528
|
+
console.log(`
|
|
1529
|
+
[server] Process exited with code ${code}`);
|
|
1530
|
+
});
|
|
1531
|
+
process.on("SIGINT", () => {
|
|
1532
|
+
console.log(`
|
|
1533
|
+
[reroute/dev] Shutting down...`);
|
|
1534
|
+
genProcess.kill("SIGINT");
|
|
1535
|
+
serverProcess.kill("SIGINT");
|
|
1536
|
+
process.exit(0);
|
|
1537
|
+
});
|
|
1538
|
+
} else {
|
|
1539
|
+
const blessed = await import("blessed");
|
|
1540
|
+
const contrib = await import("blessed-contrib");
|
|
1541
|
+
const screen = blessed.default.screen({
|
|
1542
|
+
smartCSR: true,
|
|
1543
|
+
title: "reroute dev",
|
|
1544
|
+
mouse: true
|
|
1545
|
+
});
|
|
1546
|
+
const grid = new contrib.default.grid({
|
|
1547
|
+
rows: 1,
|
|
1548
|
+
cols: 2,
|
|
1549
|
+
screen
|
|
1550
|
+
});
|
|
1551
|
+
const genBox = grid.set(0, 0, 1, 1, blessed.default.log, {
|
|
1552
|
+
label: " reroute gen --watch ",
|
|
1553
|
+
border: { type: "line" },
|
|
1554
|
+
style: {
|
|
1555
|
+
border: { fg: "cyan" }
|
|
1556
|
+
},
|
|
1557
|
+
scrollable: true,
|
|
1558
|
+
alwaysScroll: true,
|
|
1559
|
+
scrollbar: {
|
|
1560
|
+
ch: " ",
|
|
1561
|
+
inverse: true
|
|
1562
|
+
},
|
|
1563
|
+
tags: true,
|
|
1564
|
+
keys: true,
|
|
1565
|
+
vi: true,
|
|
1566
|
+
mouse: true,
|
|
1567
|
+
input: true,
|
|
1568
|
+
clickable: true
|
|
1569
|
+
});
|
|
1570
|
+
const serverBox = grid.set(0, 1, 1, 1, blessed.default.log, {
|
|
1571
|
+
label: " bun --watch src/index.ts ",
|
|
1572
|
+
border: { type: "line" },
|
|
1573
|
+
style: {
|
|
1574
|
+
border: { fg: "green" }
|
|
1575
|
+
},
|
|
1576
|
+
scrollable: true,
|
|
1577
|
+
alwaysScroll: true,
|
|
1578
|
+
scrollbar: {
|
|
1579
|
+
ch: " ",
|
|
1580
|
+
inverse: true
|
|
1581
|
+
},
|
|
1582
|
+
tags: true,
|
|
1583
|
+
keys: true,
|
|
1584
|
+
vi: true,
|
|
1585
|
+
mouse: true,
|
|
1586
|
+
input: true,
|
|
1587
|
+
clickable: true
|
|
1588
|
+
});
|
|
1589
|
+
genBox.key(["up", "k"], () => {
|
|
1590
|
+
genBox.scroll(-1);
|
|
1591
|
+
screen.render();
|
|
1592
|
+
});
|
|
1593
|
+
genBox.key(["down", "j"], () => {
|
|
1594
|
+
genBox.scroll(1);
|
|
1595
|
+
screen.render();
|
|
1596
|
+
});
|
|
1597
|
+
genBox.key(["pageup"], () => {
|
|
1598
|
+
genBox.scroll(-genBox.height);
|
|
1599
|
+
screen.render();
|
|
1600
|
+
});
|
|
1601
|
+
genBox.key(["pagedown"], () => {
|
|
1602
|
+
genBox.scroll(genBox.height);
|
|
1603
|
+
screen.render();
|
|
1604
|
+
});
|
|
1605
|
+
genBox.key(["home", "g"], () => {
|
|
1606
|
+
genBox.setScrollPerc(0);
|
|
1607
|
+
screen.render();
|
|
1608
|
+
});
|
|
1609
|
+
genBox.key(["end", "G"], () => {
|
|
1610
|
+
genBox.setScrollPerc(100);
|
|
1611
|
+
screen.render();
|
|
1612
|
+
});
|
|
1613
|
+
serverBox.key(["up", "k"], () => {
|
|
1614
|
+
serverBox.scroll(-1);
|
|
1615
|
+
screen.render();
|
|
1616
|
+
});
|
|
1617
|
+
serverBox.key(["down", "j"], () => {
|
|
1618
|
+
serverBox.scroll(1);
|
|
1619
|
+
screen.render();
|
|
1620
|
+
});
|
|
1621
|
+
serverBox.key(["pageup"], () => {
|
|
1622
|
+
serverBox.scroll(-serverBox.height);
|
|
1623
|
+
screen.render();
|
|
1624
|
+
});
|
|
1625
|
+
serverBox.key(["pagedown"], () => {
|
|
1626
|
+
serverBox.scroll(serverBox.height);
|
|
1627
|
+
screen.render();
|
|
1628
|
+
});
|
|
1629
|
+
serverBox.key(["home", "g"], () => {
|
|
1630
|
+
serverBox.setScrollPerc(0);
|
|
1631
|
+
screen.render();
|
|
1632
|
+
});
|
|
1633
|
+
serverBox.key(["end", "G"], () => {
|
|
1634
|
+
serverBox.setScrollPerc(100);
|
|
1635
|
+
screen.render();
|
|
1636
|
+
});
|
|
1637
|
+
genBox.on("wheeldown", () => {
|
|
1638
|
+
genBox.scroll(3);
|
|
1639
|
+
screen.render();
|
|
1640
|
+
});
|
|
1641
|
+
genBox.on("wheelup", () => {
|
|
1642
|
+
genBox.scroll(-3);
|
|
1643
|
+
screen.render();
|
|
1644
|
+
});
|
|
1645
|
+
serverBox.on("wheeldown", () => {
|
|
1646
|
+
serverBox.scroll(3);
|
|
1647
|
+
screen.render();
|
|
1648
|
+
});
|
|
1649
|
+
serverBox.on("wheelup", () => {
|
|
1650
|
+
serverBox.scroll(-3);
|
|
1651
|
+
screen.render();
|
|
1652
|
+
});
|
|
1653
|
+
genBox.on("click", () => {
|
|
1654
|
+
genBox.focus();
|
|
1655
|
+
screen.render();
|
|
1656
|
+
});
|
|
1657
|
+
serverBox.on("click", () => {
|
|
1658
|
+
serverBox.focus();
|
|
1659
|
+
screen.render();
|
|
1660
|
+
});
|
|
1661
|
+
screen.key(["tab"], () => {
|
|
1662
|
+
if (screen.focused === genBox) {
|
|
1663
|
+
serverBox.focus();
|
|
1664
|
+
} else {
|
|
1665
|
+
genBox.focus();
|
|
1666
|
+
}
|
|
1667
|
+
screen.render();
|
|
1668
|
+
});
|
|
1669
|
+
genBox.focus();
|
|
1670
|
+
screen.render();
|
|
1671
|
+
genProcess.stdout?.on("data", (data) => {
|
|
1672
|
+
const text = data.toString();
|
|
1673
|
+
const lines = text.split(`
|
|
1674
|
+
`).filter((line) => line.trim());
|
|
1675
|
+
if (lines.length > 0) {
|
|
1676
|
+
const colored = colorizeLogPrefix(lines.join(`
|
|
1677
|
+
`));
|
|
1678
|
+
genBox.log(colored);
|
|
1679
|
+
screen.render();
|
|
1680
|
+
}
|
|
1681
|
+
});
|
|
1682
|
+
genProcess.stderr?.on("data", (data) => {
|
|
1683
|
+
const text = data.toString();
|
|
1684
|
+
const lines = text.split(`
|
|
1685
|
+
`).filter((line) => line.trim());
|
|
1686
|
+
if (lines.length > 0) {
|
|
1687
|
+
const colored = colorizeLogPrefix(lines.join(`
|
|
1688
|
+
`));
|
|
1689
|
+
genBox.log(colored);
|
|
1690
|
+
screen.render();
|
|
1691
|
+
}
|
|
1692
|
+
});
|
|
1693
|
+
serverProcess.stdout?.on("data", (data) => {
|
|
1694
|
+
const text = data.toString();
|
|
1695
|
+
const filteredText = text.split(`
|
|
1696
|
+
`).filter((line) => line.trim()).join(`
|
|
1697
|
+
`);
|
|
1698
|
+
if (filteredText) {
|
|
1699
|
+
const colored = colorizeLogPrefix(filteredText);
|
|
1700
|
+
serverBox.log(colored);
|
|
1701
|
+
screen.render();
|
|
1702
|
+
}
|
|
1703
|
+
});
|
|
1704
|
+
serverProcess.stderr?.on("data", (data) => {
|
|
1705
|
+
const text = data.toString();
|
|
1706
|
+
const filteredText = text.split(`
|
|
1707
|
+
`).filter((line) => line.trim()).join(`
|
|
1708
|
+
`);
|
|
1709
|
+
if (filteredText) {
|
|
1710
|
+
const colored = colorizeLogPrefix(filteredText);
|
|
1711
|
+
serverBox.log(colored);
|
|
1712
|
+
screen.render();
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
genProcess.on("exit", (code) => {
|
|
1716
|
+
genBox.log(`
|
|
1717
|
+
[Process exited with code ${code}]`);
|
|
1718
|
+
screen.render();
|
|
1719
|
+
});
|
|
1720
|
+
serverProcess.on("exit", (code) => {
|
|
1721
|
+
serverBox.log(`
|
|
1722
|
+
[Process exited with code ${code}]`);
|
|
1723
|
+
screen.render();
|
|
1724
|
+
});
|
|
1725
|
+
screen.key(["escape", "q", "C-c"], () => {
|
|
1726
|
+
genProcess.kill("SIGINT");
|
|
1727
|
+
serverProcess.kill("SIGINT");
|
|
1728
|
+
screen.destroy();
|
|
1729
|
+
process.exit(0);
|
|
1730
|
+
});
|
|
1731
|
+
screen.on("resize", () => {
|
|
1732
|
+
screen.render();
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
} catch (error) {
|
|
1736
|
+
if (error.code === "SIGINT") {
|
|
1737
|
+
console.log(`
|
|
1738
|
+
[reroute/dev] Shutting down...`);
|
|
1739
|
+
process.exit(0);
|
|
1740
|
+
}
|
|
1741
|
+
console.error("[reroute/dev] Error:", error);
|
|
1742
|
+
throw error;
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
var init_dev = __esm(() => {
|
|
1746
|
+
init_log();
|
|
1747
|
+
init_boot();
|
|
1748
|
+
});
|
|
1749
|
+
|
|
1750
|
+
// packages/cli/src/commands/start.ts
|
|
1751
|
+
var exports_start = {};
|
|
1752
|
+
__export(exports_start, {
|
|
1753
|
+
default: () => start
|
|
1754
|
+
});
|
|
1755
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
1756
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
1757
|
+
import { join as join8 } from "node:path";
|
|
1758
|
+
function getRerouteCommand2() {
|
|
1759
|
+
const binPath = join8(import.meta.dir, "..", "..", "bin.ts");
|
|
1760
|
+
const isBunDev = existsSync6(binPath);
|
|
1761
|
+
if (isBunDev) {
|
|
1762
|
+
return `bun ${binPath}`;
|
|
1763
|
+
}
|
|
1764
|
+
const cwd = process.cwd();
|
|
1765
|
+
const nodeModulesPaths = [
|
|
1766
|
+
join8(cwd, "node_modules", ".bin", "reroute"),
|
|
1767
|
+
join8(cwd, "..", "node_modules", ".bin", "reroute"),
|
|
1768
|
+
join8(cwd, "..", "..", "node_modules", ".bin", "reroute"),
|
|
1769
|
+
join8(cwd, "..", "..", "..", "node_modules", ".bin", "reroute")
|
|
1770
|
+
];
|
|
1771
|
+
for (const binPath2 of nodeModulesPaths) {
|
|
1772
|
+
if (existsSync6(binPath2)) {
|
|
1773
|
+
return binPath2;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
return "reroute";
|
|
1777
|
+
}
|
|
1778
|
+
async function start(_args) {
|
|
1779
|
+
try {
|
|
1780
|
+
const rerouteCmd = getRerouteCommand2();
|
|
1781
|
+
const useShell = rerouteCmd.includes(" ");
|
|
1782
|
+
const bootBuffer = { current: "" };
|
|
1783
|
+
const genBuffer = { current: "" };
|
|
1784
|
+
const handleBootOutput = (data) => {
|
|
1785
|
+
const text = bootBuffer.current + data.toString();
|
|
1786
|
+
const lines = text.split(`
|
|
1787
|
+
`);
|
|
1788
|
+
bootBuffer.current = lines.pop() || "";
|
|
1789
|
+
for (const line of lines) {
|
|
1790
|
+
if (!line.trim()) {
|
|
1791
|
+
continue;
|
|
1792
|
+
}
|
|
1793
|
+
const ansiColored = colorizeLogPrefixAnsi(line);
|
|
1794
|
+
console.log(ansiColored);
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
const handleGenOutput = (data) => {
|
|
1798
|
+
const text = genBuffer.current + data.toString();
|
|
1799
|
+
const lines = text.split(`
|
|
1800
|
+
`);
|
|
1801
|
+
genBuffer.current = lines.pop() || "";
|
|
1802
|
+
for (const line of lines) {
|
|
1803
|
+
if (!line.trim()) {
|
|
1804
|
+
continue;
|
|
1805
|
+
}
|
|
1806
|
+
const ansiColored = colorizeLogPrefixAnsi(line);
|
|
1807
|
+
console.log(ansiColored);
|
|
1808
|
+
}
|
|
1809
|
+
};
|
|
1810
|
+
process.stdout.write(`${colorizeLogPrefixAnsi("[reroute/start] Running boot...")}
|
|
1811
|
+
`);
|
|
1812
|
+
const bootCommand = useShell ? `${rerouteCmd} boot` : rerouteCmd;
|
|
1813
|
+
const bootArgs = useShell ? [] : ["boot"];
|
|
1814
|
+
await new Promise((resolve, reject) => {
|
|
1815
|
+
const bootProcess = spawn3(bootCommand, bootArgs, {
|
|
1816
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1817
|
+
shell: useShell
|
|
1818
|
+
});
|
|
1819
|
+
bootProcess.stdout?.on("data", handleBootOutput);
|
|
1820
|
+
bootProcess.stderr?.on("data", handleBootOutput);
|
|
1821
|
+
bootProcess.on("exit", (code) => {
|
|
1822
|
+
if (code !== null && code !== 0) {
|
|
1823
|
+
reject(new Error(`Boot exited with code ${code}`));
|
|
1824
|
+
} else {
|
|
1825
|
+
resolve();
|
|
1826
|
+
}
|
|
1827
|
+
});
|
|
1828
|
+
bootProcess.on("error", (error) => {
|
|
1829
|
+
reject(error);
|
|
1830
|
+
});
|
|
1831
|
+
});
|
|
1832
|
+
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/start] Boot complete
|
|
1833
|
+
`));
|
|
1834
|
+
process.stdout.write(`${colorizeLogPrefixAnsi("[reroute/start] Running gen...")}
|
|
1835
|
+
`);
|
|
1836
|
+
const genCommand = useShell ? `${rerouteCmd} gen` : rerouteCmd;
|
|
1837
|
+
const genArgs = useShell ? [] : ["gen"];
|
|
1838
|
+
await new Promise((resolve, reject) => {
|
|
1839
|
+
const genProcess = spawn3(genCommand, genArgs, {
|
|
1840
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1841
|
+
shell: useShell
|
|
1842
|
+
});
|
|
1843
|
+
genProcess.stdout?.on("data", handleGenOutput);
|
|
1844
|
+
genProcess.stderr?.on("data", handleGenOutput);
|
|
1845
|
+
genProcess.on("exit", (code) => {
|
|
1846
|
+
if (code !== null && code !== 0) {
|
|
1847
|
+
reject(new Error(`Gen exited with code ${code}`));
|
|
1848
|
+
} else {
|
|
1849
|
+
resolve();
|
|
1850
|
+
}
|
|
1851
|
+
});
|
|
1852
|
+
genProcess.on("error", (error) => {
|
|
1853
|
+
reject(error);
|
|
1854
|
+
});
|
|
1855
|
+
});
|
|
1856
|
+
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/start] Generation complete
|
|
1857
|
+
`));
|
|
1858
|
+
process.stdout.write(`${colorizeLogPrefixAnsi("[reroute/start] Starting server...")}
|
|
1859
|
+
`);
|
|
1860
|
+
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/start] Press Ctrl+C to stop
|
|
1861
|
+
`));
|
|
1862
|
+
const serverProcess = spawn3("bun", ["src/index.ts"], {
|
|
1863
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
1864
|
+
});
|
|
1865
|
+
const serverBuffer = { current: "" };
|
|
1866
|
+
const handleServerOutput = createServerOutputHandler(serverBuffer);
|
|
1867
|
+
serverProcess.stdout?.on("data", handleServerOutput);
|
|
1868
|
+
serverProcess.stderr?.on("data", handleServerOutput);
|
|
1869
|
+
process.on("SIGINT", () => {
|
|
1870
|
+
process.stdout.write(`${colorizeLogPrefixAnsi(`
|
|
1871
|
+
[reroute/start] Shutting down...`)}
|
|
1872
|
+
`);
|
|
1873
|
+
serverProcess.kill("SIGINT");
|
|
1874
|
+
process.exit(0);
|
|
1875
|
+
});
|
|
1876
|
+
await new Promise((resolve, reject) => {
|
|
1877
|
+
serverProcess.on("exit", (code) => {
|
|
1878
|
+
if (code !== null && code !== 0) {
|
|
1879
|
+
console.error(colorizeLogPrefixAnsi(`[reroute/start] Server exited with code ${code}`));
|
|
1880
|
+
reject(new Error(`Server exited with code ${code}`));
|
|
1881
|
+
} else {
|
|
1882
|
+
resolve();
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
serverProcess.on("error", (error) => {
|
|
1886
|
+
reject(error);
|
|
1887
|
+
});
|
|
1888
|
+
});
|
|
1889
|
+
} catch (error) {
|
|
1890
|
+
if (error.code === "SIGINT") {
|
|
1891
|
+
process.stdout.write(`${colorizeLogPrefixAnsi(`
|
|
1892
|
+
[reroute/start] Shutting down...`)}
|
|
1893
|
+
`);
|
|
1894
|
+
process.exit(0);
|
|
1895
|
+
}
|
|
1896
|
+
process.stderr.write(`${colorizeLogPrefixAnsi("[reroute/start] Error: ") + String(error)}
|
|
1897
|
+
`);
|
|
1898
|
+
throw error;
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
var init_start = __esm(() => {
|
|
1902
|
+
init_log();
|
|
1903
|
+
});
|
|
1904
|
+
|
|
1905
|
+
// packages/cli/src/commands/build.ts
|
|
1906
|
+
var exports_build = {};
|
|
1907
|
+
__export(exports_build, {
|
|
1908
|
+
default: () => build
|
|
1909
|
+
});
|
|
1910
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
1911
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
|
|
1912
|
+
import { join as join9 } from "node:path";
|
|
1913
|
+
function getRerouteCommand3() {
|
|
1914
|
+
const binPath = join9(import.meta.dir, "..", "..", "bin.ts");
|
|
1915
|
+
const isBunDev = existsSync7(binPath);
|
|
1916
|
+
if (isBunDev) {
|
|
1917
|
+
return `bun ${binPath}`;
|
|
1918
|
+
}
|
|
1919
|
+
const cwd = process.cwd();
|
|
1920
|
+
const nodeModulesPaths = [
|
|
1921
|
+
join9(cwd, "node_modules", ".bin", "reroute"),
|
|
1922
|
+
join9(cwd, "..", "node_modules", ".bin", "reroute"),
|
|
1923
|
+
join9(cwd, "..", "..", "node_modules", ".bin", "reroute"),
|
|
1924
|
+
join9(cwd, "..", "..", "..", "node_modules", ".bin", "reroute")
|
|
1925
|
+
];
|
|
1926
|
+
for (const binPath2 of nodeModulesPaths) {
|
|
1927
|
+
if (existsSync7(binPath2)) {
|
|
1928
|
+
return binPath2;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
return "reroute";
|
|
1932
|
+
}
|
|
1933
|
+
function getOutputName() {
|
|
1934
|
+
const cwd = process.cwd();
|
|
1935
|
+
const packageJsonPath = join9(cwd, "package.json");
|
|
1936
|
+
if (existsSync7(packageJsonPath)) {
|
|
1937
|
+
try {
|
|
1938
|
+
const packageJson = JSON.parse(readFileSync4(packageJsonPath, "utf-8"));
|
|
1939
|
+
const name = packageJson.name;
|
|
1940
|
+
if (name) {
|
|
1941
|
+
const parts = name.split("-");
|
|
1942
|
+
if (parts.length > 1 && parts[parts.length - 1] === "example") {
|
|
1943
|
+
return parts[parts.length - 2] || "app";
|
|
1944
|
+
}
|
|
1945
|
+
return parts[parts.length - 1] || name;
|
|
1946
|
+
}
|
|
1947
|
+
} catch {}
|
|
1948
|
+
}
|
|
1949
|
+
return "app";
|
|
1950
|
+
}
|
|
1951
|
+
async function build(args) {
|
|
1952
|
+
try {
|
|
1953
|
+
const rerouteCmd = getRerouteCommand3();
|
|
1954
|
+
const useShell = rerouteCmd.includes(" ");
|
|
1955
|
+
let outputPath = `./dist/${getOutputName()}`;
|
|
1956
|
+
const outfileIndex = args.indexOf("--outfile");
|
|
1957
|
+
const shortOutfileIndex = args.indexOf("-o");
|
|
1958
|
+
const outfileArgIndex = outfileIndex !== -1 ? outfileIndex : shortOutfileIndex;
|
|
1959
|
+
if (outfileArgIndex !== -1 && args[outfileArgIndex + 1]) {
|
|
1960
|
+
outputPath = args[outfileArgIndex + 1];
|
|
1961
|
+
}
|
|
1962
|
+
const bootBuffer = { current: "" };
|
|
1963
|
+
const genBuffer = { current: "" };
|
|
1964
|
+
const handleBootOutput = (data) => {
|
|
1965
|
+
const text = bootBuffer.current + data.toString();
|
|
1966
|
+
const lines = text.split(`
|
|
1967
|
+
`);
|
|
1968
|
+
bootBuffer.current = lines.pop() || "";
|
|
1969
|
+
for (const line of lines) {
|
|
1970
|
+
if (!line.trim()) {
|
|
1971
|
+
continue;
|
|
1972
|
+
}
|
|
1973
|
+
const ansiColored = colorizeLogPrefixAnsi(line);
|
|
1974
|
+
console.log(ansiColored);
|
|
1975
|
+
}
|
|
1976
|
+
};
|
|
1977
|
+
const handleGenOutput = (data) => {
|
|
1978
|
+
const text = genBuffer.current + data.toString();
|
|
1979
|
+
const lines = text.split(`
|
|
1980
|
+
`);
|
|
1981
|
+
genBuffer.current = lines.pop() || "";
|
|
1982
|
+
for (const line of lines) {
|
|
1983
|
+
if (!line.trim()) {
|
|
1984
|
+
continue;
|
|
1985
|
+
}
|
|
1986
|
+
const ansiColored = colorizeLogPrefixAnsi(line);
|
|
1987
|
+
console.log(ansiColored);
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1990
|
+
process.stdout.write(`${colorizeLogPrefixAnsi("[reroute/build] Running boot...")}
|
|
1991
|
+
`);
|
|
1992
|
+
const bootCommand = useShell ? `${rerouteCmd} boot` : rerouteCmd;
|
|
1993
|
+
const bootArgs = useShell ? [] : ["boot"];
|
|
1994
|
+
await new Promise((resolve, reject) => {
|
|
1995
|
+
const bootProcess = spawn4(bootCommand, bootArgs, {
|
|
1996
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1997
|
+
shell: useShell
|
|
1998
|
+
});
|
|
1999
|
+
bootProcess.stdout?.on("data", handleBootOutput);
|
|
2000
|
+
bootProcess.stderr?.on("data", handleBootOutput);
|
|
2001
|
+
bootProcess.on("exit", (code) => {
|
|
2002
|
+
if (code !== null && code !== 0) {
|
|
2003
|
+
reject(new Error(`Boot exited with code ${code}`));
|
|
2004
|
+
} else {
|
|
2005
|
+
resolve();
|
|
2006
|
+
}
|
|
2007
|
+
});
|
|
2008
|
+
bootProcess.on("error", (error) => {
|
|
2009
|
+
reject(error);
|
|
2010
|
+
});
|
|
2011
|
+
});
|
|
2012
|
+
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Boot complete
|
|
2013
|
+
`));
|
|
2014
|
+
process.stdout.write(`${colorizeLogPrefixAnsi("[reroute/build] Running gen...")}
|
|
2015
|
+
`);
|
|
2016
|
+
const genCommand = useShell ? `${rerouteCmd} gen` : rerouteCmd;
|
|
2017
|
+
const genArgs = useShell ? [] : ["gen"];
|
|
2018
|
+
await new Promise((resolve, reject) => {
|
|
2019
|
+
const genProcess = spawn4(genCommand, genArgs, {
|
|
2020
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
2021
|
+
shell: useShell
|
|
2022
|
+
});
|
|
2023
|
+
genProcess.stdout?.on("data", handleGenOutput);
|
|
2024
|
+
genProcess.stderr?.on("data", handleGenOutput);
|
|
2025
|
+
genProcess.on("exit", (code) => {
|
|
2026
|
+
if (code !== null && code !== 0) {
|
|
2027
|
+
reject(new Error(`Gen exited with code ${code}`));
|
|
2028
|
+
} else {
|
|
2029
|
+
resolve();
|
|
2030
|
+
}
|
|
2031
|
+
});
|
|
2032
|
+
genProcess.on("error", (error) => {
|
|
2033
|
+
reject(error);
|
|
2034
|
+
});
|
|
2035
|
+
});
|
|
2036
|
+
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Generation complete
|
|
2037
|
+
`));
|
|
2038
|
+
process.stdout.write(`${colorizeLogPrefixAnsi(`[reroute/build] Building binary to ${outputPath}...`)}
|
|
2039
|
+
`);
|
|
2040
|
+
const isProduction = true;
|
|
2041
|
+
const buildArgs = ["build", "src/index.ts", "--target", "bun", "--compile"];
|
|
2042
|
+
if (isProduction) {
|
|
2043
|
+
buildArgs.push("--minify");
|
|
2044
|
+
}
|
|
2045
|
+
const filteredArgs = args.filter((arg, idx) => {
|
|
2046
|
+
if (outfileArgIndex !== -1) {
|
|
2047
|
+
if (idx === outfileArgIndex || idx === outfileArgIndex + 1) {
|
|
2048
|
+
return false;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
return arg !== "--outfile" && arg !== "-o" && arg !== "--minify" && arg !== "--no-minify";
|
|
2052
|
+
});
|
|
2053
|
+
buildArgs.push(...filteredArgs, "--outfile", outputPath);
|
|
2054
|
+
await new Promise((resolve, reject) => {
|
|
2055
|
+
const buildProcess = spawn4("bun", buildArgs, {
|
|
2056
|
+
stdio: "inherit"
|
|
2057
|
+
});
|
|
2058
|
+
buildProcess.on("exit", (code) => {
|
|
2059
|
+
if (code !== null && code !== 0) {
|
|
2060
|
+
reject(new Error(`Build exited with code ${code}`));
|
|
2061
|
+
} else {
|
|
2062
|
+
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Build complete: ${outputPath}
|
|
2063
|
+
`));
|
|
2064
|
+
resolve();
|
|
2065
|
+
}
|
|
2066
|
+
});
|
|
2067
|
+
buildProcess.on("error", (error) => {
|
|
2068
|
+
reject(error);
|
|
2069
|
+
});
|
|
2070
|
+
});
|
|
2071
|
+
} catch (error) {
|
|
2072
|
+
process.stderr.write(`${colorizeLogPrefixAnsi("[reroute/build] Error: ") + String(error)}
|
|
2073
|
+
`);
|
|
2074
|
+
throw error;
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
var init_build = __esm(() => {
|
|
2078
|
+
init_log();
|
|
2079
|
+
});
|
|
2080
|
+
|
|
869
2081
|
// packages/cli/src/cli.ts
|
|
870
2082
|
import path2 from "node:path";
|
|
871
2083
|
var commands = {
|
|
872
2084
|
init: () => Promise.resolve().then(() => (init_init(), exports_init)),
|
|
873
2085
|
gen: () => Promise.resolve().then(() => (init_gen(), exports_gen)),
|
|
874
|
-
boot: () => Promise.resolve().then(() => (init_boot(), exports_boot))
|
|
2086
|
+
boot: () => Promise.resolve().then(() => (init_boot(), exports_boot)),
|
|
2087
|
+
dev: () => Promise.resolve().then(() => (init_dev(), exports_dev)),
|
|
2088
|
+
start: () => Promise.resolve().then(() => (init_start(), exports_start)),
|
|
2089
|
+
build: () => Promise.resolve().then(() => (init_build(), exports_build))
|
|
875
2090
|
};
|
|
876
2091
|
async function main() {
|
|
877
2092
|
const args = process.argv.slice(2);
|
|
@@ -900,25 +2115,49 @@ async function main() {
|
|
|
900
2115
|
}
|
|
901
2116
|
}
|
|
902
2117
|
async function printHelp2() {
|
|
2118
|
+
console.log("");
|
|
903
2119
|
console.log(await getVersionString2());
|
|
904
2120
|
console.log("");
|
|
2121
|
+
console.log("");
|
|
905
2122
|
console.log("Usage:");
|
|
2123
|
+
console.log("");
|
|
906
2124
|
console.log(" reroute <command> [options]");
|
|
907
2125
|
console.log("");
|
|
2126
|
+
console.log("");
|
|
908
2127
|
console.log("Commands:");
|
|
2128
|
+
console.log("");
|
|
2129
|
+
console.log(" init Scaffold a new Reroute project");
|
|
909
2130
|
console.log(" boot Initialize .reroute directory with stub files");
|
|
910
2131
|
console.log(" gen Generate content registry and static assets");
|
|
911
|
-
console.log("
|
|
2132
|
+
console.log(" dev Start development environment");
|
|
2133
|
+
console.log(" start Run production-like server locally");
|
|
2134
|
+
console.log(" build Build production binary");
|
|
2135
|
+
console.log("");
|
|
912
2136
|
console.log("");
|
|
913
2137
|
console.log("Options:");
|
|
2138
|
+
console.log("");
|
|
914
2139
|
console.log(" -h, --help Show help");
|
|
915
2140
|
console.log(" -v, --version Show version");
|
|
916
2141
|
console.log("");
|
|
2142
|
+
console.log("");
|
|
917
2143
|
console.log("Examples:");
|
|
2144
|
+
console.log("");
|
|
2145
|
+
console.log(" reroute init my-app");
|
|
918
2146
|
console.log(" reroute boot");
|
|
2147
|
+
console.log("");
|
|
919
2148
|
console.log(" reroute gen");
|
|
2149
|
+
console.log(" reroute gen -w");
|
|
920
2150
|
console.log(" reroute gen --watch");
|
|
921
|
-
console.log("
|
|
2151
|
+
console.log("");
|
|
2152
|
+
console.log(" reroute dev");
|
|
2153
|
+
console.log(" reroute dev -s");
|
|
2154
|
+
console.log(" reroute dev --single");
|
|
2155
|
+
console.log("");
|
|
2156
|
+
console.log(" reroute start");
|
|
2157
|
+
console.log("");
|
|
2158
|
+
console.log(" reroute build");
|
|
2159
|
+
console.log(" reroute build -o ./dist/myapp");
|
|
2160
|
+
console.log(" reroute build --outfile ./dist/myapp");
|
|
922
2161
|
}
|
|
923
2162
|
async function getVersionString2() {
|
|
924
2163
|
const version = await getVersion2();
|
|
@@ -927,7 +2166,7 @@ async function getVersionString2() {
|
|
|
927
2166
|
}
|
|
928
2167
|
async function getVersion2() {
|
|
929
2168
|
if (true) {
|
|
930
|
-
return "0.
|
|
2169
|
+
return "0.7.0";
|
|
931
2170
|
}
|
|
932
2171
|
const possiblePaths = [
|
|
933
2172
|
path2.join(import.meta.dir, "../../../package.json"),
|
|
@@ -944,10 +2183,10 @@ async function getVersion2() {
|
|
|
944
2183
|
}
|
|
945
2184
|
async function getCommit2() {
|
|
946
2185
|
if (true) {
|
|
947
|
-
return "
|
|
2186
|
+
return "4b119c0";
|
|
948
2187
|
}
|
|
949
2188
|
return "dev";
|
|
950
2189
|
}
|
|
951
2190
|
main();
|
|
952
2191
|
|
|
953
|
-
//# debugId=
|
|
2192
|
+
//# debugId=B8066BB70A3F2A9464756E2164756E21
|