@cr8rcho/alkahest 0.1.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/README.ko.md +208 -0
- package/README.md +208 -0
- package/dist/assets/dashboard.html +647 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +68 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/hook.d.ts +1 -0
- package/dist/commands/hook.js +64 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/login.d.ts +11 -0
- package/dist/commands/login.js +27 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/mcp.d.ts +6 -0
- package/dist/commands/mcp.js +13 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/publish.d.ts +19 -0
- package/dist/commands/publish.js +27 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/scan.d.ts +11 -0
- package/dist/commands/scan.js +29 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/update.d.ts +15 -0
- package/dist/commands/update.js +41 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/view.d.ts +6 -0
- package/dist/commands/view.js +21 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/core/adapters/angular.d.ts +2 -0
- package/dist/core/adapters/angular.js +305 -0
- package/dist/core/adapters/angular.js.map +1 -0
- package/dist/core/adapters/astro.d.ts +3 -0
- package/dist/core/adapters/astro.js +140 -0
- package/dist/core/adapters/astro.js.map +1 -0
- package/dist/core/adapters/compose.d.ts +2 -0
- package/dist/core/adapters/compose.js +195 -0
- package/dist/core/adapters/compose.js.map +1 -0
- package/dist/core/adapters/django.d.ts +2 -0
- package/dist/core/adapters/django.js +314 -0
- package/dist/core/adapters/django.js.map +1 -0
- package/dist/core/adapters/expo-router.d.ts +2 -0
- package/dist/core/adapters/expo-router.js +60 -0
- package/dist/core/adapters/expo-router.js.map +1 -0
- package/dist/core/adapters/flask.d.ts +2 -0
- package/dist/core/adapters/flask.js +249 -0
- package/dist/core/adapters/flask.js.map +1 -0
- package/dist/core/adapters/flutter.d.ts +2 -0
- package/dist/core/adapters/flutter.js +232 -0
- package/dist/core/adapters/flutter.js.map +1 -0
- package/dist/core/adapters/index.d.ts +19 -0
- package/dist/core/adapters/index.js +59 -0
- package/dist/core/adapters/index.js.map +1 -0
- package/dist/core/adapters/next-app.d.ts +2 -0
- package/dist/core/adapters/next-app.js +62 -0
- package/dist/core/adapters/next-app.js.map +1 -0
- package/dist/core/adapters/next-pages.d.ts +2 -0
- package/dist/core/adapters/next-pages.js +70 -0
- package/dist/core/adapters/next-pages.js.map +1 -0
- package/dist/core/adapters/nuxt.d.ts +2 -0
- package/dist/core/adapters/nuxt.js +59 -0
- package/dist/core/adapters/nuxt.js.map +1 -0
- package/dist/core/adapters/rails.d.ts +2 -0
- package/dist/core/adapters/rails.js +275 -0
- package/dist/core/adapters/rails.js.map +1 -0
- package/dist/core/adapters/react-jsx.d.ts +68 -0
- package/dist/core/adapters/react-jsx.js +355 -0
- package/dist/core/adapters/react-jsx.js.map +1 -0
- package/dist/core/adapters/react-navigation.d.ts +2 -0
- package/dist/core/adapters/react-navigation.js +153 -0
- package/dist/core/adapters/react-navigation.js.map +1 -0
- package/dist/core/adapters/react-router.d.ts +2 -0
- package/dist/core/adapters/react-router.js +249 -0
- package/dist/core/adapters/react-router.js.map +1 -0
- package/dist/core/adapters/remix.d.ts +2 -0
- package/dist/core/adapters/remix.js +109 -0
- package/dist/core/adapters/remix.js.map +1 -0
- package/dist/core/adapters/static-html.d.ts +2 -0
- package/dist/core/adapters/static-html.js +157 -0
- package/dist/core/adapters/static-html.js.map +1 -0
- package/dist/core/adapters/sveltekit.d.ts +2 -0
- package/dist/core/adapters/sveltekit.js +151 -0
- package/dist/core/adapters/sveltekit.js.map +1 -0
- package/dist/core/adapters/swiftui.d.ts +2 -0
- package/dist/core/adapters/swiftui.js +216 -0
- package/dist/core/adapters/swiftui.js.map +1 -0
- package/dist/core/adapters/types.d.ts +65 -0
- package/dist/core/adapters/types.js +2 -0
- package/dist/core/adapters/types.js.map +1 -0
- package/dist/core/adapters/uikit.d.ts +2 -0
- package/dist/core/adapters/uikit.js +178 -0
- package/dist/core/adapters/uikit.js.map +1 -0
- package/dist/core/adapters/vue-router.d.ts +2 -0
- package/dist/core/adapters/vue-router.js +224 -0
- package/dist/core/adapters/vue-router.js.map +1 -0
- package/dist/core/adapters/vue-sfc.d.ts +28 -0
- package/dist/core/adapters/vue-sfc.js +132 -0
- package/dist/core/adapters/vue-sfc.js.map +1 -0
- package/dist/core/credentials.d.ts +24 -0
- package/dist/core/credentials.js +30 -0
- package/dist/core/credentials.js.map +1 -0
- package/dist/core/dashboard.d.ts +9 -0
- package/dist/core/dashboard.js +20 -0
- package/dist/core/dashboard.js.map +1 -0
- package/dist/core/emit.d.ts +7 -0
- package/dist/core/emit.js +23 -0
- package/dist/core/emit.js.map +1 -0
- package/dist/core/hash.d.ts +2 -0
- package/dist/core/hash.js +6 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/pipeline.d.ts +25 -0
- package/dist/core/pipeline.js +122 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/publish.d.ts +31 -0
- package/dist/core/publish.js +87 -0
- package/dist/core/publish.js.map +1 -0
- package/dist/core/resolve.d.ts +42 -0
- package/dist/core/resolve.js +128 -0
- package/dist/core/resolve.js.map +1 -0
- package/dist/core/serve.d.ts +5 -0
- package/dist/core/serve.js +52 -0
- package/dist/core/serve.js.map +1 -0
- package/dist/core/types.d.ts +117 -0
- package/dist/core/types.js +9 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/version.d.ts +23 -0
- package/dist/core/version.js +102 -0
- package/dist/core/version.js.map +1 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +224 -0
- package/dist/mcp/server.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative, sep, dirname } from "node:path";
|
|
3
|
+
import { Node, SyntaxKind } from "ts-morph";
|
|
4
|
+
import { walk, sourceFileFor, parseReactScreen, titleFromRoute, hasDependency, importMap, resolveComponentFile, } from "./react-jsx.js";
|
|
5
|
+
/**
|
|
6
|
+
* React Router adapter (generic React SPA: Vite / CRA). Routes are *declared*, not
|
|
7
|
+
* file-based — so discover parses the router config (data router objects and/or JSX
|
|
8
|
+
* <Routes>/<Route>), maps each route to the component it renders, and resolves that
|
|
9
|
+
* component to its source file. parse() then runs the shared JSX parser on that file.
|
|
10
|
+
*
|
|
11
|
+
* Screen id = full route path ("/dashboard/settings"). Entry = "/".
|
|
12
|
+
* Supported route forms:
|
|
13
|
+
* - createBrowserRouter / createHashRouter / createMemoryRouter ([{ path, element, children }])
|
|
14
|
+
* - JSX <Routes><Route path element /></Routes> (incl. nested + index routes)
|
|
15
|
+
* - element={<X/>} or Component={X}; lazy(() => import("…")) component imports
|
|
16
|
+
*/
|
|
17
|
+
const ROUTER_CALLS = new Set(["createBrowserRouter", "createHashRouter", "createMemoryRouter"]);
|
|
18
|
+
const SOURCE_RE = /\.(tsx|jsx|ts|js)$/;
|
|
19
|
+
const CONFIG_HINT = /create(Browser|Hash|Memory)Router|createRoutesFromElements|<Routes[\s>]|<Route[\s/>]/;
|
|
20
|
+
function srcRootOf(projectRoot) {
|
|
21
|
+
const src = join(projectRoot, "src");
|
|
22
|
+
return existsSync(src) && statSync(src).isDirectory() ? src : projectRoot;
|
|
23
|
+
}
|
|
24
|
+
export const reactRouterAdapter = {
|
|
25
|
+
id: "react-router",
|
|
26
|
+
router: "react-router",
|
|
27
|
+
detect(projectRoot) {
|
|
28
|
+
return hasDependency(projectRoot, "react-router-dom", "react-router");
|
|
29
|
+
},
|
|
30
|
+
discover(projectRoot) {
|
|
31
|
+
const root = srcRootOf(projectRoot);
|
|
32
|
+
const byRoute = new Map();
|
|
33
|
+
walk(root, (file) => {
|
|
34
|
+
if (!SOURCE_RE.test(file))
|
|
35
|
+
return;
|
|
36
|
+
const src = safeRead(file);
|
|
37
|
+
if (!CONFIG_HINT.test(src))
|
|
38
|
+
return; // cheap pre-filter before parsing
|
|
39
|
+
const sf = sourceFileFor(file);
|
|
40
|
+
const entries = [...routesFromDataRouter(sf), ...routesFromJsx(sf)];
|
|
41
|
+
if (entries.length === 0)
|
|
42
|
+
return;
|
|
43
|
+
const imports = importMap(sf);
|
|
44
|
+
const configDir = dirname(file);
|
|
45
|
+
for (const { route, component } of entries) {
|
|
46
|
+
if (byRoute.has(route))
|
|
47
|
+
continue; // first declaration wins
|
|
48
|
+
const abs = component ? resolveComponentFile(configDir, imports.get(component)) : null;
|
|
49
|
+
if (!abs)
|
|
50
|
+
continue; // can't open the component → can't extract signals; skip
|
|
51
|
+
byRoute.set(route, {
|
|
52
|
+
absPath: abs,
|
|
53
|
+
relPath: relative(projectRoot, abs).split(sep).join("/"),
|
|
54
|
+
id: route,
|
|
55
|
+
route,
|
|
56
|
+
title: titleFromRoute(route),
|
|
57
|
+
isEntry: route === "/",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return [...byRoute.values()].sort((a, b) => a.route.localeCompare(b.route));
|
|
62
|
+
},
|
|
63
|
+
parse(file) {
|
|
64
|
+
return parseReactScreen(sourceFileFor(file.absPath));
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
// ---------- route extraction ----------
|
|
68
|
+
/** createBrowserRouter([...]) and friends → flattened routes (paths joined through children). */
|
|
69
|
+
function routesFromDataRouter(sf) {
|
|
70
|
+
const out = [];
|
|
71
|
+
for (const ce of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
72
|
+
const expr = ce.getExpression();
|
|
73
|
+
if (!Node.isIdentifier(expr) || !ROUTER_CALLS.has(expr.getText()))
|
|
74
|
+
continue;
|
|
75
|
+
const arg = ce.getArguments()[0];
|
|
76
|
+
if (arg && Node.isArrayLiteralExpression(arg))
|
|
77
|
+
walkRouteArray(arg, "/", out);
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
function walkRouteArray(arr, parentPath, out) {
|
|
82
|
+
if (!Node.isArrayLiteralExpression(arr))
|
|
83
|
+
return;
|
|
84
|
+
for (const el of arr.getElements()) {
|
|
85
|
+
if (Node.isObjectLiteralExpression(el))
|
|
86
|
+
walkRouteObject(el, parentPath, out);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function walkRouteObject(obj, parentPath, out) {
|
|
90
|
+
const isIndex = boolProp(obj, "index");
|
|
91
|
+
const pathVal = stringProp(obj, "path");
|
|
92
|
+
const route = isIndex ? parentPath : joinRoute(parentPath, pathVal);
|
|
93
|
+
const component = componentOfObject(obj);
|
|
94
|
+
if (component || pathVal != null || isIndex)
|
|
95
|
+
out.push({ route, component });
|
|
96
|
+
const childrenProp = obj.getProperty("children");
|
|
97
|
+
if (childrenProp && Node.isPropertyAssignment(childrenProp)) {
|
|
98
|
+
const init = childrenProp.getInitializer();
|
|
99
|
+
if (init)
|
|
100
|
+
walkRouteArray(init, route, out);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** <Routes><Route .../></Routes> and createRoutesFromElements(...) → flattened routes. */
|
|
104
|
+
function routesFromJsx(sf) {
|
|
105
|
+
const out = [];
|
|
106
|
+
const routes = [
|
|
107
|
+
...sf.getDescendantsOfKind(SyntaxKind.JsxElement),
|
|
108
|
+
...sf.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement),
|
|
109
|
+
].filter((el) => tagName(el) === "Route");
|
|
110
|
+
for (const el of routes) {
|
|
111
|
+
if (nearestRouteAncestor(el))
|
|
112
|
+
continue; // children handled via recursion from their parent
|
|
113
|
+
walkRouteJsx(el, "/", out);
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
function walkRouteJsx(el, parentPath, out) {
|
|
118
|
+
const isIndex = jsxBoolAttr(el, "index");
|
|
119
|
+
const pathVal = jsxStringAttr(el, "path");
|
|
120
|
+
const route = isIndex ? parentPath : joinRoute(parentPath, pathVal);
|
|
121
|
+
const component = componentOfJsx(el);
|
|
122
|
+
if (component || pathVal != null || isIndex)
|
|
123
|
+
out.push({ route, component });
|
|
124
|
+
if (Node.isJsxElement(el)) {
|
|
125
|
+
for (const child of el.getJsxChildren()) {
|
|
126
|
+
if ((Node.isJsxElement(child) || Node.isJsxSelfClosingElement(child)) && tagName(child) === "Route") {
|
|
127
|
+
walkRouteJsx(child, route, out);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// ---------- small ts-morph helpers ----------
|
|
133
|
+
function tagName(el) {
|
|
134
|
+
return Node.isJsxElement(el) ? el.getOpeningElement().getTagNameNode().getText() : el.getTagNameNode().getText();
|
|
135
|
+
}
|
|
136
|
+
function nearestRouteAncestor(el) {
|
|
137
|
+
for (let p = el.getParent(); p; p = p.getParent()) {
|
|
138
|
+
if ((Node.isJsxElement(p) || Node.isJsxSelfClosingElement(p)) && tagName(p) === "Route")
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
/** element={<X/>} / Component={X} → "X". */
|
|
144
|
+
function componentOfJsx(el) {
|
|
145
|
+
const attrs = Node.isJsxElement(el) ? el.getOpeningElement() : el;
|
|
146
|
+
const element = attrs.getAttribute("element");
|
|
147
|
+
if (element && Node.isJsxAttribute(element)) {
|
|
148
|
+
const init = element.getInitializer();
|
|
149
|
+
if (init && Node.isJsxExpression(init)) {
|
|
150
|
+
const inner = init.getExpression();
|
|
151
|
+
if (inner && (Node.isJsxElement(inner) || Node.isJsxSelfClosingElement(inner)))
|
|
152
|
+
return tagName(inner);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const comp = attrs.getAttribute("Component");
|
|
156
|
+
if (comp && Node.isJsxAttribute(comp)) {
|
|
157
|
+
const init = comp.getInitializer();
|
|
158
|
+
if (init && Node.isJsxExpression(init)) {
|
|
159
|
+
const inner = init.getExpression();
|
|
160
|
+
if (inner && Node.isIdentifier(inner))
|
|
161
|
+
return inner.getText();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
/** { element: <X/> } / { Component: X } → "X". */
|
|
167
|
+
function componentOfObject(obj) {
|
|
168
|
+
const element = obj.getProperty("element");
|
|
169
|
+
if (element && Node.isPropertyAssignment(element)) {
|
|
170
|
+
const init = element.getInitializer();
|
|
171
|
+
if (init && (Node.isJsxElement(init) || Node.isJsxSelfClosingElement(init)))
|
|
172
|
+
return tagName(init);
|
|
173
|
+
}
|
|
174
|
+
const comp = obj.getProperty("Component");
|
|
175
|
+
if (comp && Node.isPropertyAssignment(comp)) {
|
|
176
|
+
const init = comp.getInitializer();
|
|
177
|
+
if (init && Node.isIdentifier(init))
|
|
178
|
+
return init.getText();
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
function stringProp(obj, name) {
|
|
183
|
+
const prop = obj.getProperty(name);
|
|
184
|
+
if (prop && Node.isPropertyAssignment(prop)) {
|
|
185
|
+
const init = prop.getInitializer();
|
|
186
|
+
if (init && Node.isStringLiteral(init))
|
|
187
|
+
return init.getLiteralValue();
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
function boolProp(obj, name) {
|
|
192
|
+
const prop = obj.getProperty(name);
|
|
193
|
+
if (prop && Node.isPropertyAssignment(prop)) {
|
|
194
|
+
return prop.getInitializer()?.getText() === "true";
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
function jsxStringAttr(el, name) {
|
|
199
|
+
const attrs = Node.isJsxElement(el) ? el.getOpeningElement() : el;
|
|
200
|
+
const attr = attrs.getAttribute(name);
|
|
201
|
+
if (!attr || !Node.isJsxAttribute(attr))
|
|
202
|
+
return null;
|
|
203
|
+
const init = attr.getInitializer();
|
|
204
|
+
if (!init)
|
|
205
|
+
return null;
|
|
206
|
+
if (Node.isStringLiteral(init))
|
|
207
|
+
return init.getLiteralValue();
|
|
208
|
+
if (Node.isJsxExpression(init)) {
|
|
209
|
+
const inner = init.getExpression();
|
|
210
|
+
if (inner && Node.isStringLiteral(inner))
|
|
211
|
+
return inner.getLiteralValue();
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
/** Bare boolean attr (`index`) or `index={true}`. */
|
|
216
|
+
function jsxBoolAttr(el, name) {
|
|
217
|
+
const attrs = Node.isJsxElement(el) ? el.getOpeningElement() : el;
|
|
218
|
+
const attr = attrs.getAttribute(name);
|
|
219
|
+
if (!attr || !Node.isJsxAttribute(attr))
|
|
220
|
+
return false;
|
|
221
|
+
const init = attr.getInitializer();
|
|
222
|
+
if (!init)
|
|
223
|
+
return true; // bare `index`
|
|
224
|
+
if (Node.isJsxExpression(init))
|
|
225
|
+
return init.getExpression()?.getText() === "true";
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
/** Join a child route segment onto a parent path (react-router relative semantics). */
|
|
229
|
+
function joinRoute(parent, child) {
|
|
230
|
+
if (child == null || child === "")
|
|
231
|
+
return parent || "/";
|
|
232
|
+
if (child.startsWith("/"))
|
|
233
|
+
return normalize(child);
|
|
234
|
+
const base = parent === "/" ? "" : parent;
|
|
235
|
+
return normalize(base + "/" + child);
|
|
236
|
+
}
|
|
237
|
+
function normalize(route) {
|
|
238
|
+
const r = ("/" + route).replace(/\/{2,}/g, "/");
|
|
239
|
+
return r.length > 1 ? r.replace(/\/+$/, "") : "/";
|
|
240
|
+
}
|
|
241
|
+
function safeRead(file) {
|
|
242
|
+
try {
|
|
243
|
+
return readFileSync(file, "utf8");
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
return "";
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=react-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-router.js","sourceRoot":"","sources":["../../../src/core/adapters/react-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { readdirSync, existsSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative, sep } from "node:path";
|
|
3
|
+
import { sourceFileFor, parseReactScreen, titleFromRoute, hasDependency } from "./react-jsx.js";
|
|
4
|
+
/**
|
|
5
|
+
* Remix / React Router 7 (framework mode) adapter. File-based flat routes under `app/routes/`,
|
|
6
|
+
* parsed with the shared React JSX parser (Remix screens are JSX, same as Next/React Router).
|
|
7
|
+
*
|
|
8
|
+
* Flat-route naming → route:
|
|
9
|
+
* - `.` separates path segments: `blog.$slug.tsx` → `/blog/:slug`
|
|
10
|
+
* - `_index` is the index route (collapses to its parent): `_index.tsx` → `/`, `blog._index.tsx` → `/blog`
|
|
11
|
+
* - a leading-underscore segment is a pathless layout (dropped): `_auth.login.tsx` → `/login`
|
|
12
|
+
* - `$param` → `:param`, bare `$` → `*` (splat)
|
|
13
|
+
* - folder form `routes/blog/route.tsx` is treated like `routes/blog.tsx`
|
|
14
|
+
* Screen id = route path; entry = "/".
|
|
15
|
+
*/
|
|
16
|
+
const ROUTE_RE = /\.(tsx|jsx|ts|js)$/;
|
|
17
|
+
function routesDirOf(projectRoot) {
|
|
18
|
+
return ([join(projectRoot, "app", "routes"), join(projectRoot, "src", "app", "routes")].find((d) => existsSync(d) && statSync(d).isDirectory()) ?? null);
|
|
19
|
+
}
|
|
20
|
+
export const remixAdapter = {
|
|
21
|
+
id: "remix",
|
|
22
|
+
router: "remix-routes",
|
|
23
|
+
detect(projectRoot) {
|
|
24
|
+
return (hasDependency(projectRoot, "@remix-run/react", "@remix-run/node", "@remix-run/dev", "@react-router/dev") &&
|
|
25
|
+
routesDirOf(projectRoot) !== null);
|
|
26
|
+
},
|
|
27
|
+
discover(projectRoot) {
|
|
28
|
+
const routesDir = routesDirOf(projectRoot);
|
|
29
|
+
if (!routesDir)
|
|
30
|
+
return [];
|
|
31
|
+
const files = [];
|
|
32
|
+
const seen = new Set();
|
|
33
|
+
for (const { abs, routeName } of routeModules(routesDir)) {
|
|
34
|
+
const route = routeFromFlat(routeName);
|
|
35
|
+
if (route == null || seen.has(route))
|
|
36
|
+
continue;
|
|
37
|
+
seen.add(route);
|
|
38
|
+
files.push({
|
|
39
|
+
absPath: abs,
|
|
40
|
+
relPath: relative(projectRoot, abs).split(sep).join("/"),
|
|
41
|
+
id: route,
|
|
42
|
+
route,
|
|
43
|
+
title: titleFromRoute(route),
|
|
44
|
+
isEntry: route === "/",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
files.sort((a, b) => a.route.localeCompare(b.route));
|
|
48
|
+
return files;
|
|
49
|
+
},
|
|
50
|
+
parse(file) {
|
|
51
|
+
return parseReactScreen(sourceFileFor(file.absPath));
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
// ---------- route module enumeration ----------
|
|
55
|
+
/** Each route module = a flat file `routes/<name>.tsx` or a folder `routes/<name>/route.tsx`. */
|
|
56
|
+
function routeModules(routesDir) {
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const entry of safeReaddir(routesDir)) {
|
|
59
|
+
if (entry.name.startsWith("."))
|
|
60
|
+
continue;
|
|
61
|
+
const full = join(routesDir, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
const routeFile = ["route.tsx", "route.jsx", "route.ts", "route.js"]
|
|
64
|
+
.map((f) => join(full, f))
|
|
65
|
+
.find((f) => existsSync(f));
|
|
66
|
+
if (routeFile)
|
|
67
|
+
out.push({ abs: routeFile, routeName: entry.name });
|
|
68
|
+
}
|
|
69
|
+
else if (ROUTE_RE.test(entry.name)) {
|
|
70
|
+
out.push({ abs: full, routeName: entry.name.replace(ROUTE_RE, "") });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
function safeReaddir(dir) {
|
|
76
|
+
try {
|
|
77
|
+
return readdirSync(dir, { withFileTypes: true });
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// ---------- flat-route name → route path ----------
|
|
84
|
+
/** Convert a Remix flat-route name (no extension) to a URL path. Null if it's not a routable module. */
|
|
85
|
+
function routeFromFlat(name) {
|
|
86
|
+
// Skip non-route conventions that sometimes live in routes/ as plain files.
|
|
87
|
+
if (name === "root")
|
|
88
|
+
return null;
|
|
89
|
+
const segs = [];
|
|
90
|
+
for (const raw of name.split(".")) {
|
|
91
|
+
if (raw === "_index" || raw === "")
|
|
92
|
+
continue; // index marker / empty
|
|
93
|
+
if (raw.startsWith("_"))
|
|
94
|
+
continue; // pathless layout segment (dropped from URL)
|
|
95
|
+
if (raw === "$") {
|
|
96
|
+
segs.push("*"); // splat
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (raw.startsWith("$")) {
|
|
100
|
+
segs.push(":" + raw.slice(1)); // $slug → :slug
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
// `parent_` (trailing underscore = break out of layout nesting) keeps the literal sans the underscore
|
|
104
|
+
segs.push(raw.replace(/_$/, ""));
|
|
105
|
+
}
|
|
106
|
+
const route = "/" + segs.join("/");
|
|
107
|
+
return route.length > 1 ? route.replace(/\/+$/, "") : "/";
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=remix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remix.js","sourceRoot":"","sources":["../../../src/core/adapters/remix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join, relative, sep, posix } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Plain multi-page HTML sites — the lowest-fidelity fallback (registered last). Each `.html`
|
|
5
|
+
* file is a page; cross-page `<a href>` links are transitions. Zero-dependency regex scan.
|
|
6
|
+
*
|
|
7
|
+
* Because it's last in the registry, by the time this runs the project matched no framework —
|
|
8
|
+
* so "a folder of .html files" still yields a product map.
|
|
9
|
+
*
|
|
10
|
+
* Mapping:
|
|
11
|
+
* - screen id = the page's route ("/about", "/docs/intro"; index.html → its dir)
|
|
12
|
+
* - nav = <a href="other.html"> resolved (relative to the page) to a route id
|
|
13
|
+
* - call = <form action> / <script> fetch()/XHR
|
|
14
|
+
* - feature = <button>, <input|textarea|select>, <form>
|
|
15
|
+
*/
|
|
16
|
+
const HTML_RE = /\.html?$/i;
|
|
17
|
+
const SKIP_DIRS = /^(node_modules|dist|build|out|coverage|\.git)$/i;
|
|
18
|
+
export const staticHtmlAdapter = {
|
|
19
|
+
id: "static",
|
|
20
|
+
router: "static-html",
|
|
21
|
+
detect(projectRoot) {
|
|
22
|
+
let found = false;
|
|
23
|
+
walkHtml(projectRoot, () => {
|
|
24
|
+
found = true;
|
|
25
|
+
});
|
|
26
|
+
return found;
|
|
27
|
+
},
|
|
28
|
+
discover(projectRoot) {
|
|
29
|
+
const files = [];
|
|
30
|
+
walkHtml(projectRoot, (file) => {
|
|
31
|
+
const route = routeFromHtmlFile(projectRoot, file);
|
|
32
|
+
files.push({
|
|
33
|
+
absPath: file,
|
|
34
|
+
relPath: relative(projectRoot, file).split(sep).join("/"),
|
|
35
|
+
id: route,
|
|
36
|
+
route,
|
|
37
|
+
title: titleFromHtmlFile(route, file),
|
|
38
|
+
isEntry: route === "/",
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
files.sort((a, b) => a.route.localeCompare(b.route));
|
|
42
|
+
return files;
|
|
43
|
+
},
|
|
44
|
+
parse(file) {
|
|
45
|
+
return parseHtml(safeRead(file.absPath), file.route);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
// ---------- discovery ----------
|
|
49
|
+
function walkHtml(dir, onFile) {
|
|
50
|
+
let entries;
|
|
51
|
+
try {
|
|
52
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
if (entry.name.startsWith(".") || SKIP_DIRS.test(entry.name))
|
|
59
|
+
continue;
|
|
60
|
+
const full = join(dir, entry.name);
|
|
61
|
+
if (entry.isDirectory())
|
|
62
|
+
walkHtml(full, onFile);
|
|
63
|
+
else if (HTML_RE.test(entry.name))
|
|
64
|
+
onFile(full);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** File path → route. `index.html` collapses to its dir; ".html" stripped; leading "/". */
|
|
68
|
+
function routeFromHtmlFile(root, file) {
|
|
69
|
+
const rel = relative(root, file).split(sep).join("/").replace(HTML_RE, "");
|
|
70
|
+
const segs = rel.split("/").filter(Boolean);
|
|
71
|
+
if (segs[segs.length - 1] === "index")
|
|
72
|
+
segs.pop();
|
|
73
|
+
const route = "/" + segs.join("/");
|
|
74
|
+
return route.length > 1 ? route.replace(/\/+$/, "") : "/";
|
|
75
|
+
}
|
|
76
|
+
function titleFromHtmlFile(route, file) {
|
|
77
|
+
// Prefer the page's <title>, else derive from the route's last segment.
|
|
78
|
+
const m = safeRead(file).match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
79
|
+
if (m && m[1].trim())
|
|
80
|
+
return m[1].trim();
|
|
81
|
+
if (route === "/")
|
|
82
|
+
return "Home";
|
|
83
|
+
const last = route.split("/").filter(Boolean).pop() ?? route;
|
|
84
|
+
return last.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
85
|
+
}
|
|
86
|
+
function safeRead(file) {
|
|
87
|
+
try {
|
|
88
|
+
return readFileSync(file, "utf8");
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return "";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ---------- parsing (regex scan) ----------
|
|
95
|
+
const FEATURE_RULES = [
|
|
96
|
+
{ re: /<button\b[^>]*>([^<]*)/i, kind: "button", label: (m) => m[1].trim() || "Button" },
|
|
97
|
+
{ re: /<(?:input|textarea|select)\b[^>]*\bplaceholder=["']([^"']*)["']/i, kind: "input", label: (m) => m[1] || "Input" },
|
|
98
|
+
{ re: /<(?:input|textarea|select)\b/i, kind: "input", label: () => "Input" },
|
|
99
|
+
{ re: /<form\b/i, kind: "form", label: () => "Form" },
|
|
100
|
+
];
|
|
101
|
+
const HREF = /<a\b[^>]*?\shref=["']([^"'#]+)["']/i;
|
|
102
|
+
const FORM_ACTION = /<form\b[^>]*?\saction=["']([^"']+)["']/i;
|
|
103
|
+
const FETCH = /\bfetch\s*\(\s*["'`]([^"'`]+)["'`]/;
|
|
104
|
+
/** `routeBase` is the page's own route, used to resolve relative <a href> into absolute route ids. */
|
|
105
|
+
function parseHtml(src, routeBase) {
|
|
106
|
+
const navs = [];
|
|
107
|
+
const calls = [];
|
|
108
|
+
const features = [];
|
|
109
|
+
const lines = src.split(/\r?\n/);
|
|
110
|
+
for (let i = 0; i < lines.length; i++) {
|
|
111
|
+
const line = lines[i].trim();
|
|
112
|
+
const lineNo = i + 1;
|
|
113
|
+
const href = line.match(HREF);
|
|
114
|
+
if (href) {
|
|
115
|
+
const target = resolveHref(href[1], routeBase);
|
|
116
|
+
navs.push({ target, raw: snippet(line), trigger: "<a href>", line: lineNo });
|
|
117
|
+
}
|
|
118
|
+
const action = line.match(FORM_ACTION);
|
|
119
|
+
if (action)
|
|
120
|
+
calls.push({ url: action[1], method: "POST", raw: snippet(line), trigger: "<form action>", line: lineNo });
|
|
121
|
+
const fetchM = line.match(FETCH);
|
|
122
|
+
if (fetchM)
|
|
123
|
+
calls.push({ url: fetchM[1], raw: snippet(line), trigger: "fetch", line: lineNo });
|
|
124
|
+
for (const rule of FEATURE_RULES) {
|
|
125
|
+
const m = line.match(rule.re);
|
|
126
|
+
if (m) {
|
|
127
|
+
features.push({ kind: rule.kind, label: rule.label(m), detail: m[0].trim().slice(0, 40), line: lineNo });
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { navs, calls, features, components: [], contains: [] };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve an <a href> to a screen-route id so transitions match other pages.
|
|
136
|
+
* External URLs pass through untouched; otherwise strip ".html"/query, resolve relative to the
|
|
137
|
+
* page's route dir, and collapse a trailing "index".
|
|
138
|
+
*/
|
|
139
|
+
function resolveHref(href, routeBase) {
|
|
140
|
+
if (/^https?:\/\//i.test(href) || href.startsWith("mailto:") || href.startsWith("tel:"))
|
|
141
|
+
return href;
|
|
142
|
+
const clean = href.split(/[?#]/)[0].replace(HTML_RE, "");
|
|
143
|
+
if (!clean)
|
|
144
|
+
return routeBase;
|
|
145
|
+
const baseDir = routeBase === "/" ? "/" : routeBase.replace(/\/[^/]*$/, "") || "/";
|
|
146
|
+
const abs = clean.startsWith("/") ? clean : posix.join(baseDir, clean);
|
|
147
|
+
const segs = abs.split("/").filter(Boolean);
|
|
148
|
+
if (segs[segs.length - 1] === "index")
|
|
149
|
+
segs.pop();
|
|
150
|
+
const route = "/" + segs.join("/");
|
|
151
|
+
return route.length > 1 ? route.replace(/\/+$/, "") : "/";
|
|
152
|
+
}
|
|
153
|
+
function snippet(text) {
|
|
154
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
155
|
+
return flat.length > 80 ? flat.slice(0, 77) + "..." : flat;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=static-html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-html.js","sourceRoot":"","sources":["../../../src/core/adapters/static-html.ts"],"names":[],"mappings":"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"}
|