@neat.is/core 0.6.2-dev.20260724 → 0.6.2
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/dist/{chunk-ZZ3VUCWL.js → chunk-AOWANF2K.js} +46 -15
- package/dist/chunk-AOWANF2K.js.map +1 -0
- package/dist/{chunk-64JJOXES.js → chunk-MSZ4NALT.js} +59 -26
- package/dist/chunk-MSZ4NALT.js.map +1 -0
- package/dist/cli.cjs +311 -26
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +17 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +104 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +104 -41
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +45 -14
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-64JJOXES.js.map +0 -1
- package/dist/chunk-ZZ3VUCWL.js.map +0 -1
package/dist/neatd.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
reconcileDaemonRecordSync,
|
|
4
4
|
startDaemon
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MSZ4NALT.js";
|
|
6
6
|
import {
|
|
7
7
|
listProjects,
|
|
8
8
|
registryPath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-AOWANF2K.js";
|
|
10
10
|
import {
|
|
11
11
|
BindAuthorityError,
|
|
12
12
|
__require
|
package/dist/server.cjs
CHANGED
|
@@ -6193,7 +6193,7 @@ function keywordArrayStrings(argsNode, key) {
|
|
|
6193
6193
|
}
|
|
6194
6194
|
return [];
|
|
6195
6195
|
}
|
|
6196
|
-
function
|
|
6196
|
+
function collectPythonRouterPrefixes(root) {
|
|
6197
6197
|
const prefixes = /* @__PURE__ */ new Map();
|
|
6198
6198
|
walk(root, (node) => {
|
|
6199
6199
|
if (node.type !== "assignment") return;
|
|
@@ -6202,7 +6202,8 @@ function collectApiRouterPrefixes(root) {
|
|
|
6202
6202
|
const fn = right.childForFieldName("function");
|
|
6203
6203
|
if (!fn) return;
|
|
6204
6204
|
const ctor = fn.type === "attribute" ? fn.childForFieldName("attribute")?.text : fn.text;
|
|
6205
|
-
|
|
6205
|
+
const prefixKey = ctor === "APIRouter" ? "prefix" : ctor === "Blueprint" ? "url_prefix" : null;
|
|
6206
|
+
if (!prefixKey) return;
|
|
6206
6207
|
const left = node.childForFieldName("left");
|
|
6207
6208
|
if (!left || left.type !== "identifier") return;
|
|
6208
6209
|
const args = right.childForFieldName("arguments");
|
|
@@ -6210,7 +6211,7 @@ function collectApiRouterPrefixes(root) {
|
|
|
6210
6211
|
for (let i = 0; i < args.namedChildCount; i++) {
|
|
6211
6212
|
const arg = args.namedChild(i);
|
|
6212
6213
|
if (arg?.type !== "keyword_argument") continue;
|
|
6213
|
-
if (arg.childForFieldName("name")?.text !==
|
|
6214
|
+
if (arg.childForFieldName("name")?.text !== prefixKey) continue;
|
|
6214
6215
|
const val = arg.childForFieldName("value");
|
|
6215
6216
|
const p = val ? pyStaticStringText(val) : null;
|
|
6216
6217
|
if (p !== null) prefixes.set(left.text, p);
|
|
@@ -6218,9 +6219,9 @@ function collectApiRouterPrefixes(root) {
|
|
|
6218
6219
|
});
|
|
6219
6220
|
return prefixes;
|
|
6220
6221
|
}
|
|
6221
|
-
function
|
|
6222
|
+
function pythonRoutesFromSource(source, parser, framework) {
|
|
6222
6223
|
const tree = parseSource2(parser, source);
|
|
6223
|
-
const prefixes =
|
|
6224
|
+
const prefixes = collectPythonRouterPrefixes(tree.rootNode);
|
|
6224
6225
|
const out = [];
|
|
6225
6226
|
walk(tree.rootNode, (node) => {
|
|
6226
6227
|
if (node.type !== "decorator") return;
|
|
@@ -6231,7 +6232,9 @@ function fastapiRoutesFromSource(source, parser) {
|
|
|
6231
6232
|
const method = fn.childForFieldName("attribute")?.text?.toLowerCase();
|
|
6232
6233
|
if (!method) return;
|
|
6233
6234
|
const isVerb = FASTAPI_METHODS.has(method);
|
|
6234
|
-
|
|
6235
|
+
const isFlaskRoute = method === "route";
|
|
6236
|
+
const isApiRoute = method === "api_route";
|
|
6237
|
+
if (!isVerb && !isFlaskRoute && !isApiRoute) return;
|
|
6235
6238
|
const args = call.childForFieldName("arguments");
|
|
6236
6239
|
const first = args?.namedChild(0);
|
|
6237
6240
|
if (!first || first.type !== "string") return;
|
|
@@ -6242,17 +6245,41 @@ function fastapiRoutesFromSource(source, parser) {
|
|
|
6242
6245
|
const pathTemplate = canonicalizeTemplate(prefix + rawPath);
|
|
6243
6246
|
const line = node.startPosition.row + 1;
|
|
6244
6247
|
if (isVerb) {
|
|
6245
|
-
out.push({ method: method.toUpperCase(), pathTemplate, line, framework
|
|
6248
|
+
out.push({ method: method.toUpperCase(), pathTemplate, line, framework });
|
|
6246
6249
|
return;
|
|
6247
6250
|
}
|
|
6248
6251
|
const methods = keywordArrayStrings(args, "methods");
|
|
6249
|
-
const list = methods.length > 0 ? methods : ["ALL"];
|
|
6252
|
+
const list = methods.length > 0 ? methods : isFlaskRoute ? ["GET"] : ["ALL"];
|
|
6250
6253
|
for (const m of list) {
|
|
6254
|
+
out.push({ method: m === "ALL" ? "ALL" : m.toUpperCase(), pathTemplate, line, framework });
|
|
6255
|
+
}
|
|
6256
|
+
});
|
|
6257
|
+
return out;
|
|
6258
|
+
}
|
|
6259
|
+
function djangoRoutesFromSource(source, parser) {
|
|
6260
|
+
const tree = parseSource2(parser, source);
|
|
6261
|
+
const out = [];
|
|
6262
|
+
walk(tree.rootNode, (node) => {
|
|
6263
|
+
if (node.type !== "assignment") return;
|
|
6264
|
+
if (node.childForFieldName("left")?.text !== "urlpatterns") return;
|
|
6265
|
+
const list = node.childForFieldName("right");
|
|
6266
|
+
if (!list || list.type !== "list") return;
|
|
6267
|
+
for (let i = 0; i < list.namedChildCount; i++) {
|
|
6268
|
+
const el = list.namedChild(i);
|
|
6269
|
+
if (el?.type !== "call") continue;
|
|
6270
|
+
if (el.childForFieldName("function")?.text !== "path") continue;
|
|
6271
|
+
const args = el.childForFieldName("arguments");
|
|
6272
|
+
const first = args?.namedChild(0);
|
|
6273
|
+
if (first?.type !== "string") continue;
|
|
6274
|
+
const raw = pyStaticStringText(first);
|
|
6275
|
+
if (raw === null) continue;
|
|
6276
|
+
const second = args?.namedChild(1);
|
|
6277
|
+
if (second?.type === "call" && second.childForFieldName("function")?.text === "include") continue;
|
|
6251
6278
|
out.push({
|
|
6252
|
-
method:
|
|
6253
|
-
pathTemplate,
|
|
6254
|
-
line,
|
|
6255
|
-
framework: "
|
|
6279
|
+
method: "ALL",
|
|
6280
|
+
pathTemplate: canonicalizeTemplate(raw),
|
|
6281
|
+
line: el.startPosition.row + 1,
|
|
6282
|
+
framework: "django"
|
|
6256
6283
|
});
|
|
6257
6284
|
}
|
|
6258
6285
|
});
|
|
@@ -6273,7 +6300,10 @@ async function addRoutes(graph, services) {
|
|
|
6273
6300
|
const hasHono = deps["hono"] !== void 0;
|
|
6274
6301
|
const hasNext = deps["next"] !== void 0;
|
|
6275
6302
|
const hasFastapi = deps["fastapi"] !== void 0;
|
|
6276
|
-
|
|
6303
|
+
const hasFlask = deps["flask"] !== void 0;
|
|
6304
|
+
const hasDjango = deps["django"] !== void 0;
|
|
6305
|
+
if (!hasExpress && !hasFastify && !hasHono && !hasNext && !hasFastapi && !hasFlask && !hasDjango)
|
|
6306
|
+
continue;
|
|
6277
6307
|
const files = await loadSourceFiles(service.dir);
|
|
6278
6308
|
for (const file of files) {
|
|
6279
6309
|
if (isTestPath(file.path)) continue;
|
|
@@ -6284,7 +6314,8 @@ async function addRoutes(graph, services) {
|
|
|
6284
6314
|
let routes;
|
|
6285
6315
|
try {
|
|
6286
6316
|
if (isPy) {
|
|
6287
|
-
routes = hasFastapi ?
|
|
6317
|
+
routes = hasFastapi || hasFlask ? pythonRoutesFromSource(file.content, pyParser, hasFastapi ? "fastapi" : "flask") : [];
|
|
6318
|
+
if (hasDjango) routes = routes.concat(djangoRoutesFromSource(file.content, pyParser));
|
|
6288
6319
|
} else if (hasNext && (isNextAppRouteFile(relFile) || isNextPagesApiFile(relFile))) {
|
|
6289
6320
|
routes = nextRoutesFromFile(file.content, relFile, jsParser);
|
|
6290
6321
|
} else if (hasExpress || hasFastify || hasHono) {
|