@catmint/vite 0.0.0-prealpha.1
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/LICENSE +339 -0
- package/dist/boundary.d.ts +15 -0
- package/dist/boundary.d.ts.map +1 -0
- package/dist/boundary.js +193 -0
- package/dist/boundary.js.map +1 -0
- package/dist/build-entries.d.ts +81 -0
- package/dist/build-entries.d.ts.map +1 -0
- package/dist/build-entries.js +1139 -0
- package/dist/build-entries.js.map +1 -0
- package/dist/cors-utils.d.ts +22 -0
- package/dist/cors-utils.d.ts.map +1 -0
- package/dist/cors-utils.js +36 -0
- package/dist/cors-utils.js.map +1 -0
- package/dist/dev-server.d.ts +34 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/dev-server.js +1683 -0
- package/dist/dev-server.js.map +1 -0
- package/dist/env-transform.d.ts +16 -0
- package/dist/env-transform.d.ts.map +1 -0
- package/dist/env-transform.js +125 -0
- package/dist/env-transform.js.map +1 -0
- package/dist/error-page.d.ts +19 -0
- package/dist/error-page.d.ts.map +1 -0
- package/dist/error-page.js +152 -0
- package/dist/error-page.js.map +1 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -0
- package/dist/mdx-transform.d.ts +33 -0
- package/dist/mdx-transform.d.ts.map +1 -0
- package/dist/mdx-transform.js +86 -0
- package/dist/mdx-transform.js.map +1 -0
- package/dist/middleware.d.ts +13 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +155 -0
- package/dist/middleware.js.map +1 -0
- package/dist/resolve-utils.d.ts +17 -0
- package/dist/resolve-utils.d.ts.map +1 -0
- package/dist/resolve-utils.js +51 -0
- package/dist/resolve-utils.js.map +1 -0
- package/dist/route-gen.d.ts +12 -0
- package/dist/route-gen.d.ts.map +1 -0
- package/dist/route-gen.js +221 -0
- package/dist/route-gen.js.map +1 -0
- package/dist/server-fn-transform.d.ts +12 -0
- package/dist/server-fn-transform.d.ts.map +1 -0
- package/dist/server-fn-transform.js +394 -0
- package/dist/server-fn-transform.js.map +1 -0
- package/dist/utils.d.ts +56 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +198 -0
- package/dist/utils.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Options for the MDX transform plugin.
|
|
4
|
+
*/
|
|
5
|
+
export interface MdxTransformOptions {
|
|
6
|
+
/** Remark plugins to apply during MDX compilation. */
|
|
7
|
+
remarkPlugins?: any[];
|
|
8
|
+
/** Rehype plugins to apply during MDX compilation. */
|
|
9
|
+
rehypePlugins?: any[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Check if a file ID is an MDX file.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isMdxFile(id: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Create the MDX transform Vite plugin.
|
|
17
|
+
*
|
|
18
|
+
* Compiles `.mdx` files into ES modules that export a React component as
|
|
19
|
+
* the default export. The compiled output uses React's automatic JSX runtime
|
|
20
|
+
* so no manual JSX import is required.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // In a page component:
|
|
25
|
+
* import Content from './content.mdx'
|
|
26
|
+
*
|
|
27
|
+
* export default function Page() {
|
|
28
|
+
* return <Content />
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function mdxPlugin(options?: MdxTransformOptions): Plugin;
|
|
33
|
+
//# sourceMappingURL=mdx-transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mdx-transform.d.ts","sourceRoot":"","sources":["../src/mdx-transform.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,sDAAsD;IACtD,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE7C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CA8DnE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// @catmint/vite/mdx-transform — MDX file support for Vite
|
|
2
|
+
//
|
|
3
|
+
// Handles:
|
|
4
|
+
// - Transforming `.mdx` file imports into React component modules
|
|
5
|
+
// - Uses `@mdx-js/mdx` `compile()` with `outputFormat: 'program'` to produce
|
|
6
|
+
// ESM output that exports a React component as the default export
|
|
7
|
+
// - Supports remark/rehype plugins via configuration
|
|
8
|
+
// - HMR: triggers full reload when `.mdx` files change
|
|
9
|
+
/**
|
|
10
|
+
* Check if a file ID is an MDX file.
|
|
11
|
+
*/
|
|
12
|
+
export function isMdxFile(id) {
|
|
13
|
+
return /\.mdx(\?.*)?$/.test(id);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create the MDX transform Vite plugin.
|
|
17
|
+
*
|
|
18
|
+
* Compiles `.mdx` files into ES modules that export a React component as
|
|
19
|
+
* the default export. The compiled output uses React's automatic JSX runtime
|
|
20
|
+
* so no manual JSX import is required.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // In a page component:
|
|
25
|
+
* import Content from './content.mdx'
|
|
26
|
+
*
|
|
27
|
+
* export default function Page() {
|
|
28
|
+
* return <Content />
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function mdxPlugin(options = {}) {
|
|
33
|
+
return {
|
|
34
|
+
name: "catmint:mdx",
|
|
35
|
+
enforce: "pre",
|
|
36
|
+
/**
|
|
37
|
+
* config hook — exclude MDX compilation dependencies from Vite's dep
|
|
38
|
+
* optimizer. These packages are server-only build tools (used in the
|
|
39
|
+
* transform hook) and should never be pre-bundled for the browser.
|
|
40
|
+
*/
|
|
41
|
+
config() {
|
|
42
|
+
return {
|
|
43
|
+
optimizeDeps: {
|
|
44
|
+
exclude: ["@mdx-js/mdx", "remark-gfm", "@shikijs/rehype", "shiki"],
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* transform hook — compile .mdx files to ESM React component modules.
|
|
50
|
+
*/
|
|
51
|
+
async transform(code, id) {
|
|
52
|
+
if (!isMdxFile(id))
|
|
53
|
+
return null;
|
|
54
|
+
const { compile } = await import("@mdx-js/mdx");
|
|
55
|
+
// Pass source as a VFile-compatible object with path for better errors
|
|
56
|
+
const compiled = await compile({ path: id, value: code }, {
|
|
57
|
+
// 'program' outputs a full ESM module with import/export statements
|
|
58
|
+
outputFormat: "program",
|
|
59
|
+
// Use React's automatic JSX runtime — no need for manual React import
|
|
60
|
+
jsxRuntime: "automatic",
|
|
61
|
+
jsxImportSource: "react",
|
|
62
|
+
remarkPlugins: options.remarkPlugins ?? [],
|
|
63
|
+
rehypePlugins: options.rehypePlugins ?? [],
|
|
64
|
+
});
|
|
65
|
+
const output = String(compiled);
|
|
66
|
+
return {
|
|
67
|
+
code: output,
|
|
68
|
+
// The compiled output is now standard ESM — Vite handles it natively
|
|
69
|
+
map: null,
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* handleHotUpdate — trigger full reload when .mdx files change.
|
|
74
|
+
*
|
|
75
|
+
* MDX compilation is async and may produce very different output
|
|
76
|
+
* for small source changes, so a full reload is safest.
|
|
77
|
+
*/
|
|
78
|
+
handleHotUpdate(ctx) {
|
|
79
|
+
if (isMdxFile(ctx.file)) {
|
|
80
|
+
ctx.server.ws.send({ type: "full-reload" });
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=mdx-transform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mdx-transform.js","sourceRoot":"","sources":["../src/mdx-transform.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,WAAW;AACX,kEAAkE;AAClE,6EAA6E;AAC7E,oEAAoE;AACpE,qDAAqD;AACrD,uDAAuD;AAcvD;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,EAAU;IAClC,OAAO,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,SAAS,CAAC,UAA+B,EAAE;IACzD,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,KAAK;QAEd;;;;WAIG;QACH,MAAM;YACJ,OAAO;gBACL,YAAY,EAAE;oBACZ,OAAO,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,OAAO,CAAC;iBACnE;aACF,CAAC;QACJ,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,EAAU;YACtC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAC;YAEhC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YAEhD,uEAAuE;YACvE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EACzB;gBACE,oEAAoE;gBACpE,YAAY,EAAE,SAAS;gBACvB,sEAAsE;gBACtE,UAAU,EAAE,WAAW;gBACvB,eAAe,EAAE,OAAO;gBACxB,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;gBAC1C,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;aAC3C,CACF,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEhC,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,qEAAqE;gBACrE,GAAG,EAAE,IAAI;aACV,CAAC;QACJ,CAAC;QAED;;;;;WAKG;QACH,eAAe,CAAC,GAAG;YACjB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBAC5C,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Create the middleware compilation Vite plugin.
|
|
4
|
+
*
|
|
5
|
+
* At build time, this plugin scans the app/ directory for middleware files
|
|
6
|
+
* and generates optimized composed middleware chains for each route.
|
|
7
|
+
*
|
|
8
|
+
* The optimization pre-computes which middleware applies to each route
|
|
9
|
+
* and generates import statements that compose them at build time rather
|
|
10
|
+
* than resolving the chain at runtime.
|
|
11
|
+
*/
|
|
12
|
+
export declare function middlewarePlugin(): Plugin;
|
|
13
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAC;AAenD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAwEzC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// @catmint/vite/middleware — Middleware chain compilation
|
|
2
|
+
//
|
|
3
|
+
// At build time, composes middleware chains into single functions per route
|
|
4
|
+
// as an optimization. Generates a manifest that maps route patterns to their
|
|
5
|
+
// pre-composed middleware chains.
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { resolve, dirname, join } from "node:path";
|
|
8
|
+
import { toPosixPath } from "./utils.js";
|
|
9
|
+
/**
|
|
10
|
+
* Middleware file names to look for, in priority order.
|
|
11
|
+
*/
|
|
12
|
+
const MIDDLEWARE_FILENAMES = [
|
|
13
|
+
"middleware.ts",
|
|
14
|
+
"middleware.tsx",
|
|
15
|
+
"middleware.js",
|
|
16
|
+
"middleware.jsx",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Create the middleware compilation Vite plugin.
|
|
20
|
+
*
|
|
21
|
+
* At build time, this plugin scans the app/ directory for middleware files
|
|
22
|
+
* and generates optimized composed middleware chains for each route.
|
|
23
|
+
*
|
|
24
|
+
* The optimization pre-computes which middleware applies to each route
|
|
25
|
+
* and generates import statements that compose them at build time rather
|
|
26
|
+
* than resolving the chain at runtime.
|
|
27
|
+
*/
|
|
28
|
+
export function middlewarePlugin() {
|
|
29
|
+
let root = "";
|
|
30
|
+
let isSsr = false;
|
|
31
|
+
return {
|
|
32
|
+
name: "catmint:middleware",
|
|
33
|
+
configResolved(config) {
|
|
34
|
+
root = config.root;
|
|
35
|
+
isSsr = !!config.build?.ssr;
|
|
36
|
+
},
|
|
37
|
+
/**
|
|
38
|
+
* resolveId hook — provide a virtual module for the composed middleware manifest.
|
|
39
|
+
*
|
|
40
|
+
* Modules can import `virtual:catmint/middleware-manifest` to get the
|
|
41
|
+
* pre-computed middleware chains.
|
|
42
|
+
*/
|
|
43
|
+
resolveId(id) {
|
|
44
|
+
if (id === "virtual:catmint/middleware-manifest") {
|
|
45
|
+
return "\0virtual:catmint/middleware-manifest";
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* load hook — generate the middleware manifest virtual module.
|
|
51
|
+
*/
|
|
52
|
+
async load(id) {
|
|
53
|
+
if (id !== "\0virtual:catmint/middleware-manifest")
|
|
54
|
+
return null;
|
|
55
|
+
const appDir = resolve(root, "app");
|
|
56
|
+
if (!existsSync(appDir)) {
|
|
57
|
+
return "export const middlewareChains = {};\n";
|
|
58
|
+
}
|
|
59
|
+
// Scan for all middleware files
|
|
60
|
+
const middlewareFiles = await findMiddlewareFiles(appDir);
|
|
61
|
+
if (middlewareFiles.length === 0) {
|
|
62
|
+
return "export const middlewareChains = {};\n";
|
|
63
|
+
}
|
|
64
|
+
// Generate imports and composition code
|
|
65
|
+
return generateMiddlewareManifest(middlewareFiles, appDir);
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* transform hook — optimize middleware imports in server bundles.
|
|
69
|
+
*
|
|
70
|
+
* When we detect `resolveMiddlewareChain` calls, we can replace them
|
|
71
|
+
* with direct imports of the pre-composed chain.
|
|
72
|
+
*/
|
|
73
|
+
transform(code, id) {
|
|
74
|
+
// Only optimize in SSR/server builds
|
|
75
|
+
if (!isSsr)
|
|
76
|
+
return null;
|
|
77
|
+
// Look for resolveMiddlewareChain imports and optimize them
|
|
78
|
+
if (/\bresolveMiddlewareChain\b/.test(code) &&
|
|
79
|
+
/from\s+['"]catmint\/middleware['"]/.test(code)) {
|
|
80
|
+
// Add a hint comment so the runtime can use the optimized manifest
|
|
81
|
+
const result = `import { middlewareChains as __catmintMiddlewareChains } from 'virtual:catmint/middleware-manifest';\n` +
|
|
82
|
+
code;
|
|
83
|
+
return { code: result, map: null };
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Recursively find all middleware files in the app directory.
|
|
91
|
+
*/
|
|
92
|
+
async function findMiddlewareFiles(dir) {
|
|
93
|
+
const { readdir, stat } = await import("node:fs/promises");
|
|
94
|
+
const files = [];
|
|
95
|
+
let entries;
|
|
96
|
+
try {
|
|
97
|
+
entries = await readdir(dir);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return files;
|
|
101
|
+
}
|
|
102
|
+
for (const entry of entries) {
|
|
103
|
+
const fullPath = join(dir, entry);
|
|
104
|
+
const entryStat = await stat(fullPath);
|
|
105
|
+
if (entryStat.isDirectory()) {
|
|
106
|
+
const subFiles = await findMiddlewareFiles(fullPath);
|
|
107
|
+
files.push(...subFiles);
|
|
108
|
+
}
|
|
109
|
+
else if (MIDDLEWARE_FILENAMES.includes(entry)) {
|
|
110
|
+
files.push(fullPath);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return files;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Generate the virtual middleware manifest module.
|
|
117
|
+
*
|
|
118
|
+
* The manifest maps route directory paths to arrays of middleware file paths,
|
|
119
|
+
* already sorted in execution order (root-to-tip).
|
|
120
|
+
*/
|
|
121
|
+
function generateMiddlewareManifest(middlewareFiles, appDir) {
|
|
122
|
+
const lines = [
|
|
123
|
+
"// Auto-generated middleware manifest by @catmint/vite",
|
|
124
|
+
"// Maps route directory depths to their middleware modules",
|
|
125
|
+
"",
|
|
126
|
+
];
|
|
127
|
+
// Generate imports for each middleware file
|
|
128
|
+
const imports = [];
|
|
129
|
+
for (let i = 0; i < middlewareFiles.length; i++) {
|
|
130
|
+
const filePath = middlewareFiles[i];
|
|
131
|
+
const posixPath = toPosixPath(filePath);
|
|
132
|
+
const relativePath = toPosixPath(filePath.startsWith(appDir) ? filePath.slice(appDir.length) : filePath);
|
|
133
|
+
const varName = `__mw_${i}`;
|
|
134
|
+
// Calculate depth based on directory nesting from app root
|
|
135
|
+
const dirPath = dirname(relativePath);
|
|
136
|
+
const depth = dirPath === "/" || dirPath === "."
|
|
137
|
+
? 0
|
|
138
|
+
: dirPath.split("/").filter(Boolean).length;
|
|
139
|
+
imports.push({ varName, filePath: posixPath, depth });
|
|
140
|
+
lines.push(`import ${varName} from ${JSON.stringify(posixPath)};`);
|
|
141
|
+
}
|
|
142
|
+
lines.push("");
|
|
143
|
+
lines.push("export const middlewareChains = {");
|
|
144
|
+
// Group by directory path to create chains
|
|
145
|
+
for (const imp of imports) {
|
|
146
|
+
const dirPath = dirname(toPosixPath(imp.filePath.startsWith(appDir)
|
|
147
|
+
? imp.filePath.slice(appDir.length)
|
|
148
|
+
: imp.filePath));
|
|
149
|
+
lines.push(` ${JSON.stringify(dirPath)}: ${imp.varName},`);
|
|
150
|
+
}
|
|
151
|
+
lines.push("};");
|
|
152
|
+
lines.push("");
|
|
153
|
+
return lines.join("\n");
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,kCAAkC;AAGlC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;GAEG;AACH,MAAM,oBAAoB,GAAG;IAC3B,eAAe;IACf,gBAAgB;IAChB,eAAe;IACf,gBAAgB;CACjB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,OAAO;QACL,IAAI,EAAE,oBAAoB;QAE1B,cAAc,CAAC,MAAsB;YACnC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC;QAC9B,CAAC;QAED;;;;;WAKG;QACH,SAAS,CAAC,EAAU;YAClB,IAAI,EAAE,KAAK,qCAAqC,EAAE,CAAC;gBACjD,OAAO,uCAAuC,CAAC;YACjD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,IAAI,CAAC,EAAU;YACnB,IAAI,EAAE,KAAK,uCAAuC;gBAAE,OAAO,IAAI,CAAC;YAEhE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,OAAO,uCAAuC,CAAC;YACjD,CAAC;YAED,gCAAgC;YAChC,MAAM,eAAe,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAE1D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,OAAO,uCAAuC,CAAC;YACjD,CAAC;YAED,wCAAwC;YACxC,OAAO,0BAA0B,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC7D,CAAC;QAED;;;;;WAKG;QACH,SAAS,CAAC,IAAY,EAAE,EAAU;YAChC,qCAAqC;YACrC,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YAExB,4DAA4D;YAC5D,IACE,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC;gBACvC,oCAAoC,CAAC,IAAI,CAAC,IAAI,CAAC,EAC/C,CAAC;gBACD,mEAAmE;gBACnE,MAAM,MAAM,GACV,wGAAwG;oBACxG,IAAI,CAAC;gBACP,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YACrC,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,mBAAmB,CAAC,GAAW;IAC5C,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAE3D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvC,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,0BAA0B,CACjC,eAAyB,EACzB,MAAc;IAEd,MAAM,KAAK,GAAa;QACtB,wDAAwD;QACxD,4DAA4D;QAC5D,EAAE;KACH,CAAC;IAEF,4CAA4C;IAC5C,MAAM,OAAO,GACX,EAAE,CAAC;IAEL,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,YAAY,GAAG,WAAW,CAC9B,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CACvE,CAAC;QACF,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC;QAE5B,2DAA2D;QAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QACtC,MAAM,KAAK,GACT,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,GAAG;YAChC,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAEhD,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,SAAS,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAEhD,2CAA2C;IAC3C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,OAAO,CACrB,WAAW,CACT,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC;YAC7B,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;YACnC,CAAC,CAAC,GAAG,CAAC,QAAQ,CACjB,CACF,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk up from a page file's directory to the app root, looking for
|
|
3
|
+
* the nearest error.tsx file. Returns the first one found, or null.
|
|
4
|
+
*
|
|
5
|
+
* Per PRD §18.1: error.tsx files follow the same walk-up resolution as
|
|
6
|
+
* layouts. If the current directory has no error.tsx, Catmint checks
|
|
7
|
+
* parent directories up to app/. A root app/error.tsx acts as the
|
|
8
|
+
* global fallback error boundary.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveErrorBoundary(pageFilePath: string, appDir: string): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Per PRD §4/§5: loading.tsx is a Suspense fallback rendered inside the
|
|
13
|
+
* layout while the page loads. It is resolved from the same directory as
|
|
14
|
+
* the page file.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveLoadingComponent(pageFilePath: string): string | null;
|
|
17
|
+
//# sourceMappingURL=resolve-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-utils.d.ts","sourceRoot":"","sources":["../src/resolve-utils.ts"],"names":[],"mappings":"AAQA;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAef;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc3E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// @catmint/vite/resolve-utils — file resolution helpers for error boundaries
|
|
2
|
+
// and loading components.
|
|
3
|
+
//
|
|
4
|
+
// Extracted from dev-server.ts so they can be unit-tested independently.
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
/**
|
|
8
|
+
* Walk up from a page file's directory to the app root, looking for
|
|
9
|
+
* the nearest error.tsx file. Returns the first one found, or null.
|
|
10
|
+
*
|
|
11
|
+
* Per PRD §18.1: error.tsx files follow the same walk-up resolution as
|
|
12
|
+
* layouts. If the current directory has no error.tsx, Catmint checks
|
|
13
|
+
* parent directories up to app/. A root app/error.tsx acts as the
|
|
14
|
+
* global fallback error boundary.
|
|
15
|
+
*/
|
|
16
|
+
export function resolveErrorBoundary(pageFilePath, appDir) {
|
|
17
|
+
let dir = dirname(pageFilePath);
|
|
18
|
+
while (dir.startsWith(appDir)) {
|
|
19
|
+
for (const name of ["error.tsx", "error.jsx", "error.ts", "error.js"]) {
|
|
20
|
+
const errorPath = join(dir, name);
|
|
21
|
+
if (existsSync(errorPath)) {
|
|
22
|
+
return errorPath;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (dir === appDir)
|
|
26
|
+
break;
|
|
27
|
+
dir = dirname(dir);
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Per PRD §4/§5: loading.tsx is a Suspense fallback rendered inside the
|
|
33
|
+
* layout while the page loads. It is resolved from the same directory as
|
|
34
|
+
* the page file.
|
|
35
|
+
*/
|
|
36
|
+
export function resolveLoadingComponent(pageFilePath) {
|
|
37
|
+
const dir = dirname(pageFilePath);
|
|
38
|
+
for (const name of [
|
|
39
|
+
"loading.tsx",
|
|
40
|
+
"loading.jsx",
|
|
41
|
+
"loading.ts",
|
|
42
|
+
"loading.js",
|
|
43
|
+
]) {
|
|
44
|
+
const loadingPath = join(dir, name);
|
|
45
|
+
if (existsSync(loadingPath)) {
|
|
46
|
+
return loadingPath;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=resolve-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-utils.js","sourceRoot":"","sources":["../src/resolve-utils.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,0BAA0B;AAC1B,EAAE;AACF,yEAAyE;AAEzE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,YAAoB,EACpB,MAAc;IAEd,IAAI,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAEhC,OAAO,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;YACtE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAClC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1B,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,IAAI,GAAG,KAAK,MAAM;YAAE,MAAM;QAC1B,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,YAAoB;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI;QACjB,aAAa;QACb,aAAa;QACb,YAAY;QACZ,YAAY;KACb,EAAE,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Create the route type generation Vite plugin.
|
|
4
|
+
*
|
|
5
|
+
* On startup (and on file changes in dev mode), scans the `app/` directory
|
|
6
|
+
* and generates `.catmint/routes.d.ts` with a typed RouteMap interface.
|
|
7
|
+
*
|
|
8
|
+
* Uses dynamic import of the scanner from `catmint/routing` to avoid
|
|
9
|
+
* module-level coupling.
|
|
10
|
+
*/
|
|
11
|
+
export declare function routeGenPlugin(): Plugin;
|
|
12
|
+
//# sourceMappingURL=route-gen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-gen.d.ts","sourceRoot":"","sources":["../src/route-gen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,MAAM,CAAC;AAelE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAqDvC"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// @catmint/vite/route-gen — Route type generation
|
|
2
|
+
//
|
|
3
|
+
// Scans the app/ directory and generates .catmint/routes.d.ts with a
|
|
4
|
+
// typed RouteMap interface. Watches for file changes in dev mode.
|
|
5
|
+
import { existsSync, mkdirSync, writeFileSync, watch } from "node:fs";
|
|
6
|
+
import { join, resolve } from "node:path";
|
|
7
|
+
/**
|
|
8
|
+
* Create the route type generation Vite plugin.
|
|
9
|
+
*
|
|
10
|
+
* On startup (and on file changes in dev mode), scans the `app/` directory
|
|
11
|
+
* and generates `.catmint/routes.d.ts` with a typed RouteMap interface.
|
|
12
|
+
*
|
|
13
|
+
* Uses dynamic import of the scanner from `catmint/routing` to avoid
|
|
14
|
+
* module-level coupling.
|
|
15
|
+
*/
|
|
16
|
+
export function routeGenPlugin() {
|
|
17
|
+
let root = "";
|
|
18
|
+
let appDir = "";
|
|
19
|
+
let outDir = "";
|
|
20
|
+
let watcher;
|
|
21
|
+
return {
|
|
22
|
+
name: "catmint:route-gen",
|
|
23
|
+
configResolved(config) {
|
|
24
|
+
root = config.root;
|
|
25
|
+
appDir = resolve(root, "app");
|
|
26
|
+
outDir = resolve(root, ".catmint");
|
|
27
|
+
},
|
|
28
|
+
async buildStart() {
|
|
29
|
+
await generateRouteTypes(appDir, outDir);
|
|
30
|
+
},
|
|
31
|
+
configureServer(server) {
|
|
32
|
+
// Watch app/ directory for changes and regenerate types
|
|
33
|
+
if (!existsSync(appDir))
|
|
34
|
+
return;
|
|
35
|
+
watcher = watch(appDir, { recursive: true }, (_event, filename) => {
|
|
36
|
+
if (!filename)
|
|
37
|
+
return;
|
|
38
|
+
// Only regenerate when page/layout/route files change
|
|
39
|
+
if (filename.endsWith("page.tsx") ||
|
|
40
|
+
filename.endsWith("page.jsx") ||
|
|
41
|
+
filename.endsWith("page.mdx") ||
|
|
42
|
+
filename.endsWith("layout.tsx") ||
|
|
43
|
+
filename.endsWith("layout.jsx") ||
|
|
44
|
+
filename.endsWith("endpoint.ts") ||
|
|
45
|
+
filename.endsWith("endpoint.js")) {
|
|
46
|
+
generateRouteTypes(appDir, outDir).catch((err) => {
|
|
47
|
+
server.config.logger.error(`[catmint] Failed to regenerate route types: ${err}`);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
// Ensure watcher is cleaned up when server closes
|
|
52
|
+
server.httpServer?.on("close", () => {
|
|
53
|
+
watcher?.close();
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
buildEnd() {
|
|
57
|
+
watcher?.close();
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Scan the app directory and generate the route types file.
|
|
63
|
+
* Uses a simplified scanner that doesn't require importing from catmint/routing
|
|
64
|
+
* (to avoid module-level dependency on the core package at build time).
|
|
65
|
+
*/
|
|
66
|
+
async function generateRouteTypes(appDir, outDir) {
|
|
67
|
+
if (!existsSync(appDir))
|
|
68
|
+
return;
|
|
69
|
+
let routes;
|
|
70
|
+
try {
|
|
71
|
+
// Dynamically import the scanner from catmint/routing.
|
|
72
|
+
// Use a variable to prevent TypeScript from statically resolving the import
|
|
73
|
+
// (which would pull catmint source files into this project's compilation).
|
|
74
|
+
const modulePath = "catmint/routing";
|
|
75
|
+
const mod = await import(modulePath);
|
|
76
|
+
const scannedRoutes = await mod.scanRoutes(appDir);
|
|
77
|
+
routes = scannedRoutes.map((route) => {
|
|
78
|
+
const params = {};
|
|
79
|
+
for (const seg of route.segments) {
|
|
80
|
+
if (seg.paramName) {
|
|
81
|
+
if (seg.type === "catch-all" || seg.type === "optional-catch-all") {
|
|
82
|
+
params[seg.paramName] = "string[]";
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
params[seg.paramName] = "string";
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Convert the pattern back to filesystem-style brackets for the type
|
|
90
|
+
const fsPattern = routePatternToFsPattern(route.pattern, route.segments);
|
|
91
|
+
return { pattern: fsPattern, params };
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Fallback: scan using a simple built-in scanner
|
|
96
|
+
routes = await scanRoutesSimple(appDir);
|
|
97
|
+
}
|
|
98
|
+
const typeContent = generateTypeFile(routes);
|
|
99
|
+
// Ensure .catmint directory exists
|
|
100
|
+
if (!existsSync(outDir)) {
|
|
101
|
+
mkdirSync(outDir, { recursive: true });
|
|
102
|
+
}
|
|
103
|
+
writeFileSync(join(outDir, "routes.d.ts"), typeContent, "utf-8");
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Convert a route pattern (with :param and *param syntax) back to
|
|
107
|
+
* filesystem-style [param] patterns for the type definition.
|
|
108
|
+
*/
|
|
109
|
+
function routePatternToFsPattern(pattern, segments) {
|
|
110
|
+
const parts = [];
|
|
111
|
+
for (const seg of segments) {
|
|
112
|
+
switch (seg.type) {
|
|
113
|
+
case "static":
|
|
114
|
+
parts.push(seg.raw);
|
|
115
|
+
break;
|
|
116
|
+
case "dynamic":
|
|
117
|
+
parts.push(`[${seg.paramName}]`);
|
|
118
|
+
break;
|
|
119
|
+
case "catch-all":
|
|
120
|
+
parts.push(`[...${seg.paramName}]`);
|
|
121
|
+
break;
|
|
122
|
+
case "optional-catch-all":
|
|
123
|
+
parts.push(`[[...${seg.paramName}]]`);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const result = "/" + parts.join("/");
|
|
128
|
+
return result === "/" ? "/" : result;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Simple built-in route scanner as a fallback when catmint/routing
|
|
132
|
+
* is not available (e.g. during initial setup or testing).
|
|
133
|
+
*/
|
|
134
|
+
async function scanRoutesSimple(appDir) {
|
|
135
|
+
const { readdir, stat: fsStat } = await import("node:fs/promises");
|
|
136
|
+
const { relative, sep, posix } = await import("node:path");
|
|
137
|
+
const routes = [];
|
|
138
|
+
const routeFiles = new Set(["page.tsx", "page.jsx", "page.mdx"]);
|
|
139
|
+
async function scanDir(dir) {
|
|
140
|
+
let entries;
|
|
141
|
+
try {
|
|
142
|
+
entries = await readdir(dir);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
for (const entry of entries) {
|
|
148
|
+
const fullPath = join(dir, entry);
|
|
149
|
+
const entryStat = await fsStat(fullPath);
|
|
150
|
+
if (entryStat.isDirectory()) {
|
|
151
|
+
await scanDir(fullPath);
|
|
152
|
+
}
|
|
153
|
+
else if (routeFiles.has(entry)) {
|
|
154
|
+
const relPath = relative(appDir, dir);
|
|
155
|
+
const posixPath = relPath.split(sep).join(posix.sep);
|
|
156
|
+
const dirParts = posixPath ? posixPath.split("/") : [];
|
|
157
|
+
// Filter out route groups
|
|
158
|
+
const filteredParts = dirParts.filter((p) => !/^\([^)]+\)$/.test(p));
|
|
159
|
+
const params = {};
|
|
160
|
+
const patternParts = [];
|
|
161
|
+
for (const part of filteredParts) {
|
|
162
|
+
// Optional catch-all
|
|
163
|
+
const optCatch = part.match(/^\[\[\.\.\.(\w+)\]\]$/);
|
|
164
|
+
if (optCatch) {
|
|
165
|
+
patternParts.push(`[[...${optCatch[1]}]]`);
|
|
166
|
+
params[optCatch[1]] = "string[]";
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
// Catch-all
|
|
170
|
+
const catchAll = part.match(/^\[\.\.\.(\w+)\]$/);
|
|
171
|
+
if (catchAll) {
|
|
172
|
+
patternParts.push(`[...${catchAll[1]}]`);
|
|
173
|
+
params[catchAll[1]] = "string[]";
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Dynamic
|
|
177
|
+
const dynamic = part.match(/^\[(\w+)\]$/);
|
|
178
|
+
if (dynamic) {
|
|
179
|
+
patternParts.push(`[${dynamic[1]}]`);
|
|
180
|
+
params[dynamic[1]] = "string";
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
// Static
|
|
184
|
+
patternParts.push(part);
|
|
185
|
+
}
|
|
186
|
+
const pattern = patternParts.length === 0 ? "/" : "/" + patternParts.join("/");
|
|
187
|
+
routes.push({ pattern, params });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
await scanDir(appDir);
|
|
192
|
+
return routes;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Generate the TypeScript declaration file content for the route map.
|
|
196
|
+
*/
|
|
197
|
+
function generateTypeFile(routes) {
|
|
198
|
+
const lines = [
|
|
199
|
+
"// Auto-generated by @catmint/vite. Do not edit.",
|
|
200
|
+
"// This file provides type-safe route definitions for the Catmint framework.",
|
|
201
|
+
"",
|
|
202
|
+
"export interface RouteMap {",
|
|
203
|
+
];
|
|
204
|
+
// Sort routes for deterministic output
|
|
205
|
+
const sorted = [...routes].sort((a, b) => a.pattern.localeCompare(b.pattern));
|
|
206
|
+
for (const route of sorted) {
|
|
207
|
+
const paramEntries = Object.entries(route.params);
|
|
208
|
+
if (paramEntries.length === 0) {
|
|
209
|
+
lines.push(` '${route.pattern}': {}`);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const paramStr = paramEntries
|
|
213
|
+
.map(([name, type]) => `${name}: ${type}`)
|
|
214
|
+
.join("; ");
|
|
215
|
+
lines.push(` '${route.pattern}': { ${paramStr} }`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
lines.push("}", "");
|
|
219
|
+
return lines.join("\n");
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=route-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-gen.js","sourceRoot":"","sources":["../src/route-gen.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Create the server function transform Vite plugin.
|
|
4
|
+
*
|
|
5
|
+
* In client bundles, `createServerFn` calls are transformed into `fetch()` stubs.
|
|
6
|
+
* The function name is hashed to produce a stable, opaque endpoint identifier.
|
|
7
|
+
*
|
|
8
|
+
* Additionally, inline async handlers on event props (`onClick`, `onSubmit`, etc.)
|
|
9
|
+
* in server components are extracted and compiled to server function fetch stubs.
|
|
10
|
+
*/
|
|
11
|
+
export declare function serverFnTransformPlugin(): Plugin;
|
|
12
|
+
//# sourceMappingURL=server-fn-transform.d.ts.map
|