@neat.is/core 0.7.7 → 0.7.9
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-BIY46Q6U.js → chunk-BC53SCT7.js} +36 -2
- package/dist/chunk-BC53SCT7.js.map +1 -0
- package/dist/{chunk-4GCV46AP.js → chunk-FCO5Z3RW.js} +2 -2
- package/dist/{chunk-YVZRBT4C.js → chunk-ILG3SMD5.js} +54 -4
- package/dist/{chunk-YVZRBT4C.js.map → chunk-ILG3SMD5.js.map} +1 -1
- package/dist/{chunk-UI3AFJAF.js → chunk-N5TPODCX.js} +171 -49
- package/dist/chunk-N5TPODCX.js.map +1 -0
- package/dist/{chunk-Y43UCVZS.js → chunk-UUYCTH2E.js} +24 -8
- package/dist/chunk-UUYCTH2E.js.map +1 -0
- package/dist/cli.cjs +238 -63
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +17 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +242 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -4
- package/dist/neatd.cjs +242 -54
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +3 -3
- package/dist/{otel-grpc-DPSAGRUU.js → otel-grpc-CO47JRIN.js} +3 -3
- package/dist/server.cjs +226 -54
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +4 -4
- package/package.json +2 -2
- package/dist/chunk-BIY46Q6U.js.map +0 -1
- package/dist/chunk-UI3AFJAF.js.map +0 -1
- package/dist/chunk-Y43UCVZS.js.map +0 -1
- /package/dist/{chunk-4GCV46AP.js.map → chunk-FCO5Z3RW.js.map} +0 -0
- /package/dist/{otel-grpc-DPSAGRUU.js.map → otel-grpc-CO47JRIN.js.map} +0 -0
package/dist/neatd.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
reconcileDaemonRecordSync,
|
|
4
4
|
startDaemon
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ILG3SMD5.js";
|
|
6
6
|
import {
|
|
7
7
|
listProjects,
|
|
8
8
|
registryPath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-N5TPODCX.js";
|
|
10
10
|
import {
|
|
11
11
|
BindAuthorityError,
|
|
12
12
|
__require
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-UUYCTH2E.js";
|
|
14
14
|
|
|
15
15
|
// src/neatd.ts
|
|
16
16
|
import { promises as fs } from "fs";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
reshapeGrpcRequest,
|
|
3
3
|
startOtelGrpcReceiver
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-FCO5Z3RW.js";
|
|
5
|
+
import "./chunk-UUYCTH2E.js";
|
|
6
6
|
export {
|
|
7
7
|
reshapeGrpcRequest,
|
|
8
8
|
startOtelGrpcReceiver
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=otel-grpc-
|
|
10
|
+
//# sourceMappingURL=otel-grpc-CO47JRIN.js.map
|
package/dist/server.cjs
CHANGED
|
@@ -502,13 +502,18 @@ function loadProtobufResponseEncoder() {
|
|
|
502
502
|
);
|
|
503
503
|
return exportTraceServiceResponseType;
|
|
504
504
|
}
|
|
505
|
-
function encodeProtobufResponseBody() {
|
|
506
|
-
if (cachedProtobufResponseBody) return cachedProtobufResponseBody;
|
|
505
|
+
function encodeProtobufResponseBody(rejected, message) {
|
|
507
506
|
const Type = loadProtobufResponseEncoder();
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
507
|
+
if (!rejected) {
|
|
508
|
+
if (cachedProtobufResponseBody) return cachedProtobufResponseBody;
|
|
509
|
+
const msg2 = Type.create({});
|
|
510
|
+
cachedProtobufResponseBody = Buffer.from(Type.encode(msg2).finish());
|
|
511
|
+
return cachedProtobufResponseBody;
|
|
512
|
+
}
|
|
513
|
+
const msg = Type.fromObject({
|
|
514
|
+
partial_success: { rejected_spans: rejected, error_message: message ?? "" }
|
|
515
|
+
});
|
|
516
|
+
return Buffer.from(Type.encode(msg).finish());
|
|
512
517
|
}
|
|
513
518
|
async function decodeProtobufBody(buf) {
|
|
514
519
|
const Type = loadProtobufDecoder();
|
|
@@ -623,6 +628,13 @@ async function buildOtelReceiver(opts) {
|
|
|
623
628
|
}
|
|
624
629
|
return reply.code(200).header("content-type", "application/json").send({ partialSuccess: {} });
|
|
625
630
|
}
|
|
631
|
+
function sendOtlpPartial(reply, flavor, rejected, message) {
|
|
632
|
+
if (flavor === "protobuf") {
|
|
633
|
+
const buf = encodeProtobufResponseBody(rejected, message);
|
|
634
|
+
return reply.code(200).header("content-type", "application/x-protobuf").send(buf);
|
|
635
|
+
}
|
|
636
|
+
return reply.code(200).header("content-type", "application/json").send({ partialSuccess: { rejectedSpans: rejected, errorMessage: message } });
|
|
637
|
+
}
|
|
626
638
|
app.addContentTypeParser(
|
|
627
639
|
"application/x-protobuf",
|
|
628
640
|
{ parseAs: "buffer", bodyLimit: opts.bodyLimit ?? 16 * 1024 * 1024 },
|
|
@@ -650,6 +662,10 @@ async function buildOtelReceiver(opts) {
|
|
|
650
662
|
}
|
|
651
663
|
}
|
|
652
664
|
enqueue(spans);
|
|
665
|
+
if (opts.classifyBareRoutability) {
|
|
666
|
+
const { rejected, message } = opts.classifyBareRoutability(spans);
|
|
667
|
+
if (rejected > 0) return sendOtlpPartial(reply, result.flavor, rejected, message);
|
|
668
|
+
}
|
|
653
669
|
return sendOtlpSuccess(reply, result.flavor);
|
|
654
670
|
});
|
|
655
671
|
app.post("/projects/:project/v1/traces", async (req, reply) => {
|
|
@@ -2796,6 +2812,7 @@ var ROUTER_METHODS = /* @__PURE__ */ new Set([
|
|
|
2796
2812
|
"all"
|
|
2797
2813
|
]);
|
|
2798
2814
|
var NEXT_APP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
2815
|
+
var NET_HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
2799
2816
|
var JS_ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"]);
|
|
2800
2817
|
function goRouterRoutesFromSource(source, parser, framework) {
|
|
2801
2818
|
const tree = parseSource2(parser, source);
|
|
@@ -2849,6 +2866,101 @@ function echoRoutesFromSource(source, parser) {
|
|
|
2849
2866
|
function fiberRoutesFromSource(source, parser) {
|
|
2850
2867
|
return goRouterRoutesFromSource(source, parser, "fiber");
|
|
2851
2868
|
}
|
|
2869
|
+
function chiRoutesFromSource(source, parser) {
|
|
2870
|
+
const tree = parseSource2(parser, source);
|
|
2871
|
+
const out = [];
|
|
2872
|
+
chiWalk(tree.rootNode, "", out);
|
|
2873
|
+
return out;
|
|
2874
|
+
}
|
|
2875
|
+
function stripChiRegex(path68) {
|
|
2876
|
+
return path68.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
|
|
2877
|
+
}
|
|
2878
|
+
function chiWalk(node, prefix, out) {
|
|
2879
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2880
|
+
const child = node.namedChild(i);
|
|
2881
|
+
if (child) chiHandle(child, prefix, out);
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
function chiHandle(node, prefix, out) {
|
|
2885
|
+
if (node.type === "call_expression") {
|
|
2886
|
+
const fn = node.childForFieldName("function");
|
|
2887
|
+
if (fn?.type === "selector_expression") {
|
|
2888
|
+
const field = fn.childForFieldName("field")?.text;
|
|
2889
|
+
const args = node.childForFieldName("arguments");
|
|
2890
|
+
if (field === "Route") {
|
|
2891
|
+
const leaf = goStringLiteral(args?.namedChild(0));
|
|
2892
|
+
const closure = args?.namedChild(1);
|
|
2893
|
+
if (leaf !== null && closure?.type === "func_literal") {
|
|
2894
|
+
const body = closure.childForFieldName("body");
|
|
2895
|
+
if (body) chiWalk(body, prefix + leaf, out);
|
|
2896
|
+
}
|
|
2897
|
+
return;
|
|
2898
|
+
}
|
|
2899
|
+
if (field === "Group") {
|
|
2900
|
+
const closure = args?.namedChild(0);
|
|
2901
|
+
if (closure?.type === "func_literal") {
|
|
2902
|
+
const body = closure.childForFieldName("body");
|
|
2903
|
+
if (body) chiWalk(body, prefix, out);
|
|
2904
|
+
}
|
|
2905
|
+
return;
|
|
2906
|
+
}
|
|
2907
|
+
if (field === "Mount") {
|
|
2908
|
+
return;
|
|
2909
|
+
}
|
|
2910
|
+
if (field && ROUTER_METHODS.has(field.toLowerCase())) {
|
|
2911
|
+
const leaf = goStringLiteral(args?.namedChild(0));
|
|
2912
|
+
if (leaf !== null) {
|
|
2913
|
+
out.push({
|
|
2914
|
+
method: field.toUpperCase(),
|
|
2915
|
+
pathTemplate: canonicalizeTemplate(stripChiRegex(prefix + leaf)),
|
|
2916
|
+
line: node.startPosition.row + 1,
|
|
2917
|
+
framework: "chi"
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
return;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
chiWalk(node, prefix, out);
|
|
2925
|
+
}
|
|
2926
|
+
function netHttpRoutesFromSource(source, parser) {
|
|
2927
|
+
const tree = parseSource2(parser, source);
|
|
2928
|
+
if (!goImportsNetHttp(tree.rootNode)) return [];
|
|
2929
|
+
const out = [];
|
|
2930
|
+
walk(tree.rootNode, (node) => {
|
|
2931
|
+
if (node.type !== "call_expression") return;
|
|
2932
|
+
const fn = node.childForFieldName("function");
|
|
2933
|
+
if (fn?.type !== "selector_expression") return;
|
|
2934
|
+
const field = fn.childForFieldName("field")?.text;
|
|
2935
|
+
if (field !== "HandleFunc" && field !== "Handle") return;
|
|
2936
|
+
const leaf = goStringLiteral(node.childForFieldName("arguments")?.namedChild(0));
|
|
2937
|
+
if (leaf === null) return;
|
|
2938
|
+
const sp = leaf.indexOf(" ");
|
|
2939
|
+
if (sp < 0) return;
|
|
2940
|
+
const method = leaf.slice(0, sp);
|
|
2941
|
+
const rest = leaf.slice(sp + 1);
|
|
2942
|
+
if (!NET_HTTP_METHODS.has(method)) return;
|
|
2943
|
+
if (!rest.startsWith("/")) return;
|
|
2944
|
+
out.push({
|
|
2945
|
+
method,
|
|
2946
|
+
pathTemplate: canonicalizeTemplate(rest),
|
|
2947
|
+
line: node.startPosition.row + 1,
|
|
2948
|
+
framework: "net/http"
|
|
2949
|
+
});
|
|
2950
|
+
});
|
|
2951
|
+
return out;
|
|
2952
|
+
}
|
|
2953
|
+
function goImportsNetHttp(root) {
|
|
2954
|
+
let found = false;
|
|
2955
|
+
walk(root, (node) => {
|
|
2956
|
+
if (found || node.type !== "import_spec") return;
|
|
2957
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
2958
|
+
const child = node.namedChild(i);
|
|
2959
|
+
if (goStringLiteral(child) === "net/http") found = true;
|
|
2960
|
+
}
|
|
2961
|
+
});
|
|
2962
|
+
return found;
|
|
2963
|
+
}
|
|
2852
2964
|
var FASTAPI_METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete", "options", "head", "trace"]);
|
|
2853
2965
|
var NESTJS_METHODS = /* @__PURE__ */ new Map([
|
|
2854
2966
|
["Get", "GET"],
|
|
@@ -4114,9 +4226,11 @@ async function addRoutes(graph, services) {
|
|
|
4114
4226
|
const hasGin = deps["github.com/gin-gonic/gin"] !== void 0;
|
|
4115
4227
|
const hasEcho = deps["github.com/labstack/echo/v4"] !== void 0 || deps["github.com/labstack/echo"] !== void 0;
|
|
4116
4228
|
const hasFiber = deps["github.com/gofiber/fiber/v2"] !== void 0 || deps["github.com/gofiber/fiber/v3"] !== void 0;
|
|
4229
|
+
const hasChi = deps["github.com/go-chi/chi/v5"] !== void 0 || deps["github.com/go-chi/chi"] !== void 0;
|
|
4230
|
+
const isGoService = service.node.language === "go";
|
|
4117
4231
|
const hasRails = deps["rails"] !== void 0;
|
|
4118
4232
|
const hasLaravel = deps["laravel/framework"] !== void 0;
|
|
4119
|
-
if (!hasExpress && !hasFastify && !hasHono && !hasNext && !hasNestjs && !hasFastapi && !hasFlask && !hasDjango && !hasGin && !hasEcho && !hasFiber && !hasRails && !hasLaravel)
|
|
4233
|
+
if (!hasExpress && !hasFastify && !hasHono && !hasNext && !hasNestjs && !hasFastapi && !hasFlask && !hasDjango && !hasGin && !hasEcho && !hasFiber && !hasChi && !isGoService && !hasRails && !hasLaravel)
|
|
4120
4234
|
continue;
|
|
4121
4235
|
const files = await loadSourceFiles(service.dir);
|
|
4122
4236
|
const mountPrefixes = hasExpress ? await expressMountPrefixes(files, service.dir, await loadTsPathConfig(service.dir)) : /* @__PURE__ */ new Map();
|
|
@@ -4143,7 +4257,9 @@ async function addRoutes(graph, services) {
|
|
|
4143
4257
|
if (hasGin) routes = ginRoutesFromSource(file.content, goParser);
|
|
4144
4258
|
else if (hasEcho) routes = echoRoutesFromSource(file.content, goParser);
|
|
4145
4259
|
else if (hasFiber) routes = fiberRoutesFromSource(file.content, goParser);
|
|
4260
|
+
else if (hasChi) routes = chiRoutesFromSource(file.content, goParser);
|
|
4146
4261
|
else routes = [];
|
|
4262
|
+
routes = routes.concat(netHttpRoutesFromSource(file.content, goParser));
|
|
4147
4263
|
} else if (isPy) {
|
|
4148
4264
|
routes = hasFastapi || hasFlask ? pythonRoutesFromSource(file.content, pyParser, hasFastapi ? "fastapi" : "flask") : [];
|
|
4149
4265
|
if (hasDjango) routes = routes.concat(djangoRoutesFromSource(file.content, pyParser));
|
|
@@ -4465,10 +4581,15 @@ function resolveDistToSrc(absFilepath, line) {
|
|
|
4465
4581
|
}
|
|
4466
4582
|
if (!entry) return null;
|
|
4467
4583
|
try {
|
|
4468
|
-
const
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4584
|
+
const queryLine = line !== void 0 && Number.isFinite(line) ? line : 1;
|
|
4585
|
+
let pos = entry.consumer.originalPositionFor({ line: queryLine, column: 0 });
|
|
4586
|
+
if (!pos || !pos.source) {
|
|
4587
|
+
pos = entry.consumer.originalPositionFor({
|
|
4588
|
+
line: queryLine,
|
|
4589
|
+
column: 0,
|
|
4590
|
+
bias: sourceMapJs.SourceMapConsumer.LEAST_UPPER_BOUND
|
|
4591
|
+
});
|
|
4592
|
+
}
|
|
4472
4593
|
if (!pos || !pos.source) return null;
|
|
4473
4594
|
const root = entry.consumer.sourceRoot ?? "";
|
|
4474
4595
|
const resolved = import_node_path10.default.resolve(entry.dir, root, pos.source);
|
|
@@ -4477,6 +4598,9 @@ function resolveDistToSrc(absFilepath, line) {
|
|
|
4477
4598
|
return null;
|
|
4478
4599
|
}
|
|
4479
4600
|
}
|
|
4601
|
+
function hasAdjacentSourceMap(absFilepath) {
|
|
4602
|
+
return sourceMapCache.get(absFilepath) != null;
|
|
4603
|
+
}
|
|
4480
4604
|
function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
4481
4605
|
const filepath = codeFilepathOf(span.attributes);
|
|
4482
4606
|
if (filepath === void 0) return null;
|
|
@@ -4492,7 +4616,7 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
|
4492
4616
|
}
|
|
4493
4617
|
const relPath = relPathForRuntimeFile(effectivePath, serviceNode, scanPath);
|
|
4494
4618
|
if (!relPath) return null;
|
|
4495
|
-
if (!resolved && abs.endsWith(".js") && relPath.startsWith("dist/") && serviceNode?.name) {
|
|
4619
|
+
if (!resolved && abs.endsWith(".js") && relPath.startsWith("dist/") && !hasAdjacentSourceMap(abs) && serviceNode?.name) {
|
|
4496
4620
|
warnNoSourceMaps(serviceNode.name);
|
|
4497
4621
|
}
|
|
4498
4622
|
const fn = codeFunctionOf(span.attributes);
|
|
@@ -4768,7 +4892,7 @@ function resolveServiceId(graph, host, env) {
|
|
|
4768
4892
|
function frontierIdFor(host) {
|
|
4769
4893
|
return (0, import_types7.frontierId)(host);
|
|
4770
4894
|
}
|
|
4771
|
-
function
|
|
4895
|
+
function resolveFusedServiceId(graph, serviceName, env) {
|
|
4772
4896
|
const id = (0, import_types7.serviceId)(serviceName, env);
|
|
4773
4897
|
if (graph.hasNode(id)) return id;
|
|
4774
4898
|
const wanted = serviceName.toLowerCase();
|
|
@@ -4778,17 +4902,21 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
4778
4902
|
if (svc.discoveredVia === "otel") return false;
|
|
4779
4903
|
return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
|
|
4780
4904
|
});
|
|
4781
|
-
|
|
4905
|
+
return extractedId ?? id;
|
|
4906
|
+
}
|
|
4907
|
+
function ensureServiceNode(graph, serviceName, env) {
|
|
4908
|
+
const resolved = resolveFusedServiceId(graph, serviceName, env);
|
|
4909
|
+
if (graph.hasNode(resolved)) return resolved;
|
|
4782
4910
|
const node = {
|
|
4783
|
-
id,
|
|
4911
|
+
id: resolved,
|
|
4784
4912
|
type: import_types7.NodeType.ServiceNode,
|
|
4785
4913
|
name: serviceName,
|
|
4786
4914
|
language: "unknown",
|
|
4787
4915
|
discoveredVia: "otel",
|
|
4788
4916
|
...env !== "unknown" ? { env } : {}
|
|
4789
4917
|
};
|
|
4790
|
-
graph.addNode(
|
|
4791
|
-
return
|
|
4918
|
+
graph.addNode(resolved, node);
|
|
4919
|
+
return resolved;
|
|
4792
4920
|
}
|
|
4793
4921
|
function ensureInfraNode(graph, kind, name, provider) {
|
|
4794
4922
|
const id = (0, import_types7.infraId)(kind, name);
|
|
@@ -4982,7 +5110,7 @@ async function appendErrorEvent(ctx, ev) {
|
|
|
4982
5110
|
await import_node_fs9.promises.appendFile(ctx.errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
4983
5111
|
}
|
|
4984
5112
|
function incidentAffectedNode(span, graph, scanPath) {
|
|
4985
|
-
const sid = (0, import_types7.serviceId)(span.service, span.env);
|
|
5113
|
+
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types7.serviceId)(span.service, span.env);
|
|
4986
5114
|
const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
|
|
4987
5115
|
const callSite = callSiteFromSpan(span, serviceNode, scanPath);
|
|
4988
5116
|
if (callSite) {
|
|
@@ -6585,6 +6713,7 @@ function goFramework(deps) {
|
|
|
6585
6713
|
if (deps["github.com/gin-gonic/gin"]) return "gin";
|
|
6586
6714
|
if (deps["github.com/labstack/echo/v4"] || deps["github.com/labstack/echo"]) return "echo";
|
|
6587
6715
|
if (deps["github.com/gofiber/fiber/v2"] || deps["github.com/gofiber/fiber/v3"]) return "fiber";
|
|
6716
|
+
if (deps["github.com/go-chi/chi/v5"] || deps["github.com/go-chi/chi"]) return "chi";
|
|
6588
6717
|
return void 0;
|
|
6589
6718
|
}
|
|
6590
6719
|
async function discoverGoService(scanPath, dir) {
|
|
@@ -7262,7 +7391,7 @@ function disambiguate(defs) {
|
|
|
7262
7391
|
}
|
|
7263
7392
|
async function addSymbols(graph, services) {
|
|
7264
7393
|
const parsers = /* @__PURE__ */ new Map();
|
|
7265
|
-
const
|
|
7394
|
+
const parserForExt5 = (ext) => {
|
|
7266
7395
|
const grammar = GRAMMAR_BY_EXT[ext];
|
|
7267
7396
|
if (!grammar) return null;
|
|
7268
7397
|
let parser = parsers.get(ext);
|
|
@@ -7278,7 +7407,7 @@ async function addSymbols(graph, services) {
|
|
|
7278
7407
|
for (const service of services) {
|
|
7279
7408
|
const files = await loadSourceFiles(service.dir);
|
|
7280
7409
|
for (const file of files) {
|
|
7281
|
-
const parser =
|
|
7410
|
+
const parser = parserForExt5(import_node_path19.default.extname(file.path));
|
|
7282
7411
|
if (!parser) continue;
|
|
7283
7412
|
const relPath = toPosix(import_node_path19.default.relative(service.dir, file.path));
|
|
7284
7413
|
let defs;
|
|
@@ -7430,7 +7559,7 @@ function stringInner(node) {
|
|
|
7430
7559
|
}
|
|
7431
7560
|
async function addSymbolEdges(graph, services) {
|
|
7432
7561
|
const parsers = /* @__PURE__ */ new Map();
|
|
7433
|
-
const
|
|
7562
|
+
const parserForExt5 = (ext) => {
|
|
7434
7563
|
const grammar = GRAMMAR_BY_EXT[ext];
|
|
7435
7564
|
if (!grammar) return null;
|
|
7436
7565
|
let parser = parsers.get(ext);
|
|
@@ -7447,7 +7576,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
7447
7576
|
const tsPaths = await loadTsPathConfig(service.dir);
|
|
7448
7577
|
const files = await loadSourceFiles(service.dir);
|
|
7449
7578
|
for (const file of files) {
|
|
7450
|
-
const parser =
|
|
7579
|
+
const parser = parserForExt5(import_node_path20.default.extname(file.path));
|
|
7451
7580
|
if (!parser) continue;
|
|
7452
7581
|
const relPath = toPosix(import_node_path20.default.relative(service.dir, file.path));
|
|
7453
7582
|
const fileDir = import_node_path20.default.dirname(file.path);
|
|
@@ -7709,7 +7838,7 @@ function firstReferenceLines(root, wanted) {
|
|
|
7709
7838
|
}
|
|
7710
7839
|
async function addServerActions(graph, services) {
|
|
7711
7840
|
const parsers = /* @__PURE__ */ new Map();
|
|
7712
|
-
const
|
|
7841
|
+
const parserForExt5 = (ext) => {
|
|
7713
7842
|
const grammar = GRAMMAR_BY_EXT[ext];
|
|
7714
7843
|
if (!grammar) return null;
|
|
7715
7844
|
let parser = parsers.get(ext);
|
|
@@ -7732,7 +7861,7 @@ async function addServerActions(graph, services) {
|
|
|
7732
7861
|
const files = await loadSourceFiles(service.dir);
|
|
7733
7862
|
for (const file of files) {
|
|
7734
7863
|
if (isTestPath(file.path)) continue;
|
|
7735
|
-
const parser =
|
|
7864
|
+
const parser = parserForExt5(import_node_path21.default.extname(file.path));
|
|
7736
7865
|
if (!parser) continue;
|
|
7737
7866
|
const relPath = toPosix(import_node_path21.default.relative(service.dir, file.path));
|
|
7738
7867
|
let root;
|
|
@@ -7795,7 +7924,7 @@ async function addServerActions(graph, services) {
|
|
|
7795
7924
|
}
|
|
7796
7925
|
for (const file of files) {
|
|
7797
7926
|
if (isTestPath(file.path)) continue;
|
|
7798
|
-
const parser =
|
|
7927
|
+
const parser = parserForExt5(import_node_path21.default.extname(file.path));
|
|
7799
7928
|
if (!parser) continue;
|
|
7800
7929
|
const relPath = toPosix(import_node_path21.default.relative(service.dir, file.path));
|
|
7801
7930
|
const fileDir = import_node_path21.default.dirname(file.path);
|
|
@@ -8759,6 +8888,7 @@ init_cjs_shims();
|
|
|
8759
8888
|
var import_node_path32 = __toESM(require("path"), 1);
|
|
8760
8889
|
var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
8761
8890
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
8891
|
+
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
8762
8892
|
var import_tree_sitter_python3 = __toESM(require("tree-sitter-python"), 1);
|
|
8763
8893
|
var import_types21 = require("@neat.is/types");
|
|
8764
8894
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
@@ -8809,19 +8939,27 @@ function callsFromSource(source, parser, knownHosts) {
|
|
|
8809
8939
|
}
|
|
8810
8940
|
return out;
|
|
8811
8941
|
}
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
8942
|
+
var GRAMMAR_BY_EXT2 = {
|
|
8943
|
+
".ts": import_tree_sitter_typescript2.default.typescript,
|
|
8944
|
+
".tsx": import_tree_sitter_typescript2.default.tsx,
|
|
8945
|
+
".js": import_tree_sitter_javascript4.default,
|
|
8946
|
+
".jsx": import_tree_sitter_javascript4.default,
|
|
8947
|
+
".mjs": import_tree_sitter_javascript4.default,
|
|
8948
|
+
".cjs": import_tree_sitter_javascript4.default,
|
|
8949
|
+
".py": import_tree_sitter_python3.default
|
|
8950
|
+
};
|
|
8951
|
+
function parserForExt(ext, cache) {
|
|
8952
|
+
const grammar = GRAMMAR_BY_EXT2[ext] ?? import_tree_sitter_javascript4.default;
|
|
8953
|
+
let parser = cache.get(grammar);
|
|
8954
|
+
if (!parser) {
|
|
8955
|
+
parser = new import_tree_sitter6.default();
|
|
8956
|
+
parser.setLanguage(grammar);
|
|
8957
|
+
cache.set(grammar, parser);
|
|
8958
|
+
}
|
|
8959
|
+
return parser;
|
|
8821
8960
|
}
|
|
8822
8961
|
async function addHttpCallEdges(graph, services) {
|
|
8823
|
-
const
|
|
8824
|
-
const pyParser = makePyParser3();
|
|
8962
|
+
const parserCache = /* @__PURE__ */ new Map();
|
|
8825
8963
|
const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
|
|
8826
8964
|
let nodesAdded = 0;
|
|
8827
8965
|
let edgesAdded = 0;
|
|
@@ -8830,7 +8968,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
8830
8968
|
const seen = /* @__PURE__ */ new Set();
|
|
8831
8969
|
for (const file of files) {
|
|
8832
8970
|
if (isTestPath(file.path)) continue;
|
|
8833
|
-
const parser = import_node_path32.default.extname(file.path)
|
|
8971
|
+
const parser = parserForExt(import_node_path32.default.extname(file.path), parserCache);
|
|
8834
8972
|
let sites;
|
|
8835
8973
|
try {
|
|
8836
8974
|
sites = callsFromSource(file.content, parser, knownHosts);
|
|
@@ -8903,7 +9041,7 @@ function parseSource5(parser, source) {
|
|
|
8903
9041
|
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK5)
|
|
8904
9042
|
);
|
|
8905
9043
|
}
|
|
8906
|
-
function
|
|
9044
|
+
function makeJsParser3() {
|
|
8907
9045
|
const p = new import_tree_sitter7.default();
|
|
8908
9046
|
p.setLanguage(import_tree_sitter_javascript5.default);
|
|
8909
9047
|
return p;
|
|
@@ -9081,7 +9219,7 @@ function findRoute(entries, method, normalizedPath) {
|
|
|
9081
9219
|
);
|
|
9082
9220
|
}
|
|
9083
9221
|
async function addRouteCallEdges(graph, services) {
|
|
9084
|
-
const jsParser =
|
|
9222
|
+
const jsParser = makeJsParser3();
|
|
9085
9223
|
const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
|
|
9086
9224
|
const routeIndex = buildRouteIndex(graph);
|
|
9087
9225
|
if (routeIndex.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
@@ -9473,7 +9611,7 @@ var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"),
|
|
|
9473
9611
|
var import_types28 = require("@neat.is/types");
|
|
9474
9612
|
var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
|
|
9475
9613
|
var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
|
|
9476
|
-
function
|
|
9614
|
+
function parserForExt2(ext) {
|
|
9477
9615
|
const p = new import_tree_sitter8.default();
|
|
9478
9616
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript6.default);
|
|
9479
9617
|
return p;
|
|
@@ -9638,7 +9776,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
9638
9776
|
const hasAdmin = FIRESTORE_ADMIN_IMPORT_RE.test(file.content);
|
|
9639
9777
|
if (!hasClient && !hasAdmin) return [];
|
|
9640
9778
|
const fileSdk = hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
|
|
9641
|
-
const tree = parseSource3(
|
|
9779
|
+
const tree = parseSource3(parserForExt2(import_node_path39.default.extname(file.path)), file.content);
|
|
9642
9780
|
const clientVars = firestoreClientVars(tree.rootNode);
|
|
9643
9781
|
const collLine = /* @__PURE__ */ new Map();
|
|
9644
9782
|
const writes = /* @__PURE__ */ new Map();
|
|
@@ -10055,7 +10193,7 @@ var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
|
|
|
10055
10193
|
var import_types30 = require("@neat.is/types");
|
|
10056
10194
|
var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
|
|
10057
10195
|
var PARSE_CHUNK6 = 16384;
|
|
10058
|
-
function
|
|
10196
|
+
function makePyParser3() {
|
|
10059
10197
|
const p = new import_tree_sitter9.default();
|
|
10060
10198
|
p.setLanguage(import_tree_sitter_python4.default);
|
|
10061
10199
|
return p;
|
|
@@ -10162,7 +10300,7 @@ function foreignKeyParentTable(call) {
|
|
|
10162
10300
|
}
|
|
10163
10301
|
function sqlalchemyForeignKeys(file, serviceDir) {
|
|
10164
10302
|
if (!SQLALCHEMY_IMPORT_RE.test(file.content)) return [];
|
|
10165
|
-
const tree = parseSource6(
|
|
10303
|
+
const tree = parseSource6(makePyParser3(), file.content);
|
|
10166
10304
|
const out = [];
|
|
10167
10305
|
const seen = /* @__PURE__ */ new Set();
|
|
10168
10306
|
walk3(tree.rootNode, (node) => {
|
|
@@ -10199,7 +10337,7 @@ function sqlalchemyForeignKeys(file, serviceDir) {
|
|
|
10199
10337
|
}
|
|
10200
10338
|
function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
10201
10339
|
if (!SQLALCHEMY_IMPORT_RE.test(file.content)) return [];
|
|
10202
|
-
const tree = parseSource6(
|
|
10340
|
+
const tree = parseSource6(makePyParser3(), file.content);
|
|
10203
10341
|
const out = [];
|
|
10204
10342
|
const seen = /* @__PURE__ */ new Set();
|
|
10205
10343
|
const push = (name, line, columns) => {
|
|
@@ -10251,7 +10389,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
10251
10389
|
function buildSqlalchemyModelRegistry(files) {
|
|
10252
10390
|
const table = /* @__PURE__ */ new Map();
|
|
10253
10391
|
const ambiguous = /* @__PURE__ */ new Set();
|
|
10254
|
-
const parser =
|
|
10392
|
+
const parser = makePyParser3();
|
|
10255
10393
|
for (const file of files) {
|
|
10256
10394
|
if (!SQLALCHEMY_IMPORT_RE.test(file.content)) continue;
|
|
10257
10395
|
const tree = parseSource6(parser, file.content);
|
|
@@ -10300,7 +10438,7 @@ function importsModelName(content, name) {
|
|
|
10300
10438
|
function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
10301
10439
|
const registry = buildSqlalchemyModelRegistry(files);
|
|
10302
10440
|
if (registry.size === 0) return [];
|
|
10303
|
-
const parser =
|
|
10441
|
+
const parser = makePyParser3();
|
|
10304
10442
|
const out = [];
|
|
10305
10443
|
const seen = /* @__PURE__ */ new Set();
|
|
10306
10444
|
for (const file of files) {
|
|
@@ -10338,7 +10476,7 @@ var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
|
10338
10476
|
var import_types31 = require("@neat.is/types");
|
|
10339
10477
|
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
10340
10478
|
var PARSE_CHUNK7 = 16384;
|
|
10341
|
-
function
|
|
10479
|
+
function makePyParser4() {
|
|
10342
10480
|
const p = new import_tree_sitter10.default();
|
|
10343
10481
|
p.setLanguage(import_tree_sitter_python5.default);
|
|
10344
10482
|
return p;
|
|
@@ -10399,7 +10537,7 @@ function readMeta(body) {
|
|
|
10399
10537
|
}
|
|
10400
10538
|
function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
10401
10539
|
if (!DJANGO_IMPORT_RE.test(file.content)) return [];
|
|
10402
|
-
const tree = parseSource7(
|
|
10540
|
+
const tree = parseSource7(makePyParser4(), file.content);
|
|
10403
10541
|
const out = [];
|
|
10404
10542
|
const seen = /* @__PURE__ */ new Set();
|
|
10405
10543
|
const defaultAppLabel = import_node_path42.default.basename(import_node_path42.default.dirname(file.path));
|
|
@@ -10434,7 +10572,7 @@ var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"),
|
|
|
10434
10572
|
var import_types32 = require("@neat.is/types");
|
|
10435
10573
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
10436
10574
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
10437
|
-
function
|
|
10575
|
+
function parserForExt3(ext) {
|
|
10438
10576
|
const p = new import_tree_sitter11.default();
|
|
10439
10577
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript7.default);
|
|
10440
10578
|
return p;
|
|
@@ -10506,7 +10644,7 @@ function columnsFromObject(obj) {
|
|
|
10506
10644
|
}
|
|
10507
10645
|
function drizzleEndpointsFromFile(file, serviceDir) {
|
|
10508
10646
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
10509
|
-
const tree = parseSource3(
|
|
10647
|
+
const tree = parseSource3(parserForExt3(import_node_path43.default.extname(file.path)), file.content);
|
|
10510
10648
|
const out = [];
|
|
10511
10649
|
const seen = /* @__PURE__ */ new Set();
|
|
10512
10650
|
const walk9 = (node) => {
|
|
@@ -10595,7 +10733,7 @@ function referencesTargetVar(call) {
|
|
|
10595
10733
|
}
|
|
10596
10734
|
function drizzleForeignKeys(file, serviceDir) {
|
|
10597
10735
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
10598
|
-
const tree = parseSource3(
|
|
10736
|
+
const tree = parseSource3(parserForExt3(import_node_path43.default.extname(file.path)), file.content);
|
|
10599
10737
|
const { tables, varToTable } = collectDrizzleTables(tree.rootNode);
|
|
10600
10738
|
const out = [];
|
|
10601
10739
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -13302,7 +13440,7 @@ var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"),
|
|
|
13302
13440
|
var import_types48 = require("@neat.is/types");
|
|
13303
13441
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
13304
13442
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
13305
|
-
function
|
|
13443
|
+
function parserForExt4(ext) {
|
|
13306
13444
|
const p = new import_tree_sitter16.default();
|
|
13307
13445
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript8.default);
|
|
13308
13446
|
return p;
|
|
@@ -13391,7 +13529,7 @@ function topLevelSchemas(root) {
|
|
|
13391
13529
|
}
|
|
13392
13530
|
function zodShapesFromFile(file, serviceDir) {
|
|
13393
13531
|
if (!ZOD_IMPORT_RE.test(file.content)) return [];
|
|
13394
|
-
const tree = parseSource3(
|
|
13532
|
+
const tree = parseSource3(parserForExt4(import_node_path59.default.extname(file.path)), file.content);
|
|
13395
13533
|
const out = [];
|
|
13396
13534
|
const seen = /* @__PURE__ */ new Set();
|
|
13397
13535
|
for (const { name, call } of topLevelSchemas(tree.rootNode)) {
|
|
@@ -18198,12 +18336,46 @@ var SubstringIndex = class {
|
|
|
18198
18336
|
this.graph = graph;
|
|
18199
18337
|
}
|
|
18200
18338
|
};
|
|
18339
|
+
var DEFAULT_SEARCH_INIT_TIMEOUT_MS = 3e4;
|
|
18340
|
+
function searchInitTimeoutMs() {
|
|
18341
|
+
const env = process.env.NEAT_SEARCH_INIT_TIMEOUT_MS;
|
|
18342
|
+
if (env !== void 0 && env.length > 0) {
|
|
18343
|
+
const n = Number.parseInt(env, 10);
|
|
18344
|
+
if (Number.isFinite(n) && n >= 0) return n;
|
|
18345
|
+
}
|
|
18346
|
+
return DEFAULT_SEARCH_INIT_TIMEOUT_MS;
|
|
18347
|
+
}
|
|
18348
|
+
async function resolveEmbedderBounded(factory, timeoutMs) {
|
|
18349
|
+
if (timeoutMs <= 0) return factory();
|
|
18350
|
+
let timer;
|
|
18351
|
+
const TIMED_OUT = /* @__PURE__ */ Symbol("embedder-init-timeout");
|
|
18352
|
+
const timeout = new Promise((resolve) => {
|
|
18353
|
+
timer = setTimeout(() => resolve(TIMED_OUT), timeoutMs);
|
|
18354
|
+
timer.unref?.();
|
|
18355
|
+
});
|
|
18356
|
+
try {
|
|
18357
|
+
const result = await Promise.race([factory(), timeout]);
|
|
18358
|
+
if (result === TIMED_OUT) {
|
|
18359
|
+
console.warn(
|
|
18360
|
+
`semantic_search: embedder init exceeded ${timeoutMs}ms; falling back to substring search. Set NEAT_SEARCH_INIT_TIMEOUT_MS to raise the bound (or 0 to wait indefinitely).`
|
|
18361
|
+
);
|
|
18362
|
+
return null;
|
|
18363
|
+
}
|
|
18364
|
+
return result;
|
|
18365
|
+
} finally {
|
|
18366
|
+
if (timer) clearTimeout(timer);
|
|
18367
|
+
}
|
|
18368
|
+
}
|
|
18201
18369
|
async function buildSearchIndex(graph, options = {}) {
|
|
18202
18370
|
let embedder = null;
|
|
18203
18371
|
if (options.embedder) {
|
|
18204
18372
|
embedder = options.embedder;
|
|
18205
18373
|
} else if (options.forceProvider !== "substring") {
|
|
18206
|
-
|
|
18374
|
+
const factory = options.embedderFactory ?? pickEmbedder;
|
|
18375
|
+
embedder = await resolveEmbedderBounded(
|
|
18376
|
+
factory,
|
|
18377
|
+
options.initTimeoutMs ?? searchInitTimeoutMs()
|
|
18378
|
+
);
|
|
18207
18379
|
if (options.forceProvider === "ollama" && embedder?.provider !== "ollama") {
|
|
18208
18380
|
embedder = null;
|
|
18209
18381
|
}
|