@neat.is/core 0.6.0 → 0.6.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/dist/{chunk-5PVQJLPR.js → chunk-3YUNROLT.js} +2 -2
- package/dist/{chunk-CS4GHQO3.js → chunk-7C6ZULNU.js} +114 -8
- package/dist/chunk-7C6ZULNU.js.map +1 -0
- package/dist/cli.cjs +113 -7
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.cjs +113 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +113 -7
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +113 -7
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-CS4GHQO3.js.map +0 -1
- /package/dist/{chunk-5PVQJLPR.js.map → chunk-3YUNROLT.js.map} +0 -0
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
touchLastSeen,
|
|
32
32
|
upsertObservedEdge,
|
|
33
33
|
writeAtomically
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-7C6ZULNU.js";
|
|
35
35
|
import {
|
|
36
36
|
assertBindAuthority,
|
|
37
37
|
buildOtelReceiver,
|
|
@@ -2765,4 +2765,4 @@ export {
|
|
|
2765
2765
|
resolveHost,
|
|
2766
2766
|
startDaemon
|
|
2767
2767
|
};
|
|
2768
|
-
//# sourceMappingURL=chunk-
|
|
2768
|
+
//# sourceMappingURL=chunk-3YUNROLT.js.map
|
|
@@ -4653,6 +4653,7 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
4653
4653
|
import path22 from "path";
|
|
4654
4654
|
import Parser2 from "tree-sitter";
|
|
4655
4655
|
import JavaScript2 from "tree-sitter-javascript";
|
|
4656
|
+
import Python2 from "tree-sitter-python";
|
|
4656
4657
|
import {
|
|
4657
4658
|
EdgeType as EdgeType8,
|
|
4658
4659
|
NodeType as NodeType9,
|
|
@@ -4672,6 +4673,11 @@ function makeJsParser2() {
|
|
|
4672
4673
|
p.setLanguage(JavaScript2);
|
|
4673
4674
|
return p;
|
|
4674
4675
|
}
|
|
4676
|
+
function makePyParser2() {
|
|
4677
|
+
const p = new Parser2();
|
|
4678
|
+
p.setLanguage(Python2);
|
|
4679
|
+
return p;
|
|
4680
|
+
}
|
|
4675
4681
|
var ROUTER_METHODS = /* @__PURE__ */ new Set([
|
|
4676
4682
|
"get",
|
|
4677
4683
|
"post",
|
|
@@ -4684,6 +4690,7 @@ var ROUTER_METHODS = /* @__PURE__ */ new Set([
|
|
|
4684
4690
|
]);
|
|
4685
4691
|
var NEXT_APP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
4686
4692
|
var JS_ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"]);
|
|
4693
|
+
var FASTAPI_METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete", "options", "head", "trace"]);
|
|
4687
4694
|
function canonicalizeTemplate(raw) {
|
|
4688
4695
|
let p = raw.split("?")[0].split("#")[0];
|
|
4689
4696
|
if (!p.startsWith("/")) p = "/" + p;
|
|
@@ -4911,8 +4918,102 @@ function nextRoutesFromFile(source, relFile, parser) {
|
|
|
4911
4918
|
}
|
|
4912
4919
|
return [];
|
|
4913
4920
|
}
|
|
4921
|
+
function pyStaticStringText(node) {
|
|
4922
|
+
if (node.type !== "string") return null;
|
|
4923
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
4924
|
+
const child = node.namedChild(i);
|
|
4925
|
+
if (child?.type === "interpolation") return null;
|
|
4926
|
+
if (child?.type === "string_content") return child.text;
|
|
4927
|
+
}
|
|
4928
|
+
return "";
|
|
4929
|
+
}
|
|
4930
|
+
function keywordArrayStrings(argsNode, key) {
|
|
4931
|
+
for (let i = 0; i < argsNode.namedChildCount; i++) {
|
|
4932
|
+
const arg = argsNode.namedChild(i);
|
|
4933
|
+
if (arg?.type !== "keyword_argument") continue;
|
|
4934
|
+
if (arg.childForFieldName("name")?.text !== key) continue;
|
|
4935
|
+
const val = arg.childForFieldName("value");
|
|
4936
|
+
if (!val || val.type !== "list") return [];
|
|
4937
|
+
const out = [];
|
|
4938
|
+
for (let j = 0; j < val.namedChildCount; j++) {
|
|
4939
|
+
const el = val.namedChild(j);
|
|
4940
|
+
if (el?.type === "string") {
|
|
4941
|
+
const s = pyStaticStringText(el);
|
|
4942
|
+
if (s) out.push(s);
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
return out;
|
|
4946
|
+
}
|
|
4947
|
+
return [];
|
|
4948
|
+
}
|
|
4949
|
+
function collectApiRouterPrefixes(root) {
|
|
4950
|
+
const prefixes = /* @__PURE__ */ new Map();
|
|
4951
|
+
walk(root, (node) => {
|
|
4952
|
+
if (node.type !== "assignment") return;
|
|
4953
|
+
const right = node.childForFieldName("right");
|
|
4954
|
+
if (!right || right.type !== "call") return;
|
|
4955
|
+
const fn = right.childForFieldName("function");
|
|
4956
|
+
if (!fn) return;
|
|
4957
|
+
const ctor = fn.type === "attribute" ? fn.childForFieldName("attribute")?.text : fn.text;
|
|
4958
|
+
if (ctor !== "APIRouter") return;
|
|
4959
|
+
const left = node.childForFieldName("left");
|
|
4960
|
+
if (!left || left.type !== "identifier") return;
|
|
4961
|
+
const args = right.childForFieldName("arguments");
|
|
4962
|
+
if (!args) return;
|
|
4963
|
+
for (let i = 0; i < args.namedChildCount; i++) {
|
|
4964
|
+
const arg = args.namedChild(i);
|
|
4965
|
+
if (arg?.type !== "keyword_argument") continue;
|
|
4966
|
+
if (arg.childForFieldName("name")?.text !== "prefix") continue;
|
|
4967
|
+
const val = arg.childForFieldName("value");
|
|
4968
|
+
const p = val ? pyStaticStringText(val) : null;
|
|
4969
|
+
if (p !== null) prefixes.set(left.text, p);
|
|
4970
|
+
}
|
|
4971
|
+
});
|
|
4972
|
+
return prefixes;
|
|
4973
|
+
}
|
|
4974
|
+
function fastapiRoutesFromSource(source, parser) {
|
|
4975
|
+
const tree = parseSource2(parser, source);
|
|
4976
|
+
const prefixes = collectApiRouterPrefixes(tree.rootNode);
|
|
4977
|
+
const out = [];
|
|
4978
|
+
walk(tree.rootNode, (node) => {
|
|
4979
|
+
if (node.type !== "decorator") return;
|
|
4980
|
+
const call = node.namedChild(0);
|
|
4981
|
+
if (!call || call.type !== "call") return;
|
|
4982
|
+
const fn = call.childForFieldName("function");
|
|
4983
|
+
if (!fn || fn.type !== "attribute") return;
|
|
4984
|
+
const method = fn.childForFieldName("attribute")?.text?.toLowerCase();
|
|
4985
|
+
if (!method) return;
|
|
4986
|
+
const isVerb = FASTAPI_METHODS.has(method);
|
|
4987
|
+
if (!isVerb && method !== "api_route") return;
|
|
4988
|
+
const args = call.childForFieldName("arguments");
|
|
4989
|
+
const first = args?.namedChild(0);
|
|
4990
|
+
if (!first || first.type !== "string") return;
|
|
4991
|
+
const rawPath = pyStaticStringText(first);
|
|
4992
|
+
if (rawPath === null || !rawPath.startsWith("/")) return;
|
|
4993
|
+
const obj = fn.childForFieldName("object")?.text;
|
|
4994
|
+
const prefix = obj ? prefixes.get(obj) ?? "" : "";
|
|
4995
|
+
const pathTemplate = canonicalizeTemplate(prefix + rawPath);
|
|
4996
|
+
const line = node.startPosition.row + 1;
|
|
4997
|
+
if (isVerb) {
|
|
4998
|
+
out.push({ method: method.toUpperCase(), pathTemplate, line, framework: "fastapi" });
|
|
4999
|
+
return;
|
|
5000
|
+
}
|
|
5001
|
+
const methods = keywordArrayStrings(args, "methods");
|
|
5002
|
+
const list = methods.length > 0 ? methods : ["ALL"];
|
|
5003
|
+
for (const m of list) {
|
|
5004
|
+
out.push({
|
|
5005
|
+
method: m === "ALL" ? "ALL" : m.toUpperCase(),
|
|
5006
|
+
pathTemplate,
|
|
5007
|
+
line,
|
|
5008
|
+
framework: "fastapi"
|
|
5009
|
+
});
|
|
5010
|
+
}
|
|
5011
|
+
});
|
|
5012
|
+
return out;
|
|
5013
|
+
}
|
|
4914
5014
|
async function addRoutes(graph, services) {
|
|
4915
5015
|
const jsParser = makeJsParser2();
|
|
5016
|
+
const pyParser = makePyParser2();
|
|
4916
5017
|
let nodesAdded = 0;
|
|
4917
5018
|
let edgesAdded = 0;
|
|
4918
5019
|
for (const service of services) {
|
|
@@ -4924,15 +5025,20 @@ async function addRoutes(graph, services) {
|
|
|
4924
5025
|
const hasFastify = deps["fastify"] !== void 0;
|
|
4925
5026
|
const hasHono = deps["hono"] !== void 0;
|
|
4926
5027
|
const hasNext = deps["next"] !== void 0;
|
|
4927
|
-
|
|
5028
|
+
const hasFastapi = deps["fastapi"] !== void 0;
|
|
5029
|
+
if (!hasExpress && !hasFastify && !hasHono && !hasNext && !hasFastapi) continue;
|
|
4928
5030
|
const files = await loadSourceFiles(service.dir);
|
|
4929
5031
|
for (const file of files) {
|
|
4930
5032
|
if (isTestPath(file.path)) continue;
|
|
4931
|
-
|
|
5033
|
+
const ext = path22.extname(file.path);
|
|
5034
|
+
const isPy = ext === ".py";
|
|
5035
|
+
if (!JS_ROUTE_EXTENSIONS.has(ext) && !isPy) continue;
|
|
4932
5036
|
const relFile = toPosix2(path22.relative(service.dir, file.path));
|
|
4933
5037
|
let routes;
|
|
4934
5038
|
try {
|
|
4935
|
-
if (
|
|
5039
|
+
if (isPy) {
|
|
5040
|
+
routes = hasFastapi ? fastapiRoutesFromSource(file.content, pyParser) : [];
|
|
5041
|
+
} else if (hasNext && (isNextAppRouteFile(relFile) || isNextPagesApiFile(relFile))) {
|
|
4936
5042
|
routes = nextRoutesFromFile(file.content, relFile, jsParser);
|
|
4937
5043
|
} else if (hasExpress || hasFastify || hasHono) {
|
|
4938
5044
|
routes = serverRoutesFromSource(file.content, jsParser, hasExpress, hasFastify, hasHono);
|
|
@@ -5126,7 +5232,7 @@ import {
|
|
|
5126
5232
|
import path24 from "path";
|
|
5127
5233
|
import Parser3 from "tree-sitter";
|
|
5128
5234
|
import JavaScript3 from "tree-sitter-javascript";
|
|
5129
|
-
import
|
|
5235
|
+
import Python3 from "tree-sitter-python";
|
|
5130
5236
|
import {
|
|
5131
5237
|
EdgeType as EdgeType10,
|
|
5132
5238
|
Provenance as Provenance9,
|
|
@@ -5186,14 +5292,14 @@ function makeJsParser3() {
|
|
|
5186
5292
|
p.setLanguage(JavaScript3);
|
|
5187
5293
|
return p;
|
|
5188
5294
|
}
|
|
5189
|
-
function
|
|
5295
|
+
function makePyParser3() {
|
|
5190
5296
|
const p = new Parser3();
|
|
5191
|
-
p.setLanguage(
|
|
5297
|
+
p.setLanguage(Python3);
|
|
5192
5298
|
return p;
|
|
5193
5299
|
}
|
|
5194
5300
|
async function addHttpCallEdges(graph, services) {
|
|
5195
5301
|
const jsParser = makeJsParser3();
|
|
5196
|
-
const pyParser =
|
|
5302
|
+
const pyParser = makePyParser3();
|
|
5197
5303
|
const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
|
|
5198
5304
|
let nodesAdded = 0;
|
|
5199
5305
|
let edgesAdded = 0;
|
|
@@ -9743,4 +9849,4 @@ export {
|
|
|
9743
9849
|
recordConnectorPoll,
|
|
9744
9850
|
buildApi
|
|
9745
9851
|
};
|
|
9746
|
-
//# sourceMappingURL=chunk-
|
|
9852
|
+
//# sourceMappingURL=chunk-7C6ZULNU.js.map
|