@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
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
resolveNeatVersion,
|
|
13
13
|
validateConnectorEntry,
|
|
14
14
|
writeDaemonRecord
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-3YUNROLT.js";
|
|
16
16
|
import {
|
|
17
17
|
buildSearchIndex
|
|
18
18
|
} from "./chunk-BIY46Q6U.js";
|
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
startPersistLoop,
|
|
72
72
|
startStalenessLoop,
|
|
73
73
|
upsertConnectorEntry
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-7C6ZULNU.js";
|
|
75
75
|
import {
|
|
76
76
|
startOtelGrpcReceiver
|
|
77
77
|
} from "./chunk-MVINCLQM.js";
|
package/dist/index.cjs
CHANGED
|
@@ -5345,6 +5345,7 @@ init_cjs_shims();
|
|
|
5345
5345
|
var import_node_path22 = __toESM(require("path"), 1);
|
|
5346
5346
|
var import_tree_sitter2 = __toESM(require("tree-sitter"), 1);
|
|
5347
5347
|
var import_tree_sitter_javascript2 = __toESM(require("tree-sitter-javascript"), 1);
|
|
5348
|
+
var import_tree_sitter_python2 = __toESM(require("tree-sitter-python"), 1);
|
|
5348
5349
|
var import_types11 = require("@neat.is/types");
|
|
5349
5350
|
var PARSE_CHUNK2 = 16384;
|
|
5350
5351
|
function parseSource2(parser, source) {
|
|
@@ -5357,6 +5358,11 @@ function makeJsParser2() {
|
|
|
5357
5358
|
p.setLanguage(import_tree_sitter_javascript2.default);
|
|
5358
5359
|
return p;
|
|
5359
5360
|
}
|
|
5361
|
+
function makePyParser2() {
|
|
5362
|
+
const p = new import_tree_sitter2.default();
|
|
5363
|
+
p.setLanguage(import_tree_sitter_python2.default);
|
|
5364
|
+
return p;
|
|
5365
|
+
}
|
|
5360
5366
|
var ROUTER_METHODS = /* @__PURE__ */ new Set([
|
|
5361
5367
|
"get",
|
|
5362
5368
|
"post",
|
|
@@ -5369,6 +5375,7 @@ var ROUTER_METHODS = /* @__PURE__ */ new Set([
|
|
|
5369
5375
|
]);
|
|
5370
5376
|
var NEXT_APP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
5371
5377
|
var JS_ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"]);
|
|
5378
|
+
var FASTAPI_METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete", "options", "head", "trace"]);
|
|
5372
5379
|
function canonicalizeTemplate(raw) {
|
|
5373
5380
|
let p = raw.split("?")[0].split("#")[0];
|
|
5374
5381
|
if (!p.startsWith("/")) p = "/" + p;
|
|
@@ -5596,8 +5603,102 @@ function nextRoutesFromFile(source, relFile, parser) {
|
|
|
5596
5603
|
}
|
|
5597
5604
|
return [];
|
|
5598
5605
|
}
|
|
5606
|
+
function pyStaticStringText(node) {
|
|
5607
|
+
if (node.type !== "string") return null;
|
|
5608
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
5609
|
+
const child = node.namedChild(i);
|
|
5610
|
+
if (child?.type === "interpolation") return null;
|
|
5611
|
+
if (child?.type === "string_content") return child.text;
|
|
5612
|
+
}
|
|
5613
|
+
return "";
|
|
5614
|
+
}
|
|
5615
|
+
function keywordArrayStrings(argsNode, key) {
|
|
5616
|
+
for (let i = 0; i < argsNode.namedChildCount; i++) {
|
|
5617
|
+
const arg = argsNode.namedChild(i);
|
|
5618
|
+
if (arg?.type !== "keyword_argument") continue;
|
|
5619
|
+
if (arg.childForFieldName("name")?.text !== key) continue;
|
|
5620
|
+
const val = arg.childForFieldName("value");
|
|
5621
|
+
if (!val || val.type !== "list") return [];
|
|
5622
|
+
const out = [];
|
|
5623
|
+
for (let j = 0; j < val.namedChildCount; j++) {
|
|
5624
|
+
const el = val.namedChild(j);
|
|
5625
|
+
if (el?.type === "string") {
|
|
5626
|
+
const s = pyStaticStringText(el);
|
|
5627
|
+
if (s) out.push(s);
|
|
5628
|
+
}
|
|
5629
|
+
}
|
|
5630
|
+
return out;
|
|
5631
|
+
}
|
|
5632
|
+
return [];
|
|
5633
|
+
}
|
|
5634
|
+
function collectApiRouterPrefixes(root) {
|
|
5635
|
+
const prefixes = /* @__PURE__ */ new Map();
|
|
5636
|
+
walk(root, (node) => {
|
|
5637
|
+
if (node.type !== "assignment") return;
|
|
5638
|
+
const right = node.childForFieldName("right");
|
|
5639
|
+
if (!right || right.type !== "call") return;
|
|
5640
|
+
const fn = right.childForFieldName("function");
|
|
5641
|
+
if (!fn) return;
|
|
5642
|
+
const ctor = fn.type === "attribute" ? fn.childForFieldName("attribute")?.text : fn.text;
|
|
5643
|
+
if (ctor !== "APIRouter") return;
|
|
5644
|
+
const left = node.childForFieldName("left");
|
|
5645
|
+
if (!left || left.type !== "identifier") return;
|
|
5646
|
+
const args = right.childForFieldName("arguments");
|
|
5647
|
+
if (!args) return;
|
|
5648
|
+
for (let i = 0; i < args.namedChildCount; i++) {
|
|
5649
|
+
const arg = args.namedChild(i);
|
|
5650
|
+
if (arg?.type !== "keyword_argument") continue;
|
|
5651
|
+
if (arg.childForFieldName("name")?.text !== "prefix") continue;
|
|
5652
|
+
const val = arg.childForFieldName("value");
|
|
5653
|
+
const p = val ? pyStaticStringText(val) : null;
|
|
5654
|
+
if (p !== null) prefixes.set(left.text, p);
|
|
5655
|
+
}
|
|
5656
|
+
});
|
|
5657
|
+
return prefixes;
|
|
5658
|
+
}
|
|
5659
|
+
function fastapiRoutesFromSource(source, parser) {
|
|
5660
|
+
const tree = parseSource2(parser, source);
|
|
5661
|
+
const prefixes = collectApiRouterPrefixes(tree.rootNode);
|
|
5662
|
+
const out = [];
|
|
5663
|
+
walk(tree.rootNode, (node) => {
|
|
5664
|
+
if (node.type !== "decorator") return;
|
|
5665
|
+
const call = node.namedChild(0);
|
|
5666
|
+
if (!call || call.type !== "call") return;
|
|
5667
|
+
const fn = call.childForFieldName("function");
|
|
5668
|
+
if (!fn || fn.type !== "attribute") return;
|
|
5669
|
+
const method = fn.childForFieldName("attribute")?.text?.toLowerCase();
|
|
5670
|
+
if (!method) return;
|
|
5671
|
+
const isVerb = FASTAPI_METHODS.has(method);
|
|
5672
|
+
if (!isVerb && method !== "api_route") return;
|
|
5673
|
+
const args = call.childForFieldName("arguments");
|
|
5674
|
+
const first = args?.namedChild(0);
|
|
5675
|
+
if (!first || first.type !== "string") return;
|
|
5676
|
+
const rawPath = pyStaticStringText(first);
|
|
5677
|
+
if (rawPath === null || !rawPath.startsWith("/")) return;
|
|
5678
|
+
const obj = fn.childForFieldName("object")?.text;
|
|
5679
|
+
const prefix = obj ? prefixes.get(obj) ?? "" : "";
|
|
5680
|
+
const pathTemplate = canonicalizeTemplate(prefix + rawPath);
|
|
5681
|
+
const line = node.startPosition.row + 1;
|
|
5682
|
+
if (isVerb) {
|
|
5683
|
+
out.push({ method: method.toUpperCase(), pathTemplate, line, framework: "fastapi" });
|
|
5684
|
+
return;
|
|
5685
|
+
}
|
|
5686
|
+
const methods = keywordArrayStrings(args, "methods");
|
|
5687
|
+
const list = methods.length > 0 ? methods : ["ALL"];
|
|
5688
|
+
for (const m of list) {
|
|
5689
|
+
out.push({
|
|
5690
|
+
method: m === "ALL" ? "ALL" : m.toUpperCase(),
|
|
5691
|
+
pathTemplate,
|
|
5692
|
+
line,
|
|
5693
|
+
framework: "fastapi"
|
|
5694
|
+
});
|
|
5695
|
+
}
|
|
5696
|
+
});
|
|
5697
|
+
return out;
|
|
5698
|
+
}
|
|
5599
5699
|
async function addRoutes(graph, services) {
|
|
5600
5700
|
const jsParser = makeJsParser2();
|
|
5701
|
+
const pyParser = makePyParser2();
|
|
5601
5702
|
let nodesAdded = 0;
|
|
5602
5703
|
let edgesAdded = 0;
|
|
5603
5704
|
for (const service of services) {
|
|
@@ -5609,15 +5710,20 @@ async function addRoutes(graph, services) {
|
|
|
5609
5710
|
const hasFastify = deps["fastify"] !== void 0;
|
|
5610
5711
|
const hasHono = deps["hono"] !== void 0;
|
|
5611
5712
|
const hasNext = deps["next"] !== void 0;
|
|
5612
|
-
|
|
5713
|
+
const hasFastapi = deps["fastapi"] !== void 0;
|
|
5714
|
+
if (!hasExpress && !hasFastify && !hasHono && !hasNext && !hasFastapi) continue;
|
|
5613
5715
|
const files = await loadSourceFiles(service.dir);
|
|
5614
5716
|
for (const file of files) {
|
|
5615
5717
|
if (isTestPath(file.path)) continue;
|
|
5616
|
-
|
|
5718
|
+
const ext = import_node_path22.default.extname(file.path);
|
|
5719
|
+
const isPy = ext === ".py";
|
|
5720
|
+
if (!JS_ROUTE_EXTENSIONS.has(ext) && !isPy) continue;
|
|
5617
5721
|
const relFile = toPosix2(import_node_path22.default.relative(service.dir, file.path));
|
|
5618
5722
|
let routes;
|
|
5619
5723
|
try {
|
|
5620
|
-
if (
|
|
5724
|
+
if (isPy) {
|
|
5725
|
+
routes = hasFastapi ? fastapiRoutesFromSource(file.content, pyParser) : [];
|
|
5726
|
+
} else if (hasNext && (isNextAppRouteFile(relFile) || isNextPagesApiFile(relFile))) {
|
|
5621
5727
|
routes = nextRoutesFromFile(file.content, relFile, jsParser);
|
|
5622
5728
|
} else if (hasExpress || hasFastify || hasHono) {
|
|
5623
5729
|
routes = serverRoutesFromSource(file.content, jsParser, hasExpress, hasFastify, hasHono);
|
|
@@ -5801,7 +5907,7 @@ init_cjs_shims();
|
|
|
5801
5907
|
var import_node_path24 = __toESM(require("path"), 1);
|
|
5802
5908
|
var import_tree_sitter3 = __toESM(require("tree-sitter"), 1);
|
|
5803
5909
|
var import_tree_sitter_javascript3 = __toESM(require("tree-sitter-javascript"), 1);
|
|
5804
|
-
var
|
|
5910
|
+
var import_tree_sitter_python3 = __toESM(require("tree-sitter-python"), 1);
|
|
5805
5911
|
var import_types13 = require("@neat.is/types");
|
|
5806
5912
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
5807
5913
|
var JSX_EXTERNAL_LINK_TAGS = /* @__PURE__ */ new Set(["a", "Link", "NavLink", "ExternalLink", "Anchor"]);
|
|
@@ -5856,14 +5962,14 @@ function makeJsParser3() {
|
|
|
5856
5962
|
p.setLanguage(import_tree_sitter_javascript3.default);
|
|
5857
5963
|
return p;
|
|
5858
5964
|
}
|
|
5859
|
-
function
|
|
5965
|
+
function makePyParser3() {
|
|
5860
5966
|
const p = new import_tree_sitter3.default();
|
|
5861
|
-
p.setLanguage(
|
|
5967
|
+
p.setLanguage(import_tree_sitter_python3.default);
|
|
5862
5968
|
return p;
|
|
5863
5969
|
}
|
|
5864
5970
|
async function addHttpCallEdges(graph, services) {
|
|
5865
5971
|
const jsParser = makeJsParser3();
|
|
5866
|
-
const pyParser =
|
|
5972
|
+
const pyParser = makePyParser3();
|
|
5867
5973
|
const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
|
|
5868
5974
|
let nodesAdded = 0;
|
|
5869
5975
|
let edgesAdded = 0;
|