@neat.is/core 0.9.12-dev.20260831 → 0.9.12
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-3UAUMPIY.js → chunk-RBZNXA5L.js} +591 -460
- package/dist/chunk-RBZNXA5L.js.map +1 -0
- package/dist/{chunk-UNO3X6ZV.js → chunk-WE3AFQYL.js} +468 -19
- package/dist/chunk-WE3AFQYL.js.map +1 -0
- package/dist/cli.cjs +1108 -951
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.cjs +1229 -645
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +1245 -661
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +661 -534
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-3UAUMPIY.js.map +0 -1
- package/dist/chunk-UNO3X6ZV.js.map +0 -1
package/dist/server.cjs
CHANGED
|
@@ -59,8 +59,8 @@ function mountBearerAuth(app, opts) {
|
|
|
59
59
|
]);
|
|
60
60
|
const publicRead = opts.publicRead === true;
|
|
61
61
|
app.addHook("preHandler", (req, reply, done) => {
|
|
62
|
-
const
|
|
63
|
-
if (exactUnauthPaths.has(
|
|
62
|
+
const path77 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
63
|
+
if (exactUnauthPaths.has(path77) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path77)) {
|
|
64
64
|
done();
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
@@ -192,8 +192,8 @@ function reshapeGrpcRequest(req) {
|
|
|
192
192
|
};
|
|
193
193
|
}
|
|
194
194
|
function resolveProtoRoot() {
|
|
195
|
-
const here =
|
|
196
|
-
return
|
|
195
|
+
const here = import_node_path55.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
196
|
+
return import_node_path55.default.resolve(here, "..", "proto");
|
|
197
197
|
}
|
|
198
198
|
function loadTraceService() {
|
|
199
199
|
const protoRoot = resolveProtoRoot();
|
|
@@ -261,13 +261,13 @@ async function startOtelGrpcReceiver(opts) {
|
|
|
261
261
|
})
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
|
-
var import_node_url,
|
|
264
|
+
var import_node_url, import_node_path55, import_node_crypto2, grpc, protoLoader;
|
|
265
265
|
var init_otel_grpc = __esm({
|
|
266
266
|
"src/otel-grpc.ts"() {
|
|
267
267
|
"use strict";
|
|
268
268
|
init_cjs_shims();
|
|
269
269
|
import_node_url = require("url");
|
|
270
|
-
|
|
270
|
+
import_node_path55 = __toESM(require("path"), 1);
|
|
271
271
|
import_node_crypto2 = require("crypto");
|
|
272
272
|
grpc = __toESM(require("@grpc/grpc-js"), 1);
|
|
273
273
|
protoLoader = __toESM(require("@grpc/proto-loader"), 1);
|
|
@@ -413,8 +413,8 @@ function websocketChannelPathOf(attrs) {
|
|
|
413
413
|
const v = attrs[key];
|
|
414
414
|
if (typeof v === "string" && v.length > 0) {
|
|
415
415
|
const q = v.indexOf("?");
|
|
416
|
-
const
|
|
417
|
-
if (
|
|
416
|
+
const path77 = q === -1 ? v : v.slice(0, q);
|
|
417
|
+
if (path77.length > 0) return path77;
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
return void 0;
|
|
@@ -476,10 +476,10 @@ function parseOtlpRequest(body) {
|
|
|
476
476
|
return out;
|
|
477
477
|
}
|
|
478
478
|
function loadProtoRoot() {
|
|
479
|
-
const here =
|
|
480
|
-
const protoRoot =
|
|
479
|
+
const here = import_node_path56.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
|
|
480
|
+
const protoRoot = import_node_path56.default.resolve(here, "..", "proto");
|
|
481
481
|
const root = new import_protobufjs.default.Root();
|
|
482
|
-
root.resolvePath = (_origin, target) =>
|
|
482
|
+
root.resolvePath = (_origin, target) => import_node_path56.default.resolve(protoRoot, target);
|
|
483
483
|
root.loadSync(
|
|
484
484
|
"opentelemetry/proto/collector/trace/v1/trace_service.proto",
|
|
485
485
|
{ keepCase: true }
|
|
@@ -741,12 +741,12 @@ async function buildOtelReceiver(opts) {
|
|
|
741
741
|
};
|
|
742
742
|
return decorated;
|
|
743
743
|
}
|
|
744
|
-
var
|
|
744
|
+
var import_node_path56, import_node_url2, import_node_zlib, import_fastify, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody;
|
|
745
745
|
var init_otel = __esm({
|
|
746
746
|
"src/otel.ts"() {
|
|
747
747
|
"use strict";
|
|
748
748
|
init_cjs_shims();
|
|
749
|
-
|
|
749
|
+
import_node_path56 = __toESM(require("path"), 1);
|
|
750
750
|
import_node_url2 = require("url");
|
|
751
751
|
import_node_zlib = __toESM(require("zlib"), 1);
|
|
752
752
|
import_fastify = __toESM(require("fastify"), 1);
|
|
@@ -763,7 +763,7 @@ var init_otel = __esm({
|
|
|
763
763
|
|
|
764
764
|
// src/server.ts
|
|
765
765
|
init_cjs_shims();
|
|
766
|
-
var
|
|
766
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
767
767
|
|
|
768
768
|
// src/graph.ts
|
|
769
769
|
init_cjs_shims();
|
|
@@ -787,7 +787,7 @@ function getGraph(project = DEFAULT_PROJECT) {
|
|
|
787
787
|
init_cjs_shims();
|
|
788
788
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
789
789
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
790
|
-
var
|
|
790
|
+
var import_types100 = require("@neat.is/types");
|
|
791
791
|
|
|
792
792
|
// src/extend/index.ts
|
|
793
793
|
init_cjs_shims();
|
|
@@ -899,12 +899,12 @@ var HOOK_WALK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
899
899
|
]);
|
|
900
900
|
async function findHookFiles(scanPath) {
|
|
901
901
|
const found = [];
|
|
902
|
-
const
|
|
902
|
+
const walk11 = async (dir) => {
|
|
903
903
|
const entries = await import_node_fs2.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
904
904
|
for (const entry of entries) {
|
|
905
905
|
if (entry.isDirectory()) {
|
|
906
906
|
if (entry.name.startsWith(".") || HOOK_WALK_SKIP_DIRS.has(entry.name)) continue;
|
|
907
|
-
await
|
|
907
|
+
await walk11(import_node_path2.default.join(dir, entry.name));
|
|
908
908
|
} else if (entry.isFile()) {
|
|
909
909
|
if ((entry.name.startsWith("instrumentation") || entry.name.startsWith("otel-init")) && /\.(ts|js|cjs|mjs)$/.test(entry.name)) {
|
|
910
910
|
const rel = import_node_path2.default.relative(scanPath, import_node_path2.default.join(dir, entry.name));
|
|
@@ -913,7 +913,7 @@ async function findHookFiles(scanPath) {
|
|
|
913
913
|
}
|
|
914
914
|
}
|
|
915
915
|
};
|
|
916
|
-
await
|
|
916
|
+
await walk11(scanPath);
|
|
917
917
|
return found.sort();
|
|
918
918
|
}
|
|
919
919
|
async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
|
|
@@ -2320,7 +2320,7 @@ function buildServiceHostIndex(services) {
|
|
|
2320
2320
|
async function walkSourceFiles(dir, excludeDirs = []) {
|
|
2321
2321
|
const excluded = new Set(excludeDirs.map((d) => import_node_path7.default.resolve(d)));
|
|
2322
2322
|
const out = [];
|
|
2323
|
-
async function
|
|
2323
|
+
async function walk11(current) {
|
|
2324
2324
|
const entries = await import_node_fs7.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
2325
2325
|
for (const entry of entries) {
|
|
2326
2326
|
const full = import_node_path7.default.join(current, entry.name);
|
|
@@ -2328,7 +2328,7 @@ async function walkSourceFiles(dir, excludeDirs = []) {
|
|
|
2328
2328
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
2329
2329
|
if (excluded.has(import_node_path7.default.resolve(full))) continue;
|
|
2330
2330
|
if (await isPythonVenvDir(full)) continue;
|
|
2331
|
-
await
|
|
2331
|
+
await walk11(full);
|
|
2332
2332
|
} else if (entry.isFile() && SERVICE_FILE_EXTENSIONS.has(import_node_path7.default.extname(entry.name)) && // Skip NEAT's own generated `otel-init.*` bootstrap — extracting it
|
|
2333
2333
|
// would attribute our instrumentation imports to the user's service.
|
|
2334
2334
|
!isNeatAuthoredSourceFile(entry.name)) {
|
|
@@ -2336,7 +2336,7 @@ async function walkSourceFiles(dir, excludeDirs = []) {
|
|
|
2336
2336
|
}
|
|
2337
2337
|
}
|
|
2338
2338
|
}
|
|
2339
|
-
await
|
|
2339
|
+
await walk11(dir);
|
|
2340
2340
|
return out;
|
|
2341
2341
|
}
|
|
2342
2342
|
async function loadSourceFiles(dir, excludeDirs = []) {
|
|
@@ -2932,8 +2932,8 @@ function chiRoutesFromSource(source, parser) {
|
|
|
2932
2932
|
chiWalk(tree.rootNode, "", out);
|
|
2933
2933
|
return out;
|
|
2934
2934
|
}
|
|
2935
|
-
function stripChiRegex(
|
|
2936
|
-
return
|
|
2935
|
+
function stripChiRegex(path77) {
|
|
2936
|
+
return path77.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
|
|
2937
2937
|
}
|
|
2938
2938
|
function chiWalk(node, prefix, out) {
|
|
2939
2939
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
@@ -3605,9 +3605,9 @@ function rubyRocketRoute(args) {
|
|
|
3605
3605
|
if (!pair || pair.type !== "pair") continue;
|
|
3606
3606
|
const k = pair.childForFieldName("key");
|
|
3607
3607
|
if (k?.type !== "string") continue;
|
|
3608
|
-
const
|
|
3609
|
-
if (
|
|
3610
|
-
return { path:
|
|
3608
|
+
const path77 = rubyLiteral(k);
|
|
3609
|
+
if (path77 === null) continue;
|
|
3610
|
+
return { path: path77, target: rubyLiteral(pair.childForFieldName("value")) };
|
|
3611
3611
|
}
|
|
3612
3612
|
return null;
|
|
3613
3613
|
}
|
|
@@ -6102,29 +6102,29 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
6102
6102
|
toPromote.push({ frontierId: id, serviceId: target });
|
|
6103
6103
|
});
|
|
6104
6104
|
let promoted = 0;
|
|
6105
|
-
for (const { frontierId: frontierId2, serviceId:
|
|
6105
|
+
for (const { frontierId: frontierId2, serviceId: serviceId17 } of toPromote) {
|
|
6106
6106
|
if (opts.policies && opts.policies.length > 0 && opts.policyCtx) {
|
|
6107
6107
|
const gate = canPromoteFrontier(graph, frontierId2, opts.policies, opts.policyCtx);
|
|
6108
6108
|
if (!gate.allowed) {
|
|
6109
6109
|
continue;
|
|
6110
6110
|
}
|
|
6111
6111
|
}
|
|
6112
|
-
rewireFrontierEdges(graph, frontierId2,
|
|
6112
|
+
rewireFrontierEdges(graph, frontierId2, serviceId17);
|
|
6113
6113
|
graph.dropNode(frontierId2);
|
|
6114
6114
|
promoted++;
|
|
6115
6115
|
}
|
|
6116
6116
|
return promoted;
|
|
6117
6117
|
}
|
|
6118
|
-
function rewireFrontierEdges(graph, frontierId2,
|
|
6118
|
+
function rewireFrontierEdges(graph, frontierId2, serviceId17) {
|
|
6119
6119
|
const inbound = [...graph.inboundEdges(frontierId2)];
|
|
6120
6120
|
const outbound = [...graph.outboundEdges(frontierId2)];
|
|
6121
6121
|
for (const edgeId of inbound) {
|
|
6122
6122
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6123
|
-
rebuildEdge(graph, edge, edge.source,
|
|
6123
|
+
rebuildEdge(graph, edge, edge.source, serviceId17, edgeId);
|
|
6124
6124
|
}
|
|
6125
6125
|
for (const edgeId of outbound) {
|
|
6126
6126
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6127
|
-
rebuildEdge(graph, edge,
|
|
6127
|
+
rebuildEdge(graph, edge, serviceId17, edge.target, edgeId);
|
|
6128
6128
|
}
|
|
6129
6129
|
}
|
|
6130
6130
|
function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
@@ -6464,19 +6464,19 @@ function confidenceFromMix(edges, now = Date.now()) {
|
|
|
6464
6464
|
function longestIncomingWalk(graph, start, maxDepth) {
|
|
6465
6465
|
let best = { path: [start], edges: [] };
|
|
6466
6466
|
const visited = /* @__PURE__ */ new Set([start]);
|
|
6467
|
-
function step(node,
|
|
6468
|
-
if (
|
|
6469
|
-
best = { path: [...
|
|
6467
|
+
function step(node, path77, edges) {
|
|
6468
|
+
if (path77.length > best.path.length) {
|
|
6469
|
+
best = { path: [...path77], edges: [...edges] };
|
|
6470
6470
|
}
|
|
6471
|
-
if (
|
|
6471
|
+
if (path77.length - 1 >= maxDepth) return;
|
|
6472
6472
|
const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
|
|
6473
6473
|
for (const [srcId, edge] of incoming) {
|
|
6474
6474
|
if (visited.has(srcId)) continue;
|
|
6475
6475
|
visited.add(srcId);
|
|
6476
|
-
|
|
6476
|
+
path77.push(srcId);
|
|
6477
6477
|
edges.push(edge);
|
|
6478
|
-
step(srcId,
|
|
6479
|
-
|
|
6478
|
+
step(srcId, path77, edges);
|
|
6479
|
+
path77.pop();
|
|
6480
6480
|
edges.pop();
|
|
6481
6481
|
visited.delete(srcId);
|
|
6482
6482
|
}
|
|
@@ -6484,14 +6484,14 @@ function longestIncomingWalk(graph, start, maxDepth) {
|
|
|
6484
6484
|
step(start, [start], []);
|
|
6485
6485
|
return best;
|
|
6486
6486
|
}
|
|
6487
|
-
function databaseRootCauseShape(graph, origin,
|
|
6487
|
+
function databaseRootCauseShape(graph, origin, walk11) {
|
|
6488
6488
|
const targetDb = origin;
|
|
6489
6489
|
const candidatePairs = compatPairs().filter((p) => p.engine === targetDb.engine);
|
|
6490
6490
|
if (candidatePairs.length === 0) return null;
|
|
6491
|
-
for (const id of
|
|
6491
|
+
for (const id of walk11.path) {
|
|
6492
6492
|
const owner = resolveOwningService(graph, id);
|
|
6493
6493
|
if (!owner) continue;
|
|
6494
|
-
const { id:
|
|
6494
|
+
const { id: serviceId17, svc } = owner;
|
|
6495
6495
|
const deps = svc.dependencies ?? {};
|
|
6496
6496
|
for (const pair of candidatePairs) {
|
|
6497
6497
|
const declared = deps[pair.driver];
|
|
@@ -6504,7 +6504,7 @@ function databaseRootCauseShape(graph, origin, walk10) {
|
|
|
6504
6504
|
);
|
|
6505
6505
|
if (!result.compatible) {
|
|
6506
6506
|
return {
|
|
6507
|
-
rootCauseNode:
|
|
6507
|
+
rootCauseNode: serviceId17,
|
|
6508
6508
|
rootCauseReason: result.reason ?? "incompatible driver",
|
|
6509
6509
|
...result.minDriverVersion ? {
|
|
6510
6510
|
fixRecommendation: `Upgrade ${svc.name} ${pair.driver} driver to >= ${result.minDriverVersion}`
|
|
@@ -6515,11 +6515,11 @@ function databaseRootCauseShape(graph, origin, walk10) {
|
|
|
6515
6515
|
}
|
|
6516
6516
|
return null;
|
|
6517
6517
|
}
|
|
6518
|
-
function serviceRootCauseShape(graph, _origin,
|
|
6519
|
-
for (const id of
|
|
6518
|
+
function serviceRootCauseShape(graph, _origin, walk11) {
|
|
6519
|
+
for (const id of walk11.path) {
|
|
6520
6520
|
const owner = resolveOwningService(graph, id);
|
|
6521
6521
|
if (!owner) continue;
|
|
6522
|
-
const { id:
|
|
6522
|
+
const { id: serviceId17, svc } = owner;
|
|
6523
6523
|
const deps = svc.dependencies ?? {};
|
|
6524
6524
|
const serviceNodeEngine = svc.nodeEngine;
|
|
6525
6525
|
for (const constraint of nodeEngineConstraints()) {
|
|
@@ -6528,7 +6528,7 @@ function serviceRootCauseShape(graph, _origin, walk10) {
|
|
|
6528
6528
|
const result = checkNodeEngineConstraint(constraint, declared, serviceNodeEngine);
|
|
6529
6529
|
if (!result.compatible && result.reason) {
|
|
6530
6530
|
return {
|
|
6531
|
-
rootCauseNode:
|
|
6531
|
+
rootCauseNode: serviceId17,
|
|
6532
6532
|
rootCauseReason: result.reason,
|
|
6533
6533
|
...result.requiredNodeVersion ? {
|
|
6534
6534
|
fixRecommendation: `Bump ${svc.name}'s engines.node to >= ${result.requiredNodeVersion}`
|
|
@@ -6543,7 +6543,7 @@ function serviceRootCauseShape(graph, _origin, walk10) {
|
|
|
6543
6543
|
const result = checkPackageConflict(conflict, declared, requiredDeclared);
|
|
6544
6544
|
if (!result.compatible && result.reason) {
|
|
6545
6545
|
return {
|
|
6546
|
-
rootCauseNode:
|
|
6546
|
+
rootCauseNode: serviceId17,
|
|
6547
6547
|
rootCauseReason: result.reason,
|
|
6548
6548
|
fixRecommendation: `Upgrade ${svc.name}'s ${conflict.requires.name} to >= ${conflict.requires.minVersion}`
|
|
6549
6549
|
};
|
|
@@ -6552,15 +6552,15 @@ function serviceRootCauseShape(graph, _origin, walk10) {
|
|
|
6552
6552
|
}
|
|
6553
6553
|
return null;
|
|
6554
6554
|
}
|
|
6555
|
-
function fileRootCauseShape(graph, origin,
|
|
6555
|
+
function fileRootCauseShape(graph, origin, walk11) {
|
|
6556
6556
|
const owner = resolveOwningService(graph, origin.id);
|
|
6557
6557
|
if (!owner) return null;
|
|
6558
|
-
return serviceRootCauseShape(graph, owner.svc,
|
|
6558
|
+
return serviceRootCauseShape(graph, owner.svc, walk11);
|
|
6559
6559
|
}
|
|
6560
|
-
function symbolRootCauseShape(graph, origin,
|
|
6560
|
+
function symbolRootCauseShape(graph, origin, walk11) {
|
|
6561
6561
|
const owner = resolveOwningService(graph, origin.id);
|
|
6562
6562
|
if (!owner) return null;
|
|
6563
|
-
return serviceRootCauseShape(graph, owner.svc,
|
|
6563
|
+
return serviceRootCauseShape(graph, owner.svc, walk11);
|
|
6564
6564
|
}
|
|
6565
6565
|
var rootCauseShapes = {
|
|
6566
6566
|
[import_types8.NodeType.DatabaseNode]: databaseRootCauseShape,
|
|
@@ -6573,8 +6573,8 @@ function legacyRootCause(graph, errorNodeId, errorEvent, incidents) {
|
|
|
6573
6573
|
const origin = graph.getNodeAttributes(errorNodeId);
|
|
6574
6574
|
const shape = rootCauseShapes[origin.type];
|
|
6575
6575
|
if (shape) {
|
|
6576
|
-
const
|
|
6577
|
-
const match = shape(graph, origin,
|
|
6576
|
+
const walk11 = longestIncomingWalk(graph, errorNodeId, ROOT_CAUSE_MAX_DEPTH);
|
|
6577
|
+
const match = shape(graph, origin, walk11);
|
|
6578
6578
|
if (match) {
|
|
6579
6579
|
const reason = errorEvent ? `${match.rootCauseReason} (observed error: ${errorEvent.errorMessage})` : match.rootCauseReason;
|
|
6580
6580
|
return {
|
|
@@ -6582,9 +6582,9 @@ function legacyRootCause(graph, errorNodeId, errorEvent, incidents) {
|
|
|
6582
6582
|
result: import_types8.RootCauseResultSchema.parse({
|
|
6583
6583
|
rootCauseNode: match.rootCauseNode,
|
|
6584
6584
|
rootCauseReason: reason,
|
|
6585
|
-
traversalPath:
|
|
6586
|
-
edgeProvenances:
|
|
6587
|
-
confidence: confidenceFromMix(
|
|
6585
|
+
traversalPath: walk11.path,
|
|
6586
|
+
edgeProvenances: walk11.edges.map((e) => e.provenance),
|
|
6587
|
+
confidence: confidenceFromMix(walk11.edges),
|
|
6588
6588
|
fixRecommendation: match.fixRecommendation
|
|
6589
6589
|
})
|
|
6590
6590
|
};
|
|
@@ -6648,9 +6648,9 @@ function rootCauseFromIncidents(nodeId, incidents, errorEvent) {
|
|
|
6648
6648
|
function isFailingCallEdge(e) {
|
|
6649
6649
|
return e.type === import_types8.EdgeType.CALLS && (e.signal?.errorCount ?? 0) > 0;
|
|
6650
6650
|
}
|
|
6651
|
-
function callSourcesForService(graph,
|
|
6652
|
-
const ids = [
|
|
6653
|
-
for (const edgeId of graph.outboundEdges(
|
|
6651
|
+
function callSourcesForService(graph, serviceId17) {
|
|
6652
|
+
const ids = [serviceId17];
|
|
6653
|
+
for (const edgeId of graph.outboundEdges(serviceId17)) {
|
|
6654
6654
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6655
6655
|
if (e.type !== import_types8.EdgeType.CONTAINS) continue;
|
|
6656
6656
|
const tgt = graph.getNodeAttributes(e.target);
|
|
@@ -6674,9 +6674,9 @@ function failingCallDominates(e, id, curEdge, curId) {
|
|
|
6674
6674
|
}
|
|
6675
6675
|
return id < curId;
|
|
6676
6676
|
}
|
|
6677
|
-
function dominantFailingCall(graph,
|
|
6677
|
+
function dominantFailingCall(graph, serviceId17, visited) {
|
|
6678
6678
|
let best = null;
|
|
6679
|
-
for (const src of callSourcesForService(graph,
|
|
6679
|
+
for (const src of callSourcesForService(graph, serviceId17)) {
|
|
6680
6680
|
for (const edgeId of graph.outboundEdges(src)) {
|
|
6681
6681
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6682
6682
|
if (!isFailingCallEdge(e)) continue;
|
|
@@ -6691,20 +6691,20 @@ function dominantFailingCall(graph, serviceId16, visited) {
|
|
|
6691
6691
|
return best;
|
|
6692
6692
|
}
|
|
6693
6693
|
function followFailingCallChain(graph, originServiceId, maxDepth) {
|
|
6694
|
-
const
|
|
6694
|
+
const path77 = [originServiceId];
|
|
6695
6695
|
const edges = [];
|
|
6696
6696
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
6697
6697
|
let current = originServiceId;
|
|
6698
6698
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
6699
6699
|
const hop = dominantFailingCall(graph, current, visited);
|
|
6700
6700
|
if (!hop) break;
|
|
6701
|
-
|
|
6701
|
+
path77.push(hop.nextService);
|
|
6702
6702
|
edges.push(hop.edge);
|
|
6703
6703
|
visited.add(hop.nextService);
|
|
6704
6704
|
current = hop.nextService;
|
|
6705
6705
|
}
|
|
6706
6706
|
if (edges.length === 0) return null;
|
|
6707
|
-
return { path:
|
|
6707
|
+
return { path: path77, edges, culprit: current };
|
|
6708
6708
|
}
|
|
6709
6709
|
function isStaleCallEdge(e) {
|
|
6710
6710
|
return e.type === import_types8.EdgeType.CALLS && e.provenance === import_types8.Provenance.STALE;
|
|
@@ -6715,9 +6715,9 @@ function staleCallDominates(e, id, curEdge, curId) {
|
|
|
6715
6715
|
if (ev !== cv) return ev > cv;
|
|
6716
6716
|
return id < curId;
|
|
6717
6717
|
}
|
|
6718
|
-
function dominantStaleCall(graph,
|
|
6718
|
+
function dominantStaleCall(graph, serviceId17, visited) {
|
|
6719
6719
|
const bestByCallee = /* @__PURE__ */ new Map();
|
|
6720
|
-
for (const src of callSourcesForService(graph,
|
|
6720
|
+
for (const src of callSourcesForService(graph, serviceId17)) {
|
|
6721
6721
|
for (const edgeId of graph.outboundEdges(src)) {
|
|
6722
6722
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6723
6723
|
if (e.type !== import_types8.EdgeType.CALLS) continue;
|
|
@@ -6740,26 +6740,26 @@ function dominantStaleCall(graph, serviceId16, visited) {
|
|
|
6740
6740
|
return best;
|
|
6741
6741
|
}
|
|
6742
6742
|
function followStaleCallChain(graph, originServiceId, maxDepth) {
|
|
6743
|
-
const
|
|
6743
|
+
const path77 = [originServiceId];
|
|
6744
6744
|
const edges = [];
|
|
6745
6745
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
6746
6746
|
let current = originServiceId;
|
|
6747
6747
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
6748
6748
|
const hop = dominantStaleCall(graph, current, visited);
|
|
6749
6749
|
if (!hop) break;
|
|
6750
|
-
|
|
6750
|
+
path77.push(hop.nextService);
|
|
6751
6751
|
edges.push(hop.edge);
|
|
6752
6752
|
visited.add(hop.nextService);
|
|
6753
6753
|
current = hop.nextService;
|
|
6754
6754
|
}
|
|
6755
6755
|
if (edges.length === 0) return null;
|
|
6756
|
-
return { path:
|
|
6756
|
+
return { path: path77, edges, culprit: current };
|
|
6757
6757
|
}
|
|
6758
6758
|
function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
6759
6759
|
const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
|
|
6760
6760
|
if (!chain) return null;
|
|
6761
6761
|
const culprit = chain.culprit;
|
|
6762
|
-
const
|
|
6762
|
+
const path77 = [...chain.path];
|
|
6763
6763
|
const edgeProvenances = chain.edges.map((e) => e.provenance);
|
|
6764
6764
|
const baseConfidence = confidenceFromMix(chain.edges);
|
|
6765
6765
|
const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
|
|
@@ -6767,14 +6767,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
6767
6767
|
if (loc) {
|
|
6768
6768
|
let rootCauseNode = culprit;
|
|
6769
6769
|
if (loc.fileNode) {
|
|
6770
|
-
|
|
6770
|
+
path77.push(loc.fileNode);
|
|
6771
6771
|
edgeProvenances.push(import_types8.Provenance.OBSERVED);
|
|
6772
6772
|
rootCauseNode = loc.fileNode;
|
|
6773
6773
|
}
|
|
6774
6774
|
return import_types8.RootCauseResultSchema.parse({
|
|
6775
6775
|
rootCauseNode,
|
|
6776
6776
|
rootCauseReason: loc.rootCauseReason,
|
|
6777
|
-
traversalPath:
|
|
6777
|
+
traversalPath: path77,
|
|
6778
6778
|
edgeProvenances,
|
|
6779
6779
|
confidence,
|
|
6780
6780
|
...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
|
|
@@ -6786,7 +6786,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
6786
6786
|
return import_types8.RootCauseResultSchema.parse({
|
|
6787
6787
|
rootCauseNode: culprit,
|
|
6788
6788
|
rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
|
|
6789
|
-
traversalPath:
|
|
6789
|
+
traversalPath: path77,
|
|
6790
6790
|
edgeProvenances,
|
|
6791
6791
|
confidence,
|
|
6792
6792
|
fixRecommendation: `Inspect ${culpritName}'s failing handler`
|
|
@@ -7399,10 +7399,10 @@ function enrichWithNavigation(graph, errorNodeId, tagged, incidents, now) {
|
|
|
7399
7399
|
traversalPath = staleChain.path;
|
|
7400
7400
|
edgeProvenances = staleChain.edges.map((e) => e.provenance);
|
|
7401
7401
|
} else if (top.node !== seedNode) {
|
|
7402
|
-
const
|
|
7403
|
-
if (
|
|
7404
|
-
traversalPath =
|
|
7405
|
-
edgeProvenances =
|
|
7402
|
+
const path77 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
|
|
7403
|
+
if (path77) {
|
|
7404
|
+
traversalPath = path77.nodes;
|
|
7405
|
+
edgeProvenances = path77.edges.map((e) => e.provenance);
|
|
7406
7406
|
} else {
|
|
7407
7407
|
traversalPath = [errorNodeId, top.node];
|
|
7408
7408
|
edgeProvenances = [top.provenance ?? import_types8.Provenance.OBSERVED];
|
|
@@ -7950,10 +7950,10 @@ function datastoreEverObserved(graph, nodeId) {
|
|
|
7950
7950
|
}
|
|
7951
7951
|
return false;
|
|
7952
7952
|
}
|
|
7953
|
-
function serviceHasObservedSameEngineStore(graph, buckets2,
|
|
7953
|
+
function serviceHasObservedSameEngineStore(graph, buckets2, serviceId17, engine, excludeTarget) {
|
|
7954
7954
|
for (const bucket of buckets2.values()) {
|
|
7955
7955
|
if (bucket.type !== import_types9.EdgeType.CONNECTS_TO) continue;
|
|
7956
|
-
if (bucket.source !==
|
|
7956
|
+
if (bucket.source !== serviceId17) continue;
|
|
7957
7957
|
if (bucket.target === excludeTarget) continue;
|
|
7958
7958
|
if (!graph.hasNode(bucket.target)) continue;
|
|
7959
7959
|
const target = graph.getNodeAttributes(bucket.target);
|
|
@@ -9041,9 +9041,9 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
|
9041
9041
|
"StatefulSet",
|
|
9042
9042
|
"DaemonSet"
|
|
9043
9043
|
]);
|
|
9044
|
-
function addAliases(graph,
|
|
9045
|
-
if (!graph.hasNode(
|
|
9046
|
-
const node = graph.getNodeAttributes(
|
|
9044
|
+
function addAliases(graph, serviceId17, candidates) {
|
|
9045
|
+
if (!graph.hasNode(serviceId17)) return;
|
|
9046
|
+
const node = graph.getNodeAttributes(serviceId17);
|
|
9047
9047
|
if (node.type !== import_types20.NodeType.ServiceNode) return;
|
|
9048
9048
|
const set = new Set(node.aliases ?? []);
|
|
9049
9049
|
for (const c of candidates) {
|
|
@@ -9053,7 +9053,7 @@ function addAliases(graph, serviceId16, candidates) {
|
|
|
9053
9053
|
}
|
|
9054
9054
|
if (set.size === 0) return;
|
|
9055
9055
|
const updated = { ...node, aliases: [...set].sort() };
|
|
9056
|
-
graph.replaceNodeAttributes(
|
|
9056
|
+
graph.replaceNodeAttributes(serviceId17, updated);
|
|
9057
9057
|
}
|
|
9058
9058
|
function indexServicesByName(services) {
|
|
9059
9059
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -9086,12 +9086,12 @@ async function collectComposeAliases(graph, scanPath, serviceIndex) {
|
|
|
9086
9086
|
}
|
|
9087
9087
|
if (!compose?.services) return;
|
|
9088
9088
|
for (const [composeName, svc] of Object.entries(compose.services)) {
|
|
9089
|
-
const
|
|
9090
|
-
if (!
|
|
9089
|
+
const serviceId17 = serviceIndex.get(composeName);
|
|
9090
|
+
if (!serviceId17) continue;
|
|
9091
9091
|
const aliases = /* @__PURE__ */ new Set([composeName]);
|
|
9092
9092
|
if (svc.container_name) aliases.add(svc.container_name);
|
|
9093
9093
|
if (svc.hostname) aliases.add(svc.hostname);
|
|
9094
|
-
addAliases(graph,
|
|
9094
|
+
addAliases(graph, serviceId17, aliases);
|
|
9095
9095
|
}
|
|
9096
9096
|
}
|
|
9097
9097
|
var LABEL_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -10202,7 +10202,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
10202
10202
|
return best;
|
|
10203
10203
|
};
|
|
10204
10204
|
const requests = [];
|
|
10205
|
-
const
|
|
10205
|
+
const walk11 = (node) => {
|
|
10206
10206
|
if (node.type === "class_declaration" || node.type === "abstract_class_declaration" || node.type === "class") {
|
|
10207
10207
|
const self = localBySpan.get(`${node.startPosition.row + 1}:${node.endPosition.row + 1}`);
|
|
10208
10208
|
if (self && self.kind === "class") {
|
|
@@ -10248,10 +10248,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
10248
10248
|
}
|
|
10249
10249
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
10250
10250
|
const child = node.namedChild(i);
|
|
10251
|
-
if (child)
|
|
10251
|
+
if (child) walk11(child);
|
|
10252
10252
|
}
|
|
10253
10253
|
};
|
|
10254
|
-
|
|
10254
|
+
walk11(root);
|
|
10255
10255
|
for (const req of requests) {
|
|
10256
10256
|
const targetSid = resolveTarget(req.targetName, req.wantKind);
|
|
10257
10257
|
if (!targetSid) continue;
|
|
@@ -11423,7 +11423,7 @@ var import_types25 = require("@neat.is/types");
|
|
|
11423
11423
|
async function walkConfigFiles(dir, excludeDirs = []) {
|
|
11424
11424
|
const excluded = new Set(excludeDirs.map((d) => import_node_path37.default.resolve(d)));
|
|
11425
11425
|
const out = [];
|
|
11426
|
-
async function
|
|
11426
|
+
async function walk11(current) {
|
|
11427
11427
|
const entries = await import_node_fs25.promises.readdir(current, { withFileTypes: true });
|
|
11428
11428
|
for (const entry of entries) {
|
|
11429
11429
|
const full = import_node_path37.default.join(current, entry.name);
|
|
@@ -11431,13 +11431,13 @@ async function walkConfigFiles(dir, excludeDirs = []) {
|
|
|
11431
11431
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
11432
11432
|
if (excluded.has(import_node_path37.default.resolve(full))) continue;
|
|
11433
11433
|
if (await isPythonVenvDir(full)) continue;
|
|
11434
|
-
await
|
|
11434
|
+
await walk11(full);
|
|
11435
11435
|
} else if (entry.isFile() && isConfigFile(entry.name).match) {
|
|
11436
11436
|
out.push(full);
|
|
11437
11437
|
}
|
|
11438
11438
|
}
|
|
11439
11439
|
}
|
|
11440
|
-
await
|
|
11440
|
+
await walk11(dir);
|
|
11441
11441
|
return out;
|
|
11442
11442
|
}
|
|
11443
11443
|
async function addConfigNodes(graph, services, scanPath) {
|
|
@@ -11528,7 +11528,7 @@ function grpcMethodsFromProto(content, fqPackage) {
|
|
|
11528
11528
|
async function walkProtoFiles(dir, excludeDirs = []) {
|
|
11529
11529
|
const excluded = new Set(excludeDirs.map((d) => import_node_path38.default.resolve(d)));
|
|
11530
11530
|
const out = [];
|
|
11531
|
-
async function
|
|
11531
|
+
async function walk11(current) {
|
|
11532
11532
|
const entries = await import_node_fs26.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
11533
11533
|
for (const entry of entries) {
|
|
11534
11534
|
const full = import_node_path38.default.join(current, entry.name);
|
|
@@ -11536,13 +11536,13 @@ async function walkProtoFiles(dir, excludeDirs = []) {
|
|
|
11536
11536
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
11537
11537
|
if (excluded.has(import_node_path38.default.resolve(full))) continue;
|
|
11538
11538
|
if (await isPythonVenvDir(full)) continue;
|
|
11539
|
-
await
|
|
11539
|
+
await walk11(full);
|
|
11540
11540
|
} else if (entry.isFile() && import_node_path38.default.extname(entry.name) === PROTO_EXTENSION) {
|
|
11541
11541
|
out.push(full);
|
|
11542
11542
|
}
|
|
11543
11543
|
}
|
|
11544
11544
|
}
|
|
11545
|
-
await
|
|
11545
|
+
await walk11(dir);
|
|
11546
11546
|
return out;
|
|
11547
11547
|
}
|
|
11548
11548
|
async function addGrpcMethods(graph, services) {
|
|
@@ -11610,7 +11610,7 @@ async function addGrpcMethods(graph, services) {
|
|
|
11610
11610
|
|
|
11611
11611
|
// src/extract/calls/index.ts
|
|
11612
11612
|
init_cjs_shims();
|
|
11613
|
-
var
|
|
11613
|
+
var import_types46 = require("@neat.is/types");
|
|
11614
11614
|
|
|
11615
11615
|
// src/extract/calls/http.ts
|
|
11616
11616
|
init_cjs_shims();
|
|
@@ -12545,7 +12545,7 @@ function isFirestoreClientFactory(node) {
|
|
|
12545
12545
|
}
|
|
12546
12546
|
function firestoreClientVars(root) {
|
|
12547
12547
|
const vars = /* @__PURE__ */ new Set();
|
|
12548
|
-
const
|
|
12548
|
+
const walk11 = (node) => {
|
|
12549
12549
|
if (node.type === "variable_declarator") {
|
|
12550
12550
|
const name = node.childForFieldName("name");
|
|
12551
12551
|
let value = node.childForFieldName("value");
|
|
@@ -12554,9 +12554,9 @@ function firestoreClientVars(root) {
|
|
|
12554
12554
|
vars.add(name.text);
|
|
12555
12555
|
}
|
|
12556
12556
|
}
|
|
12557
|
-
for (const c of namedChildren(node))
|
|
12557
|
+
for (const c of namedChildren(node)) walk11(c);
|
|
12558
12558
|
};
|
|
12559
|
-
|
|
12559
|
+
walk11(root);
|
|
12560
12560
|
return vars;
|
|
12561
12561
|
}
|
|
12562
12562
|
function isClientExpr(node, clientVars) {
|
|
@@ -12711,7 +12711,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
12711
12711
|
}
|
|
12712
12712
|
s.add(field);
|
|
12713
12713
|
};
|
|
12714
|
-
const
|
|
12714
|
+
const walk11 = (node) => {
|
|
12715
12715
|
if (node.type === "call_expression") {
|
|
12716
12716
|
const fn = node.childForFieldName("function");
|
|
12717
12717
|
const line = node.startPosition.row + 1;
|
|
@@ -12751,9 +12751,9 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
12751
12751
|
}
|
|
12752
12752
|
}
|
|
12753
12753
|
}
|
|
12754
|
-
for (const c of namedChildren(node))
|
|
12754
|
+
for (const c of namedChildren(node)) walk11(c);
|
|
12755
12755
|
};
|
|
12756
|
-
|
|
12756
|
+
walk11(tree.rootNode);
|
|
12757
12757
|
const out = [];
|
|
12758
12758
|
for (const [collPath, line] of collLine) {
|
|
12759
12759
|
const byField = writes.get(collPath);
|
|
@@ -13369,13 +13369,13 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
13369
13369
|
return out;
|
|
13370
13370
|
}
|
|
13371
13371
|
|
|
13372
|
-
// src/extract/calls/
|
|
13372
|
+
// src/extract/calls/socket.ts
|
|
13373
13373
|
init_cjs_shims();
|
|
13374
13374
|
var import_node_path49 = __toESM(require("path"), 1);
|
|
13375
13375
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
13376
13376
|
var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
|
|
13377
13377
|
var import_types37 = require("@neat.is/types");
|
|
13378
|
-
var
|
|
13378
|
+
var SOCKET_IMPORT_RE = /(?:^|\n)\s*(?:import\s+socket\b|from\s+socket\s+import\b)/;
|
|
13379
13379
|
var PARSE_CHUNK7 = 16384;
|
|
13380
13380
|
function makePyParser4() {
|
|
13381
13381
|
const p = new import_tree_sitter10.default();
|
|
@@ -13395,22 +13395,109 @@ function namedChildren3(node) {
|
|
|
13395
13395
|
}
|
|
13396
13396
|
return out;
|
|
13397
13397
|
}
|
|
13398
|
+
function walk4(node, visit) {
|
|
13399
|
+
visit(node);
|
|
13400
|
+
for (const c of namedChildren3(node)) walk4(c, visit);
|
|
13401
|
+
}
|
|
13398
13402
|
function pyStaticStringText3(node) {
|
|
13399
13403
|
if (node.type !== "string") return null;
|
|
13400
|
-
for (const
|
|
13404
|
+
for (const child of namedChildren3(node)) {
|
|
13405
|
+
if (child.type === "interpolation") return null;
|
|
13406
|
+
if (child.type === "string_content") return child.text;
|
|
13407
|
+
}
|
|
13408
|
+
return "";
|
|
13409
|
+
}
|
|
13410
|
+
function hasSocketConstructor(root) {
|
|
13411
|
+
let found = false;
|
|
13412
|
+
walk4(root, (n) => {
|
|
13413
|
+
if (found || n.type !== "call") return;
|
|
13414
|
+
const t = n.childForFieldName("function")?.text;
|
|
13415
|
+
if (t === "socket.socket" || t === "socket") found = true;
|
|
13416
|
+
});
|
|
13417
|
+
return found;
|
|
13418
|
+
}
|
|
13419
|
+
function socketEndpointsFromFile(file, serviceDir) {
|
|
13420
|
+
if (!SOCKET_IMPORT_RE.test(file.content)) return [];
|
|
13421
|
+
const tree = parseSource7(makePyParser4(), file.content);
|
|
13422
|
+
if (!hasSocketConstructor(tree.rootNode)) return [];
|
|
13423
|
+
const out = [];
|
|
13424
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13425
|
+
walk4(tree.rootNode, (node) => {
|
|
13426
|
+
if (node.type !== "call") return;
|
|
13427
|
+
const fn = node.childForFieldName("function");
|
|
13428
|
+
if (fn?.type !== "attribute" || fn.childForFieldName("attribute")?.text !== "connect") return;
|
|
13429
|
+
const args = node.childForFieldName("arguments");
|
|
13430
|
+
const first = args ? namedChildren3(args).find((a) => a.type !== "keyword_argument") : void 0;
|
|
13431
|
+
if (!first || first.type !== "tuple") return;
|
|
13432
|
+
const elems = namedChildren3(first);
|
|
13433
|
+
if (elems.length < 2) return;
|
|
13434
|
+
const hostNode = elems[0];
|
|
13435
|
+
const host = hostNode.type === "string" ? pyStaticStringText3(hostNode) : null;
|
|
13436
|
+
const portNode = elems[1];
|
|
13437
|
+
const port = portNode.type === "integer" ? portNode.text : null;
|
|
13438
|
+
const name = host ? port ? `${host}:${port}` : host : "env";
|
|
13439
|
+
if (seen.has(name)) return;
|
|
13440
|
+
seen.add(name);
|
|
13441
|
+
const line = node.startPosition.row + 1;
|
|
13442
|
+
out.push({
|
|
13443
|
+
infraId: (0, import_types37.infraId)("socket", name),
|
|
13444
|
+
name,
|
|
13445
|
+
kind: "socket",
|
|
13446
|
+
edgeType: "CALLS",
|
|
13447
|
+
// A verified `socket.socket(...)` + `.connect((host, port))` call site.
|
|
13448
|
+
confidenceKind: "verified-call-site",
|
|
13449
|
+
evidence: {
|
|
13450
|
+
file: import_node_path49.default.relative(serviceDir, file.path),
|
|
13451
|
+
line,
|
|
13452
|
+
snippet: snippet(file.content, line)
|
|
13453
|
+
}
|
|
13454
|
+
});
|
|
13455
|
+
});
|
|
13456
|
+
return out;
|
|
13457
|
+
}
|
|
13458
|
+
|
|
13459
|
+
// src/extract/calls/django-orm.ts
|
|
13460
|
+
init_cjs_shims();
|
|
13461
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
13462
|
+
var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
|
|
13463
|
+
var import_tree_sitter_python7 = __toESM(require("tree-sitter-python"), 1);
|
|
13464
|
+
var import_types38 = require("@neat.is/types");
|
|
13465
|
+
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
13466
|
+
var PARSE_CHUNK8 = 16384;
|
|
13467
|
+
function makePyParser5() {
|
|
13468
|
+
const p = new import_tree_sitter11.default();
|
|
13469
|
+
p.setLanguage(import_tree_sitter_python7.default);
|
|
13470
|
+
return p;
|
|
13471
|
+
}
|
|
13472
|
+
function parseSource8(parser, source) {
|
|
13473
|
+
return parser.parse(
|
|
13474
|
+
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK8)
|
|
13475
|
+
);
|
|
13476
|
+
}
|
|
13477
|
+
function namedChildren4(node) {
|
|
13478
|
+
const out = [];
|
|
13479
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
13480
|
+
const c = node.namedChild(i);
|
|
13481
|
+
if (c) out.push(c);
|
|
13482
|
+
}
|
|
13483
|
+
return out;
|
|
13484
|
+
}
|
|
13485
|
+
function pyStaticStringText4(node) {
|
|
13486
|
+
if (node.type !== "string") return null;
|
|
13487
|
+
for (const c of namedChildren4(node)) {
|
|
13401
13488
|
if (c.type === "interpolation") return null;
|
|
13402
13489
|
if (c.type === "string_content") return c.text;
|
|
13403
13490
|
}
|
|
13404
13491
|
return "";
|
|
13405
13492
|
}
|
|
13406
|
-
function
|
|
13493
|
+
function walk5(node, visit) {
|
|
13407
13494
|
visit(node);
|
|
13408
|
-
for (const c of
|
|
13495
|
+
for (const c of namedChildren4(node)) walk5(c, visit);
|
|
13409
13496
|
}
|
|
13410
13497
|
function extendsDjangoModel(cls) {
|
|
13411
13498
|
const supers = cls.childForFieldName("superclasses");
|
|
13412
13499
|
if (!supers) return false;
|
|
13413
|
-
for (const a of
|
|
13500
|
+
for (const a of namedChildren4(supers)) {
|
|
13414
13501
|
const t = a.text;
|
|
13415
13502
|
if (t === "models.Model" || t === "Model" || t.endsWith(".Model")) return true;
|
|
13416
13503
|
}
|
|
@@ -13418,31 +13505,31 @@ function extendsDjangoModel(cls) {
|
|
|
13418
13505
|
}
|
|
13419
13506
|
function readMeta(body) {
|
|
13420
13507
|
const out = {};
|
|
13421
|
-
for (const stmt of
|
|
13508
|
+
for (const stmt of namedChildren4(body)) {
|
|
13422
13509
|
if (stmt.type !== "class_definition") continue;
|
|
13423
13510
|
if (stmt.childForFieldName("name")?.text !== "Meta") continue;
|
|
13424
13511
|
const metaBody = stmt.childForFieldName("body");
|
|
13425
13512
|
if (!metaBody) continue;
|
|
13426
|
-
for (const ms of
|
|
13513
|
+
for (const ms of namedChildren4(metaBody)) {
|
|
13427
13514
|
if (ms.type !== "expression_statement") continue;
|
|
13428
13515
|
const a = ms.namedChild(0);
|
|
13429
13516
|
if (a?.type !== "assignment") continue;
|
|
13430
13517
|
const l = a.childForFieldName("left")?.text;
|
|
13431
13518
|
const r = a.childForFieldName("right");
|
|
13432
13519
|
if (r?.type !== "string") continue;
|
|
13433
|
-
if (l === "db_table") out.dbTable =
|
|
13434
|
-
if (l === "app_label") out.appLabel =
|
|
13520
|
+
if (l === "db_table") out.dbTable = pyStaticStringText4(r) ?? void 0;
|
|
13521
|
+
if (l === "app_label") out.appLabel = pyStaticStringText4(r) ?? void 0;
|
|
13435
13522
|
}
|
|
13436
13523
|
}
|
|
13437
13524
|
return out;
|
|
13438
13525
|
}
|
|
13439
13526
|
function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
13440
13527
|
if (!DJANGO_IMPORT_RE.test(file.content)) return [];
|
|
13441
|
-
const tree =
|
|
13528
|
+
const tree = parseSource8(makePyParser5(), file.content);
|
|
13442
13529
|
const out = [];
|
|
13443
13530
|
const seen = /* @__PURE__ */ new Set();
|
|
13444
|
-
const defaultAppLabel =
|
|
13445
|
-
|
|
13531
|
+
const defaultAppLabel = import_node_path50.default.basename(import_node_path50.default.dirname(file.path));
|
|
13532
|
+
walk5(tree.rootNode, (node) => {
|
|
13446
13533
|
if (node.type !== "class_definition") return;
|
|
13447
13534
|
if (!extendsDjangoModel(node)) return;
|
|
13448
13535
|
const nameNode = node.childForFieldName("name");
|
|
@@ -13454,12 +13541,12 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
13454
13541
|
seen.add(table);
|
|
13455
13542
|
const line = node.startPosition.row + 1;
|
|
13456
13543
|
out.push({
|
|
13457
|
-
infraId: (0,
|
|
13544
|
+
infraId: (0, import_types38.infraId)("sql-table", table),
|
|
13458
13545
|
name: table,
|
|
13459
13546
|
kind: "sql-table",
|
|
13460
13547
|
edgeType: "CALLS",
|
|
13461
13548
|
confidenceKind: "verified-call-site",
|
|
13462
|
-
evidence: { file:
|
|
13549
|
+
evidence: { file: import_node_path50.default.relative(serviceDir, file.path), line, snippet: snippet(file.content, line) }
|
|
13463
13550
|
});
|
|
13464
13551
|
});
|
|
13465
13552
|
return out;
|
|
@@ -13467,18 +13554,18 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
13467
13554
|
|
|
13468
13555
|
// src/extract/calls/drizzle.ts
|
|
13469
13556
|
init_cjs_shims();
|
|
13470
|
-
var
|
|
13471
|
-
var
|
|
13557
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
13558
|
+
var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
|
|
13472
13559
|
var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
|
|
13473
|
-
var
|
|
13560
|
+
var import_types39 = require("@neat.is/types");
|
|
13474
13561
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
13475
13562
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
13476
13563
|
function parserForExt3(ext) {
|
|
13477
|
-
const p = new
|
|
13564
|
+
const p = new import_tree_sitter12.default();
|
|
13478
13565
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript7.default);
|
|
13479
13566
|
return p;
|
|
13480
13567
|
}
|
|
13481
|
-
function
|
|
13568
|
+
function namedChildren5(node) {
|
|
13482
13569
|
const out = [];
|
|
13483
13570
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
13484
13571
|
const c = node.namedChild(i);
|
|
@@ -13488,7 +13575,7 @@ function namedChildren4(node) {
|
|
|
13488
13575
|
}
|
|
13489
13576
|
function stringLiteralText4(node) {
|
|
13490
13577
|
if (!node || node.type !== "string") return null;
|
|
13491
|
-
for (const child of
|
|
13578
|
+
for (const child of namedChildren5(node)) {
|
|
13492
13579
|
if (child.type === "string_fragment") return child.text;
|
|
13493
13580
|
}
|
|
13494
13581
|
return "";
|
|
@@ -13496,7 +13583,7 @@ function stringLiteralText4(node) {
|
|
|
13496
13583
|
function firstStringArg(call) {
|
|
13497
13584
|
const args = call.childForFieldName("arguments");
|
|
13498
13585
|
if (!args) return null;
|
|
13499
|
-
for (const arg of
|
|
13586
|
+
for (const arg of namedChildren5(args)) {
|
|
13500
13587
|
if (arg.type === "string") return stringLiteralText4(arg);
|
|
13501
13588
|
return null;
|
|
13502
13589
|
}
|
|
@@ -13531,7 +13618,7 @@ function keyName2(key) {
|
|
|
13531
13618
|
function columnsFromObject(obj) {
|
|
13532
13619
|
const out = [];
|
|
13533
13620
|
const seen = /* @__PURE__ */ new Set();
|
|
13534
|
-
for (const child of
|
|
13621
|
+
for (const child of namedChildren5(obj)) {
|
|
13535
13622
|
if (child.type !== "pair") continue;
|
|
13536
13623
|
const value = child.childForFieldName("value");
|
|
13537
13624
|
const key = keyName2(child.childForFieldName("key"));
|
|
@@ -13545,15 +13632,15 @@ function columnsFromObject(obj) {
|
|
|
13545
13632
|
}
|
|
13546
13633
|
function drizzleEndpointsFromFile(file, serviceDir) {
|
|
13547
13634
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
13548
|
-
const tree = parseSource3(parserForExt3(
|
|
13635
|
+
const tree = parseSource3(parserForExt3(import_node_path51.default.extname(file.path)), file.content);
|
|
13549
13636
|
const out = [];
|
|
13550
13637
|
const seen = /* @__PURE__ */ new Set();
|
|
13551
|
-
const
|
|
13638
|
+
const walk11 = (node) => {
|
|
13552
13639
|
if (node.type === "call_expression") {
|
|
13553
13640
|
const fn = node.childForFieldName("function");
|
|
13554
13641
|
if (fn?.type === "identifier" && TABLE_BUILDERS.has(fn.text)) {
|
|
13555
13642
|
const args = node.childForFieldName("arguments");
|
|
13556
|
-
const argNodes = args ?
|
|
13643
|
+
const argNodes = args ? namedChildren5(args) : [];
|
|
13557
13644
|
const tableName = stringLiteralText4(argNodes[0] ?? null);
|
|
13558
13645
|
const obj = argNodes[1];
|
|
13559
13646
|
if (tableName && obj?.type === "object" && !seen.has(tableName)) {
|
|
@@ -13561,14 +13648,14 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
13561
13648
|
const columns = columnsFromObject(obj);
|
|
13562
13649
|
const line = node.startPosition.row + 1;
|
|
13563
13650
|
out.push({
|
|
13564
|
-
infraId: (0,
|
|
13651
|
+
infraId: (0, import_types39.infraId)("sql-table", tableName),
|
|
13565
13652
|
name: tableName,
|
|
13566
13653
|
kind: "sql-table",
|
|
13567
13654
|
edgeType: "CALLS",
|
|
13568
13655
|
confidenceKind: "structural",
|
|
13569
13656
|
columns,
|
|
13570
13657
|
evidence: {
|
|
13571
|
-
file:
|
|
13658
|
+
file: import_node_path51.default.relative(serviceDir, file.path),
|
|
13572
13659
|
line,
|
|
13573
13660
|
snippet: snippet(file.content, line)
|
|
13574
13661
|
}
|
|
@@ -13576,9 +13663,9 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
13576
13663
|
}
|
|
13577
13664
|
}
|
|
13578
13665
|
}
|
|
13579
|
-
for (const c of
|
|
13666
|
+
for (const c of namedChildren5(node)) walk11(c);
|
|
13580
13667
|
};
|
|
13581
|
-
|
|
13668
|
+
walk11(tree.rootNode);
|
|
13582
13669
|
return out;
|
|
13583
13670
|
}
|
|
13584
13671
|
function enclosingVarName(call) {
|
|
@@ -13600,12 +13687,12 @@ function enclosingVarName(call) {
|
|
|
13600
13687
|
function collectDrizzleTables(root) {
|
|
13601
13688
|
const tables = [];
|
|
13602
13689
|
const varToTable = /* @__PURE__ */ new Map();
|
|
13603
|
-
const
|
|
13690
|
+
const walk11 = (node) => {
|
|
13604
13691
|
if (node.type === "call_expression") {
|
|
13605
13692
|
const fn = node.childForFieldName("function");
|
|
13606
13693
|
if (fn?.type === "identifier" && TABLE_BUILDERS.has(fn.text)) {
|
|
13607
13694
|
const args = node.childForFieldName("arguments");
|
|
13608
|
-
const argNodes = args ?
|
|
13695
|
+
const argNodes = args ? namedChildren5(args) : [];
|
|
13609
13696
|
const tableName = stringLiteralText4(argNodes[0] ?? null);
|
|
13610
13697
|
const obj = argNodes[1]?.type === "object" ? argNodes[1] : null;
|
|
13611
13698
|
if (tableName) {
|
|
@@ -13615,9 +13702,9 @@ function collectDrizzleTables(root) {
|
|
|
13615
13702
|
}
|
|
13616
13703
|
}
|
|
13617
13704
|
}
|
|
13618
|
-
for (const c of
|
|
13705
|
+
for (const c of namedChildren5(node)) walk11(c);
|
|
13619
13706
|
};
|
|
13620
|
-
|
|
13707
|
+
walk11(root);
|
|
13621
13708
|
return { tables, varToTable };
|
|
13622
13709
|
}
|
|
13623
13710
|
function referencesTargetVar(call) {
|
|
@@ -13625,7 +13712,7 @@ function referencesTargetVar(call) {
|
|
|
13625
13712
|
if (fn?.type !== "member_expression") return null;
|
|
13626
13713
|
if (fn.childForFieldName("property")?.text !== "references") return null;
|
|
13627
13714
|
const args = call.childForFieldName("arguments");
|
|
13628
|
-
const first = args ?
|
|
13715
|
+
const first = args ? namedChildren5(args)[0] ?? null : null;
|
|
13629
13716
|
if (first?.type !== "arrow_function") return null;
|
|
13630
13717
|
const body = first.childForFieldName("body");
|
|
13631
13718
|
if (body?.type !== "member_expression") return null;
|
|
@@ -13634,13 +13721,13 @@ function referencesTargetVar(call) {
|
|
|
13634
13721
|
}
|
|
13635
13722
|
function drizzleForeignKeys(file, serviceDir) {
|
|
13636
13723
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
13637
|
-
const tree = parseSource3(parserForExt3(
|
|
13724
|
+
const tree = parseSource3(parserForExt3(import_node_path51.default.extname(file.path)), file.content);
|
|
13638
13725
|
const { tables, varToTable } = collectDrizzleTables(tree.rootNode);
|
|
13639
13726
|
const out = [];
|
|
13640
13727
|
const seen = /* @__PURE__ */ new Set();
|
|
13641
13728
|
for (const table of tables) {
|
|
13642
13729
|
if (!table.object) continue;
|
|
13643
|
-
const
|
|
13730
|
+
const walk11 = (node) => {
|
|
13644
13731
|
if (node.type === "call_expression") {
|
|
13645
13732
|
const targetVar = referencesTargetVar(node);
|
|
13646
13733
|
const parentTable = targetVar ? varToTable.get(targetVar) : void 0;
|
|
@@ -13653,7 +13740,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13653
13740
|
childTable: table.tableName,
|
|
13654
13741
|
parentTable,
|
|
13655
13742
|
evidence: {
|
|
13656
|
-
file:
|
|
13743
|
+
file: import_node_path51.default.relative(serviceDir, file.path),
|
|
13657
13744
|
line,
|
|
13658
13745
|
snippet: snippet(file.content, line)
|
|
13659
13746
|
}
|
|
@@ -13661,17 +13748,17 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13661
13748
|
}
|
|
13662
13749
|
}
|
|
13663
13750
|
}
|
|
13664
|
-
for (const c of
|
|
13751
|
+
for (const c of namedChildren5(node)) walk11(c);
|
|
13665
13752
|
};
|
|
13666
|
-
|
|
13753
|
+
walk11(table.object);
|
|
13667
13754
|
}
|
|
13668
13755
|
return out;
|
|
13669
13756
|
}
|
|
13670
13757
|
|
|
13671
13758
|
// src/extract/calls/prisma.ts
|
|
13672
13759
|
init_cjs_shims();
|
|
13673
|
-
var
|
|
13674
|
-
var
|
|
13760
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
13761
|
+
var import_types40 = require("@neat.is/types");
|
|
13675
13762
|
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
13676
13763
|
"Int",
|
|
13677
13764
|
"String",
|
|
@@ -13719,14 +13806,14 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13719
13806
|
if (seenTable.has(b.tableName)) return;
|
|
13720
13807
|
seenTable.add(b.tableName);
|
|
13721
13808
|
out.push({
|
|
13722
|
-
infraId: (0,
|
|
13809
|
+
infraId: (0, import_types40.infraId)("sql-table", b.tableName),
|
|
13723
13810
|
name: b.tableName,
|
|
13724
13811
|
kind: "sql-table",
|
|
13725
13812
|
edgeType: "CALLS",
|
|
13726
13813
|
confidenceKind: "structural",
|
|
13727
13814
|
columns: b.columns,
|
|
13728
13815
|
evidence: {
|
|
13729
|
-
file:
|
|
13816
|
+
file: import_node_path52.default.relative(serviceDir, file.path),
|
|
13730
13817
|
line: b.startLine,
|
|
13731
13818
|
snippet: snippet(content, b.startLine)
|
|
13732
13819
|
}
|
|
@@ -13787,7 +13874,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13787
13874
|
}
|
|
13788
13875
|
async function prismaColumnEndpoints(serviceDir) {
|
|
13789
13876
|
const schemaPath = await findFirst(serviceDir, [
|
|
13790
|
-
|
|
13877
|
+
import_node_path52.default.join("prisma", "schema.prisma"),
|
|
13791
13878
|
"schema.prisma"
|
|
13792
13879
|
]);
|
|
13793
13880
|
if (!schemaPath) return [];
|
|
@@ -13862,7 +13949,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
|
|
|
13862
13949
|
childTable: current.table,
|
|
13863
13950
|
parentTable,
|
|
13864
13951
|
evidence: {
|
|
13865
|
-
file:
|
|
13952
|
+
file: import_node_path52.default.relative(serviceDir, file.path),
|
|
13866
13953
|
line: lineNo,
|
|
13867
13954
|
snippet: snippet(content, lineNo)
|
|
13868
13955
|
}
|
|
@@ -13877,7 +13964,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
|
|
|
13877
13964
|
}
|
|
13878
13965
|
async function prismaForeignKeys(serviceDir) {
|
|
13879
13966
|
const schemaPath = await findFirst(serviceDir, [
|
|
13880
|
-
|
|
13967
|
+
import_node_path52.default.join("prisma", "schema.prisma"),
|
|
13881
13968
|
"schema.prisma"
|
|
13882
13969
|
]);
|
|
13883
13970
|
if (!schemaPath) return [];
|
|
@@ -13888,27 +13975,27 @@ async function prismaForeignKeys(serviceDir) {
|
|
|
13888
13975
|
|
|
13889
13976
|
// src/extract/calls/activerecord.ts
|
|
13890
13977
|
init_cjs_shims();
|
|
13891
|
-
var
|
|
13892
|
-
var
|
|
13978
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
13979
|
+
var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
|
|
13893
13980
|
var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
|
|
13894
|
-
var
|
|
13981
|
+
var import_types41 = require("@neat.is/types");
|
|
13895
13982
|
var AR_SCHEMA_RE = /ActiveRecord::Schema/;
|
|
13896
|
-
var
|
|
13983
|
+
var PARSE_CHUNK9 = 16384;
|
|
13897
13984
|
function makeRubyParser2() {
|
|
13898
|
-
const p = new
|
|
13985
|
+
const p = new import_tree_sitter13.default();
|
|
13899
13986
|
p.setLanguage(import_tree_sitter_ruby3.default);
|
|
13900
13987
|
return p;
|
|
13901
13988
|
}
|
|
13902
|
-
function
|
|
13989
|
+
function parseSource9(parser, source) {
|
|
13903
13990
|
return parser.parse(
|
|
13904
|
-
(index) => index >= source.length ? "" : source.slice(index, index +
|
|
13991
|
+
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK9)
|
|
13905
13992
|
);
|
|
13906
13993
|
}
|
|
13907
|
-
function
|
|
13994
|
+
function walk6(node, visit) {
|
|
13908
13995
|
visit(node);
|
|
13909
13996
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
13910
13997
|
const c = node.namedChild(i);
|
|
13911
|
-
if (c)
|
|
13998
|
+
if (c) walk6(c, visit);
|
|
13912
13999
|
}
|
|
13913
14000
|
}
|
|
13914
14001
|
function rubyLiteral2(node) {
|
|
@@ -14079,24 +14166,24 @@ function readCreateTable(call) {
|
|
|
14079
14166
|
}
|
|
14080
14167
|
function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
14081
14168
|
if (!AR_SCHEMA_RE.test(file.content)) return [];
|
|
14082
|
-
const tree =
|
|
14169
|
+
const tree = parseSource9(makeRubyParser2(), file.content);
|
|
14083
14170
|
const out = [];
|
|
14084
14171
|
const seen = /* @__PURE__ */ new Set();
|
|
14085
|
-
|
|
14172
|
+
walk6(tree.rootNode, (node) => {
|
|
14086
14173
|
if (node.type !== "call") return;
|
|
14087
14174
|
if (blockCallMethod(node) !== "create_table") return;
|
|
14088
14175
|
const table = readCreateTable(node);
|
|
14089
14176
|
if (!table || seen.has(table.name)) return;
|
|
14090
14177
|
seen.add(table.name);
|
|
14091
14178
|
out.push({
|
|
14092
|
-
infraId: (0,
|
|
14179
|
+
infraId: (0, import_types41.infraId)("sql-table", table.name),
|
|
14093
14180
|
name: table.name,
|
|
14094
14181
|
kind: "sql-table",
|
|
14095
14182
|
edgeType: "CALLS",
|
|
14096
14183
|
confidenceKind: "structural",
|
|
14097
14184
|
...table.columns.length > 0 ? { columns: table.columns } : {},
|
|
14098
14185
|
evidence: {
|
|
14099
|
-
file:
|
|
14186
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
14100
14187
|
line: table.line,
|
|
14101
14188
|
snippet: snippet(file.content, table.line)
|
|
14102
14189
|
}
|
|
@@ -14106,7 +14193,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
|
14106
14193
|
}
|
|
14107
14194
|
function railsSchemaForeignKeys(file, serviceDir) {
|
|
14108
14195
|
if (!AR_SCHEMA_RE.test(file.content)) return [];
|
|
14109
|
-
const tree =
|
|
14196
|
+
const tree = parseSource9(makeRubyParser2(), file.content);
|
|
14110
14197
|
const out = [];
|
|
14111
14198
|
const seen = /* @__PURE__ */ new Set();
|
|
14112
14199
|
const emit = (childTable, parentTable, line) => {
|
|
@@ -14118,13 +14205,13 @@ function railsSchemaForeignKeys(file, serviceDir) {
|
|
|
14118
14205
|
childTable,
|
|
14119
14206
|
parentTable,
|
|
14120
14207
|
evidence: {
|
|
14121
|
-
file:
|
|
14208
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
14122
14209
|
line,
|
|
14123
14210
|
snippet: snippet(file.content, line)
|
|
14124
14211
|
}
|
|
14125
14212
|
});
|
|
14126
14213
|
};
|
|
14127
|
-
|
|
14214
|
+
walk6(tree.rootNode, (node) => {
|
|
14128
14215
|
if (node.type !== "call") return;
|
|
14129
14216
|
const method = blockCallMethod(node);
|
|
14130
14217
|
if (method === "add_foreign_key") {
|
|
@@ -14185,23 +14272,23 @@ function modelTable(cls) {
|
|
|
14185
14272
|
return tableize(nameNode.text);
|
|
14186
14273
|
}
|
|
14187
14274
|
function railsModelEndpointsFromFile(file, serviceDir) {
|
|
14188
|
-
const tree =
|
|
14275
|
+
const tree = parseSource9(makeRubyParser2(), file.content);
|
|
14189
14276
|
const out = [];
|
|
14190
14277
|
const seen = /* @__PURE__ */ new Set();
|
|
14191
|
-
|
|
14278
|
+
walk6(tree.rootNode, (node) => {
|
|
14192
14279
|
if (node.type !== "class" || !isActiveRecordModel(node)) return;
|
|
14193
14280
|
const table = modelTable(node);
|
|
14194
14281
|
if (!table || seen.has(table)) return;
|
|
14195
14282
|
seen.add(table);
|
|
14196
14283
|
const line = node.startPosition.row + 1;
|
|
14197
14284
|
out.push({
|
|
14198
|
-
infraId: (0,
|
|
14285
|
+
infraId: (0, import_types41.infraId)("sql-table", table),
|
|
14199
14286
|
name: table,
|
|
14200
14287
|
kind: "sql-table",
|
|
14201
14288
|
edgeType: "CALLS",
|
|
14202
14289
|
confidenceKind: "verified-call-site",
|
|
14203
14290
|
evidence: {
|
|
14204
|
-
file:
|
|
14291
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
14205
14292
|
line,
|
|
14206
14293
|
snippet: snippet(file.content, line)
|
|
14207
14294
|
}
|
|
@@ -14211,10 +14298,10 @@ function railsModelEndpointsFromFile(file, serviceDir) {
|
|
|
14211
14298
|
}
|
|
14212
14299
|
var AR_ASSOCIATIONS = /* @__PURE__ */ new Set(["belongs_to", "has_many", "has_one"]);
|
|
14213
14300
|
function railsModelForeignKeys(file, serviceDir) {
|
|
14214
|
-
const tree =
|
|
14301
|
+
const tree = parseSource9(makeRubyParser2(), file.content);
|
|
14215
14302
|
const out = [];
|
|
14216
14303
|
const seen = /* @__PURE__ */ new Set();
|
|
14217
|
-
|
|
14304
|
+
walk6(tree.rootNode, (node) => {
|
|
14218
14305
|
if (node.type !== "class" || !isActiveRecordModel(node)) return;
|
|
14219
14306
|
const thisTable = modelTable(node);
|
|
14220
14307
|
if (!thisTable) return;
|
|
@@ -14238,7 +14325,7 @@ function railsModelForeignKeys(file, serviceDir) {
|
|
|
14238
14325
|
childTable,
|
|
14239
14326
|
parentTable,
|
|
14240
14327
|
evidence: {
|
|
14241
|
-
file:
|
|
14328
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
14242
14329
|
line,
|
|
14243
14330
|
snippet: snippet(file.content, line)
|
|
14244
14331
|
}
|
|
@@ -14250,27 +14337,27 @@ function railsModelForeignKeys(file, serviceDir) {
|
|
|
14250
14337
|
|
|
14251
14338
|
// src/extract/calls/eloquent.ts
|
|
14252
14339
|
init_cjs_shims();
|
|
14253
|
-
var
|
|
14254
|
-
var
|
|
14340
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
14341
|
+
var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
|
|
14255
14342
|
var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
|
|
14256
|
-
var
|
|
14343
|
+
var import_types42 = require("@neat.is/types");
|
|
14257
14344
|
var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
|
|
14258
|
-
var
|
|
14345
|
+
var PARSE_CHUNK10 = 16384;
|
|
14259
14346
|
function makePhpParser2() {
|
|
14260
|
-
const p = new
|
|
14347
|
+
const p = new import_tree_sitter14.default();
|
|
14261
14348
|
p.setLanguage(import_tree_sitter_php3.default.php_only);
|
|
14262
14349
|
return p;
|
|
14263
14350
|
}
|
|
14264
|
-
function
|
|
14351
|
+
function parseSource10(parser, source) {
|
|
14265
14352
|
return parser.parse(
|
|
14266
|
-
(index) => index >= source.length ? "" : source.slice(index, index +
|
|
14353
|
+
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK10)
|
|
14267
14354
|
);
|
|
14268
14355
|
}
|
|
14269
|
-
function
|
|
14356
|
+
function walk7(node, visit) {
|
|
14270
14357
|
visit(node);
|
|
14271
14358
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
14272
14359
|
const c = node.namedChild(i);
|
|
14273
|
-
if (c)
|
|
14360
|
+
if (c) walk7(c, visit);
|
|
14274
14361
|
}
|
|
14275
14362
|
}
|
|
14276
14363
|
function phpStaticString2(node) {
|
|
@@ -14481,9 +14568,9 @@ function columnsFromCall(chain, blueprintVar) {
|
|
|
14481
14568
|
}
|
|
14482
14569
|
function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
14483
14570
|
if (!LARAVEL_SCHEMA_RE.test(file.content)) return [];
|
|
14484
|
-
const tree =
|
|
14571
|
+
const tree = parseSource10(makePhpParser2(), file.content);
|
|
14485
14572
|
const out = [];
|
|
14486
|
-
|
|
14573
|
+
walk7(tree.rootNode, (node) => {
|
|
14487
14574
|
if (!isSchemaCall(node)) return;
|
|
14488
14575
|
const bp = readBlueprint(node);
|
|
14489
14576
|
if (!bp) return;
|
|
@@ -14500,14 +14587,14 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
14500
14587
|
}
|
|
14501
14588
|
}
|
|
14502
14589
|
out.push({
|
|
14503
|
-
infraId: (0,
|
|
14590
|
+
infraId: (0, import_types42.infraId)("sql-table", bp.table),
|
|
14504
14591
|
name: bp.table,
|
|
14505
14592
|
kind: "sql-table",
|
|
14506
14593
|
edgeType: "CALLS",
|
|
14507
14594
|
confidenceKind: "structural",
|
|
14508
14595
|
...columns.length > 0 ? { columns } : {},
|
|
14509
14596
|
evidence: {
|
|
14510
|
-
file:
|
|
14597
|
+
file: import_node_path54.default.relative(serviceDir, file.path),
|
|
14511
14598
|
line: bp.line,
|
|
14512
14599
|
snippet: snippet(file.content, bp.line)
|
|
14513
14600
|
}
|
|
@@ -14517,7 +14604,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
14517
14604
|
}
|
|
14518
14605
|
function laravelMigrationForeignKeys(file, serviceDir) {
|
|
14519
14606
|
if (!LARAVEL_SCHEMA_RE.test(file.content)) return [];
|
|
14520
|
-
const tree =
|
|
14607
|
+
const tree = parseSource10(makePhpParser2(), file.content);
|
|
14521
14608
|
const out = [];
|
|
14522
14609
|
const seen = /* @__PURE__ */ new Set();
|
|
14523
14610
|
const emit = (childTable, parentTable, line) => {
|
|
@@ -14529,13 +14616,13 @@ function laravelMigrationForeignKeys(file, serviceDir) {
|
|
|
14529
14616
|
childTable,
|
|
14530
14617
|
parentTable,
|
|
14531
14618
|
evidence: {
|
|
14532
|
-
file:
|
|
14619
|
+
file: import_node_path54.default.relative(serviceDir, file.path),
|
|
14533
14620
|
line,
|
|
14534
14621
|
snippet: snippet(file.content, line)
|
|
14535
14622
|
}
|
|
14536
14623
|
});
|
|
14537
14624
|
};
|
|
14538
|
-
|
|
14625
|
+
walk7(tree.rootNode, (node) => {
|
|
14539
14626
|
if (!isSchemaCall(node)) return;
|
|
14540
14627
|
const bp = readBlueprint(node);
|
|
14541
14628
|
if (!bp || !bp.closureBody) return;
|
|
@@ -14633,23 +14720,23 @@ function walkWithinClass(cls, visit) {
|
|
|
14633
14720
|
recur(body);
|
|
14634
14721
|
}
|
|
14635
14722
|
function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
14636
|
-
const tree =
|
|
14723
|
+
const tree = parseSource10(makePhpParser2(), file.content);
|
|
14637
14724
|
const out = [];
|
|
14638
14725
|
const seen = /* @__PURE__ */ new Set();
|
|
14639
|
-
|
|
14726
|
+
walk7(tree.rootNode, (node) => {
|
|
14640
14727
|
if (node.type !== "class_declaration" || !isEloquentModel(node)) return;
|
|
14641
14728
|
const table = modelTable2(node);
|
|
14642
14729
|
if (!table || seen.has(table)) return;
|
|
14643
14730
|
seen.add(table);
|
|
14644
14731
|
const line = node.startPosition.row + 1;
|
|
14645
14732
|
out.push({
|
|
14646
|
-
infraId: (0,
|
|
14733
|
+
infraId: (0, import_types42.infraId)("sql-table", table),
|
|
14647
14734
|
name: table,
|
|
14648
14735
|
kind: "sql-table",
|
|
14649
14736
|
edgeType: "CALLS",
|
|
14650
14737
|
confidenceKind: "verified-call-site",
|
|
14651
14738
|
evidence: {
|
|
14652
|
-
file:
|
|
14739
|
+
file: import_node_path54.default.relative(serviceDir, file.path),
|
|
14653
14740
|
line,
|
|
14654
14741
|
snippet: snippet(file.content, line)
|
|
14655
14742
|
}
|
|
@@ -14659,10 +14746,10 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
|
14659
14746
|
}
|
|
14660
14747
|
var ELOQUENT_RELATIONS = /* @__PURE__ */ new Set(["belongsTo", "hasMany", "hasOne"]);
|
|
14661
14748
|
function laravelModelForeignKeys(file, serviceDir) {
|
|
14662
|
-
const tree =
|
|
14749
|
+
const tree = parseSource10(makePhpParser2(), file.content);
|
|
14663
14750
|
const out = [];
|
|
14664
14751
|
const seen = /* @__PURE__ */ new Set();
|
|
14665
|
-
|
|
14752
|
+
walk7(tree.rootNode, (node) => {
|
|
14666
14753
|
if (node.type !== "class_declaration" || !isEloquentModel(node)) return;
|
|
14667
14754
|
const thisTable = modelTable2(node);
|
|
14668
14755
|
if (!thisTable) return;
|
|
@@ -14685,7 +14772,7 @@ function laravelModelForeignKeys(file, serviceDir) {
|
|
|
14685
14772
|
childTable,
|
|
14686
14773
|
parentTable,
|
|
14687
14774
|
evidence: {
|
|
14688
|
-
file:
|
|
14775
|
+
file: import_node_path54.default.relative(serviceDir, file.path),
|
|
14689
14776
|
line,
|
|
14690
14777
|
snippet: snippet(file.content, line)
|
|
14691
14778
|
}
|
|
@@ -14697,12 +14784,12 @@ function laravelModelForeignKeys(file, serviceDir) {
|
|
|
14697
14784
|
|
|
14698
14785
|
// src/extract/calls/go.ts
|
|
14699
14786
|
init_cjs_shims();
|
|
14700
|
-
var
|
|
14701
|
-
var
|
|
14787
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
14788
|
+
var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
|
|
14702
14789
|
var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
|
|
14703
|
-
var
|
|
14790
|
+
var import_types43 = require("@neat.is/types");
|
|
14704
14791
|
init_otel();
|
|
14705
|
-
var
|
|
14792
|
+
var PARSE_CHUNK11 = 16384;
|
|
14706
14793
|
var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
|
|
14707
14794
|
"Query",
|
|
14708
14795
|
"QueryContext",
|
|
@@ -14728,20 +14815,20 @@ var SQLX_METHODS = /* @__PURE__ */ new Set([
|
|
|
14728
14815
|
var DATABASE_SQL_IMPORT = "database/sql";
|
|
14729
14816
|
var SQLX_IMPORT = "github.com/jmoiron/sqlx";
|
|
14730
14817
|
function makeGoParser3() {
|
|
14731
|
-
const p = new
|
|
14818
|
+
const p = new import_tree_sitter15.default();
|
|
14732
14819
|
p.setLanguage(import_tree_sitter_go4.default);
|
|
14733
14820
|
return p;
|
|
14734
14821
|
}
|
|
14735
|
-
function
|
|
14822
|
+
function parseSource11(parser, source) {
|
|
14736
14823
|
return parser.parse(
|
|
14737
|
-
(index) => index >= source.length ? "" : source.slice(index, index +
|
|
14824
|
+
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK11)
|
|
14738
14825
|
);
|
|
14739
14826
|
}
|
|
14740
|
-
function
|
|
14827
|
+
function walk8(node, visit) {
|
|
14741
14828
|
visit(node);
|
|
14742
14829
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
14743
14830
|
const child = node.namedChild(i);
|
|
14744
|
-
if (child)
|
|
14831
|
+
if (child) walk8(child, visit);
|
|
14745
14832
|
}
|
|
14746
14833
|
}
|
|
14747
14834
|
function goStringLiteralValue(node) {
|
|
@@ -14754,7 +14841,7 @@ function goStringLiteralValue(node) {
|
|
|
14754
14841
|
}
|
|
14755
14842
|
function goImportsAny(root, names) {
|
|
14756
14843
|
let found = false;
|
|
14757
|
-
|
|
14844
|
+
walk8(root, (node) => {
|
|
14758
14845
|
if (found || node.type !== "import_spec") return;
|
|
14759
14846
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
14760
14847
|
const value = goStringLiteralValue(node.namedChild(i));
|
|
@@ -14772,14 +14859,14 @@ function firstStringLiteralArg(argsNode) {
|
|
|
14772
14859
|
return null;
|
|
14773
14860
|
}
|
|
14774
14861
|
function goSqlEndpointsFromFile(file, serviceDir) {
|
|
14775
|
-
if (
|
|
14862
|
+
if (import_node_path57.default.extname(file.path) !== ".go") return [];
|
|
14776
14863
|
if (!file.content.includes(DATABASE_SQL_IMPORT) && !file.content.includes(SQLX_IMPORT)) return [];
|
|
14777
|
-
const tree =
|
|
14864
|
+
const tree = parseSource11(makeGoParser3(), file.content);
|
|
14778
14865
|
const importsDatabaseSql = goImportsAny(tree.rootNode, /* @__PURE__ */ new Set([DATABASE_SQL_IMPORT]));
|
|
14779
14866
|
const importsSqlx = goImportsAny(tree.rootNode, /* @__PURE__ */ new Set([SQLX_IMPORT]));
|
|
14780
14867
|
if (!importsDatabaseSql && !importsSqlx) return [];
|
|
14781
14868
|
const out = [];
|
|
14782
|
-
|
|
14869
|
+
walk8(tree.rootNode, (node) => {
|
|
14783
14870
|
if (node.type !== "call_expression") return;
|
|
14784
14871
|
const fn = node.childForFieldName("function");
|
|
14785
14872
|
if (fn?.type !== "selector_expression") return;
|
|
@@ -14794,14 +14881,14 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14794
14881
|
const columns = columnsFromSqlStatement(sql);
|
|
14795
14882
|
const line = node.startPosition.row + 1;
|
|
14796
14883
|
out.push({
|
|
14797
|
-
infraId: (0,
|
|
14884
|
+
infraId: (0, import_types43.infraId)("sql-table", table),
|
|
14798
14885
|
name: table,
|
|
14799
14886
|
kind: "sql-table",
|
|
14800
14887
|
edgeType: "CALLS",
|
|
14801
14888
|
confidenceKind: "verified-call-site",
|
|
14802
14889
|
...columns.length > 0 ? { columns } : {},
|
|
14803
14890
|
evidence: {
|
|
14804
|
-
file: toPosix(
|
|
14891
|
+
file: toPosix(import_node_path57.default.relative(serviceDir, file.path)),
|
|
14805
14892
|
line,
|
|
14806
14893
|
snippet: snippet(file.content, line)
|
|
14807
14894
|
}
|
|
@@ -14812,27 +14899,27 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14812
14899
|
|
|
14813
14900
|
// src/extract/calls/gorm.ts
|
|
14814
14901
|
init_cjs_shims();
|
|
14815
|
-
var
|
|
14816
|
-
var
|
|
14902
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
14903
|
+
var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
|
|
14817
14904
|
var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
|
|
14818
|
-
var
|
|
14905
|
+
var import_types44 = require("@neat.is/types");
|
|
14819
14906
|
var GORM_IMPORT_RE = /gorm\.io\/gorm/;
|
|
14820
|
-
var
|
|
14907
|
+
var PARSE_CHUNK12 = 16384;
|
|
14821
14908
|
function makeGoParser4() {
|
|
14822
|
-
const p = new
|
|
14909
|
+
const p = new import_tree_sitter16.default();
|
|
14823
14910
|
p.setLanguage(import_tree_sitter_go5.default);
|
|
14824
14911
|
return p;
|
|
14825
14912
|
}
|
|
14826
|
-
function
|
|
14913
|
+
function parseSource12(parser, source) {
|
|
14827
14914
|
return parser.parse(
|
|
14828
|
-
(index) => index >= source.length ? "" : source.slice(index, index +
|
|
14915
|
+
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK12)
|
|
14829
14916
|
);
|
|
14830
14917
|
}
|
|
14831
|
-
function
|
|
14918
|
+
function walk9(node, visit) {
|
|
14832
14919
|
visit(node);
|
|
14833
14920
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
14834
14921
|
const c = node.namedChild(i);
|
|
14835
|
-
if (c)
|
|
14922
|
+
if (c) walk9(c, visit);
|
|
14836
14923
|
}
|
|
14837
14924
|
}
|
|
14838
14925
|
var COMMON_INITIALISMS = [
|
|
@@ -15065,7 +15152,7 @@ function readField(fieldDecl) {
|
|
|
15065
15152
|
}
|
|
15066
15153
|
function collectStructs(tree) {
|
|
15067
15154
|
const structs = /* @__PURE__ */ new Map();
|
|
15068
|
-
|
|
15155
|
+
walk9(tree.rootNode, (node) => {
|
|
15069
15156
|
if (node.type !== "type_spec") return;
|
|
15070
15157
|
const nameNode = node.childForFieldName("name");
|
|
15071
15158
|
const typeNode = node.childForFieldName("type");
|
|
@@ -15114,7 +15201,7 @@ function compositeStructName(arg) {
|
|
|
15114
15201
|
}
|
|
15115
15202
|
function collectCallModels(tree) {
|
|
15116
15203
|
const models = /* @__PURE__ */ new Set();
|
|
15117
|
-
|
|
15204
|
+
walk9(tree.rootNode, (node) => {
|
|
15118
15205
|
if (node.type !== "call_expression") return;
|
|
15119
15206
|
const fn = node.childForFieldName("function");
|
|
15120
15207
|
if (fn?.type !== "selector_expression") return;
|
|
@@ -15134,7 +15221,7 @@ function collectCallModels(tree) {
|
|
|
15134
15221
|
function collectTableNameOverrides(tree) {
|
|
15135
15222
|
const overrides = /* @__PURE__ */ new Map();
|
|
15136
15223
|
const declarers = /* @__PURE__ */ new Set();
|
|
15137
|
-
|
|
15224
|
+
walk9(tree.rootNode, (node) => {
|
|
15138
15225
|
if (node.type !== "method_declaration") return;
|
|
15139
15226
|
if (node.childForFieldName("name")?.text !== "TableName") return;
|
|
15140
15227
|
const receiver = node.childForFieldName("receiver");
|
|
@@ -15151,7 +15238,7 @@ function collectTableNameOverrides(tree) {
|
|
|
15151
15238
|
const body = node.childForFieldName("body");
|
|
15152
15239
|
if (!body) return;
|
|
15153
15240
|
let literal = null;
|
|
15154
|
-
|
|
15241
|
+
walk9(body, (n) => {
|
|
15155
15242
|
if (literal !== null) return;
|
|
15156
15243
|
if (n.type !== "return_statement") return;
|
|
15157
15244
|
const exprList = n.namedChild(0);
|
|
@@ -15245,9 +15332,9 @@ function collectColumns(struct, structs, seen, prefix, out, emitted) {
|
|
|
15245
15332
|
seen.delete(struct.name);
|
|
15246
15333
|
}
|
|
15247
15334
|
function gormEndpointsFromFile(file, serviceDir) {
|
|
15248
|
-
if (
|
|
15335
|
+
if (import_node_path58.default.extname(file.path) !== ".go") return [];
|
|
15249
15336
|
if (!GORM_IMPORT_RE.test(file.content)) return [];
|
|
15250
|
-
const tree =
|
|
15337
|
+
const tree = parseSource12(makeGoParser4(), file.content);
|
|
15251
15338
|
const { structs, models, tableFor } = analyze(tree);
|
|
15252
15339
|
const out = [];
|
|
15253
15340
|
const seenTables = /* @__PURE__ */ new Set();
|
|
@@ -15260,14 +15347,14 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
15260
15347
|
const columns = [];
|
|
15261
15348
|
collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
|
|
15262
15349
|
out.push({
|
|
15263
|
-
infraId: (0,
|
|
15350
|
+
infraId: (0, import_types44.infraId)("sql-table", table),
|
|
15264
15351
|
name: table,
|
|
15265
15352
|
kind: "sql-table",
|
|
15266
15353
|
edgeType: "CALLS",
|
|
15267
15354
|
confidenceKind: "structural",
|
|
15268
15355
|
...columns.length > 0 ? { columns } : {},
|
|
15269
15356
|
evidence: {
|
|
15270
|
-
file: toPosix(
|
|
15357
|
+
file: toPosix(import_node_path58.default.relative(serviceDir, file.path)),
|
|
15271
15358
|
line: struct.line,
|
|
15272
15359
|
snippet: snippet(file.content, struct.line)
|
|
15273
15360
|
}
|
|
@@ -15276,9 +15363,9 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
15276
15363
|
return out;
|
|
15277
15364
|
}
|
|
15278
15365
|
function gormForeignKeys(file, serviceDir) {
|
|
15279
|
-
if (
|
|
15366
|
+
if (import_node_path58.default.extname(file.path) !== ".go") return [];
|
|
15280
15367
|
if (!GORM_IMPORT_RE.test(file.content)) return [];
|
|
15281
|
-
const tree =
|
|
15368
|
+
const tree = parseSource12(makeGoParser4(), file.content);
|
|
15282
15369
|
const { structs, models, tableFor } = analyze(tree);
|
|
15283
15370
|
const out = [];
|
|
15284
15371
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -15291,7 +15378,7 @@ function gormForeignKeys(file, serviceDir) {
|
|
|
15291
15378
|
childTable,
|
|
15292
15379
|
parentTable,
|
|
15293
15380
|
evidence: {
|
|
15294
|
-
file: toPosix(
|
|
15381
|
+
file: toPosix(import_node_path58.default.relative(serviceDir, file.path)),
|
|
15295
15382
|
line,
|
|
15296
15383
|
snippet: snippet(file.content, line)
|
|
15297
15384
|
}
|
|
@@ -15328,27 +15415,27 @@ function gormForeignKeys(file, serviceDir) {
|
|
|
15328
15415
|
|
|
15329
15416
|
// src/extract/calls/efcore.ts
|
|
15330
15417
|
init_cjs_shims();
|
|
15331
|
-
var
|
|
15332
|
-
var
|
|
15418
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
15419
|
+
var import_tree_sitter17 = __toESM(require("tree-sitter"), 1);
|
|
15333
15420
|
var import_tree_sitter_c_sharp2 = __toESM(require("tree-sitter-c-sharp"), 1);
|
|
15334
|
-
var
|
|
15421
|
+
var import_types45 = require("@neat.is/types");
|
|
15335
15422
|
var EFCORE_GATE = /Microsoft\.EntityFrameworkCore|DataAnnotations\.Schema|\bDbContext\b|\bDbSet\s*</;
|
|
15336
|
-
var
|
|
15423
|
+
var PARSE_CHUNK13 = 16384;
|
|
15337
15424
|
function makeCsParser() {
|
|
15338
|
-
const p = new
|
|
15425
|
+
const p = new import_tree_sitter17.default();
|
|
15339
15426
|
p.setLanguage(import_tree_sitter_c_sharp2.default);
|
|
15340
15427
|
return p;
|
|
15341
15428
|
}
|
|
15342
|
-
function
|
|
15429
|
+
function parseSource13(parser, source) {
|
|
15343
15430
|
return parser.parse(
|
|
15344
|
-
(index) => index >= source.length ? "" : source.slice(index, index +
|
|
15431
|
+
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK13)
|
|
15345
15432
|
);
|
|
15346
15433
|
}
|
|
15347
|
-
function
|
|
15434
|
+
function walk10(node, visit) {
|
|
15348
15435
|
visit(node);
|
|
15349
15436
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
15350
15437
|
const c = node.namedChild(i);
|
|
15351
|
-
if (c)
|
|
15438
|
+
if (c) walk10(c, visit);
|
|
15352
15439
|
}
|
|
15353
15440
|
}
|
|
15354
15441
|
function firstChildOfType(node, type) {
|
|
@@ -15407,28 +15494,28 @@ function tableFromToTable(call) {
|
|
|
15407
15494
|
return value ? csStringLiteral(value) : null;
|
|
15408
15495
|
}
|
|
15409
15496
|
function efcoreEndpointsFromFile(file, serviceDir) {
|
|
15410
|
-
if (
|
|
15497
|
+
if (import_node_path59.default.extname(file.path) !== ".cs") return [];
|
|
15411
15498
|
if (!EFCORE_GATE.test(file.content)) return [];
|
|
15412
|
-
const tree =
|
|
15499
|
+
const tree = parseSource13(makeCsParser(), file.content);
|
|
15413
15500
|
const out = [];
|
|
15414
15501
|
const seen = /* @__PURE__ */ new Set();
|
|
15415
15502
|
const push = (name, line) => {
|
|
15416
15503
|
if (!name || seen.has(name)) return;
|
|
15417
15504
|
seen.add(name);
|
|
15418
15505
|
out.push({
|
|
15419
|
-
infraId: (0,
|
|
15506
|
+
infraId: (0, import_types45.infraId)("sql-table", name),
|
|
15420
15507
|
name,
|
|
15421
15508
|
kind: "sql-table",
|
|
15422
15509
|
edgeType: "CALLS",
|
|
15423
15510
|
confidenceKind: "structural",
|
|
15424
15511
|
evidence: {
|
|
15425
|
-
file: toPosix(
|
|
15512
|
+
file: toPosix(import_node_path59.default.relative(serviceDir, file.path)),
|
|
15426
15513
|
line,
|
|
15427
15514
|
snippet: snippet(file.content, line)
|
|
15428
15515
|
}
|
|
15429
15516
|
});
|
|
15430
15517
|
};
|
|
15431
|
-
|
|
15518
|
+
walk10(tree.rootNode, (node) => {
|
|
15432
15519
|
if (node.type === "attribute") {
|
|
15433
15520
|
const table = tableFromAttribute(node);
|
|
15434
15521
|
if (table) push(table, node.startPosition.row + 1);
|
|
@@ -15446,11 +15533,11 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
15446
15533
|
function edgeTypeFromEndpoint(ep) {
|
|
15447
15534
|
switch (ep.edgeType) {
|
|
15448
15535
|
case "PUBLISHES_TO":
|
|
15449
|
-
return
|
|
15536
|
+
return import_types46.EdgeType.PUBLISHES_TO;
|
|
15450
15537
|
case "CONSUMES_FROM":
|
|
15451
|
-
return
|
|
15538
|
+
return import_types46.EdgeType.CONSUMES_FROM;
|
|
15452
15539
|
default:
|
|
15453
|
-
return
|
|
15540
|
+
return import_types46.EdgeType.CALLS;
|
|
15454
15541
|
}
|
|
15455
15542
|
}
|
|
15456
15543
|
function isAwsKind(kind) {
|
|
@@ -15505,6 +15592,11 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15505
15592
|
} catch (err) {
|
|
15506
15593
|
recordExtractionError("efcore data-axis extraction", file.path, err);
|
|
15507
15594
|
}
|
|
15595
|
+
try {
|
|
15596
|
+
endpoints.push(...socketEndpointsFromFile(file, service.dir));
|
|
15597
|
+
} catch (err) {
|
|
15598
|
+
recordExtractionError("python socket call extraction", file.path, err);
|
|
15599
|
+
}
|
|
15508
15600
|
}
|
|
15509
15601
|
endpoints.push(...await mongooseCrossFileEndpoints(maskedFiles, service.dir));
|
|
15510
15602
|
endpoints.push(...pythonOrmCrossFileEndpoints(maskedFiles, service.dir));
|
|
@@ -15515,7 +15607,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15515
15607
|
if (!graph.hasNode(ep.infraId)) {
|
|
15516
15608
|
const node = {
|
|
15517
15609
|
id: ep.infraId,
|
|
15518
|
-
type:
|
|
15610
|
+
type: import_types46.NodeType.InfraNode,
|
|
15519
15611
|
name: ep.name,
|
|
15520
15612
|
// #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
|
|
15521
15613
|
// aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
|
|
@@ -15528,21 +15620,21 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15528
15620
|
}
|
|
15529
15621
|
if (ep.columns && ep.columns.length > 0) {
|
|
15530
15622
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15531
|
-
if (node.type ===
|
|
15623
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15532
15624
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15533
15625
|
...node,
|
|
15534
15626
|
columns: foldColumns(
|
|
15535
15627
|
node.columns,
|
|
15536
15628
|
ep.columns,
|
|
15537
|
-
|
|
15538
|
-
(0,
|
|
15629
|
+
import_types46.Provenance.EXTRACTED,
|
|
15630
|
+
(0, import_types46.confidenceForExtracted)(ep.confidenceKind)
|
|
15539
15631
|
)
|
|
15540
15632
|
});
|
|
15541
15633
|
}
|
|
15542
15634
|
}
|
|
15543
15635
|
if (ep.sdkWrites && Object.keys(ep.sdkWrites).length > 0) {
|
|
15544
15636
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15545
|
-
if (node.type ===
|
|
15637
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15546
15638
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15547
15639
|
...node,
|
|
15548
15640
|
columns: foldSdkWrites(node.columns, ep.sdkWrites)
|
|
@@ -15550,7 +15642,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15550
15642
|
}
|
|
15551
15643
|
}
|
|
15552
15644
|
const edgeType = edgeTypeFromEndpoint(ep);
|
|
15553
|
-
const confidence = (0,
|
|
15645
|
+
const confidence = (0, import_types46.confidenceForExtracted)(ep.confidenceKind);
|
|
15554
15646
|
const relFile = toPosix(ep.evidence.file);
|
|
15555
15647
|
const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
15556
15648
|
graph,
|
|
@@ -15560,7 +15652,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15560
15652
|
);
|
|
15561
15653
|
nodesAdded += n;
|
|
15562
15654
|
edgesAdded += e;
|
|
15563
|
-
if (!(0,
|
|
15655
|
+
if (!(0, import_types46.passesExtractedFloor)(confidence)) {
|
|
15564
15656
|
noteExtractedDropped({
|
|
15565
15657
|
source: fileNodeId,
|
|
15566
15658
|
target: ep.infraId,
|
|
@@ -15580,7 +15672,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15580
15672
|
source: fileNodeId,
|
|
15581
15673
|
target: ep.infraId,
|
|
15582
15674
|
type: edgeType,
|
|
15583
|
-
provenance:
|
|
15675
|
+
provenance: import_types46.Provenance.EXTRACTED,
|
|
15584
15676
|
confidence,
|
|
15585
15677
|
evidence: ep.evidence
|
|
15586
15678
|
};
|
|
@@ -15603,7 +15695,7 @@ async function addCallEdges(graph, services) {
|
|
|
15603
15695
|
|
|
15604
15696
|
// src/extract/table-edges.ts
|
|
15605
15697
|
init_cjs_shims();
|
|
15606
|
-
var
|
|
15698
|
+
var import_types47 = require("@neat.is/types");
|
|
15607
15699
|
async function addTableEdges(graph, services) {
|
|
15608
15700
|
let nodesAdded = 0;
|
|
15609
15701
|
let edgesAdded = 0;
|
|
@@ -15631,20 +15723,20 @@ async function addTableEdges(graph, services) {
|
|
|
15631
15723
|
}
|
|
15632
15724
|
refs.push(...modelRefs);
|
|
15633
15725
|
for (const ref of refs) {
|
|
15634
|
-
const childId = (0,
|
|
15635
|
-
const parentId = (0,
|
|
15726
|
+
const childId = (0, import_types47.infraId)("sql-table", ref.childTable);
|
|
15727
|
+
const parentId = (0, import_types47.infraId)("sql-table", ref.parentTable);
|
|
15636
15728
|
if (childId === parentId) continue;
|
|
15637
15729
|
nodesAdded += ensureTableNode(graph, childId, ref.childTable);
|
|
15638
15730
|
nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
|
|
15639
|
-
const edgeId = (0,
|
|
15731
|
+
const edgeId = (0, import_types47.extractedEdgeId)(childId, parentId, import_types47.EdgeType.REFERENCES);
|
|
15640
15732
|
if (graph.hasEdge(edgeId)) continue;
|
|
15641
15733
|
const edge = {
|
|
15642
15734
|
id: edgeId,
|
|
15643
15735
|
source: childId,
|
|
15644
15736
|
target: parentId,
|
|
15645
|
-
type:
|
|
15646
|
-
provenance:
|
|
15647
|
-
confidence: (0,
|
|
15737
|
+
type: import_types47.EdgeType.REFERENCES,
|
|
15738
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
15739
|
+
confidence: (0, import_types47.confidenceForExtracted)("structural"),
|
|
15648
15740
|
evidence: ref.evidence
|
|
15649
15741
|
};
|
|
15650
15742
|
graph.addEdgeWithKey(edgeId, childId, parentId, edge);
|
|
@@ -15657,7 +15749,7 @@ function ensureTableNode(graph, id, name) {
|
|
|
15657
15749
|
if (graph.hasNode(id)) return 0;
|
|
15658
15750
|
const node = {
|
|
15659
15751
|
id,
|
|
15660
|
-
type:
|
|
15752
|
+
type: import_types47.NodeType.InfraNode,
|
|
15661
15753
|
name,
|
|
15662
15754
|
provider: "self",
|
|
15663
15755
|
kind: "sql-table"
|
|
@@ -15671,16 +15763,16 @@ init_cjs_shims();
|
|
|
15671
15763
|
|
|
15672
15764
|
// src/extract/infra/docker-compose.ts
|
|
15673
15765
|
init_cjs_shims();
|
|
15674
|
-
var
|
|
15675
|
-
var
|
|
15766
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
15767
|
+
var import_types49 = require("@neat.is/types");
|
|
15676
15768
|
|
|
15677
15769
|
// src/extract/infra/shared.ts
|
|
15678
15770
|
init_cjs_shims();
|
|
15679
|
-
var
|
|
15771
|
+
var import_types48 = require("@neat.is/types");
|
|
15680
15772
|
function makeInfraNode(kind, name, provider = "self", extras) {
|
|
15681
15773
|
return {
|
|
15682
|
-
id: (0,
|
|
15683
|
-
type:
|
|
15774
|
+
id: (0, import_types48.infraId)(kind, name),
|
|
15775
|
+
type: import_types48.NodeType.InfraNode,
|
|
15684
15776
|
name,
|
|
15685
15777
|
provider,
|
|
15686
15778
|
kind,
|
|
@@ -15724,8 +15816,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
|
|
|
15724
15816
|
source: anchorId,
|
|
15725
15817
|
target: node.id,
|
|
15726
15818
|
type: edgeType,
|
|
15727
|
-
provenance:
|
|
15728
|
-
confidence: (0,
|
|
15819
|
+
provenance: import_types48.Provenance.EXTRACTED,
|
|
15820
|
+
confidence: (0, import_types48.confidenceForExtracted)("structural"),
|
|
15729
15821
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15730
15822
|
};
|
|
15731
15823
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15742,7 +15834,7 @@ function dependsOnList(value) {
|
|
|
15742
15834
|
}
|
|
15743
15835
|
function serviceNameToServiceNode(name, services) {
|
|
15744
15836
|
for (const s of services) {
|
|
15745
|
-
if (s.node.name === name ||
|
|
15837
|
+
if (s.node.name === name || import_node_path60.default.basename(s.dir) === name) return s.node.id;
|
|
15746
15838
|
}
|
|
15747
15839
|
return null;
|
|
15748
15840
|
}
|
|
@@ -15751,7 +15843,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15751
15843
|
let edgesAdded = 0;
|
|
15752
15844
|
let composePath = null;
|
|
15753
15845
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
15754
|
-
const abs =
|
|
15846
|
+
const abs = import_node_path60.default.join(scanPath, name);
|
|
15755
15847
|
if (await exists2(abs)) {
|
|
15756
15848
|
composePath = abs;
|
|
15757
15849
|
break;
|
|
@@ -15764,13 +15856,13 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15764
15856
|
} catch (err) {
|
|
15765
15857
|
recordExtractionError(
|
|
15766
15858
|
"infra docker-compose",
|
|
15767
|
-
|
|
15859
|
+
import_node_path60.default.relative(scanPath, composePath),
|
|
15768
15860
|
err
|
|
15769
15861
|
);
|
|
15770
15862
|
return { nodesAdded, edgesAdded };
|
|
15771
15863
|
}
|
|
15772
15864
|
if (!compose?.services) return { nodesAdded, edgesAdded };
|
|
15773
|
-
const evidenceFile =
|
|
15865
|
+
const evidenceFile = import_node_path60.default.relative(scanPath, composePath).split(import_node_path60.default.sep).join("/");
|
|
15774
15866
|
const composeNameToNodeId = /* @__PURE__ */ new Map();
|
|
15775
15867
|
for (const [composeName, svc] of Object.entries(compose.services)) {
|
|
15776
15868
|
const matchedServiceId = serviceNameToServiceNode(composeName, services);
|
|
@@ -15792,15 +15884,15 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15792
15884
|
for (const dep of dependsOnList(svc.depends_on)) {
|
|
15793
15885
|
const targetId = composeNameToNodeId.get(dep);
|
|
15794
15886
|
if (!targetId) continue;
|
|
15795
|
-
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId,
|
|
15887
|
+
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types49.EdgeType.DEPENDS_ON);
|
|
15796
15888
|
if (graph.hasEdge(edgeId)) continue;
|
|
15797
15889
|
const edge = {
|
|
15798
15890
|
id: edgeId,
|
|
15799
15891
|
source: sourceId,
|
|
15800
15892
|
target: targetId,
|
|
15801
|
-
type:
|
|
15802
|
-
provenance:
|
|
15803
|
-
confidence: (0,
|
|
15893
|
+
type: import_types49.EdgeType.DEPENDS_ON,
|
|
15894
|
+
provenance: import_types49.Provenance.EXTRACTED,
|
|
15895
|
+
confidence: (0, import_types49.confidenceForExtracted)("structural"),
|
|
15804
15896
|
evidence: { file: evidenceFile }
|
|
15805
15897
|
};
|
|
15806
15898
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15812,9 +15904,9 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15812
15904
|
|
|
15813
15905
|
// src/extract/infra/dockerfile.ts
|
|
15814
15906
|
init_cjs_shims();
|
|
15815
|
-
var
|
|
15907
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
15816
15908
|
var import_node_fs27 = require("fs");
|
|
15817
|
-
var
|
|
15909
|
+
var import_types50 = require("@neat.is/types");
|
|
15818
15910
|
function readDockerfile(content) {
|
|
15819
15911
|
let image = null;
|
|
15820
15912
|
const ports = [];
|
|
@@ -15843,7 +15935,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15843
15935
|
let nodesAdded = 0;
|
|
15844
15936
|
let edgesAdded = 0;
|
|
15845
15937
|
for (const service of services) {
|
|
15846
|
-
const dockerfilePath =
|
|
15938
|
+
const dockerfilePath = import_node_path61.default.join(service.dir, "Dockerfile");
|
|
15847
15939
|
if (!await exists2(dockerfilePath)) continue;
|
|
15848
15940
|
let content;
|
|
15849
15941
|
try {
|
|
@@ -15851,7 +15943,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15851
15943
|
} catch (err) {
|
|
15852
15944
|
recordExtractionError(
|
|
15853
15945
|
"infra dockerfile",
|
|
15854
|
-
|
|
15946
|
+
import_node_path61.default.relative(scanPath, dockerfilePath),
|
|
15855
15947
|
err
|
|
15856
15948
|
);
|
|
15857
15949
|
continue;
|
|
@@ -15863,8 +15955,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15863
15955
|
graph.addNode(node.id, node);
|
|
15864
15956
|
nodesAdded++;
|
|
15865
15957
|
}
|
|
15866
|
-
const relDockerfile = toPosix(
|
|
15867
|
-
const evidenceFile = toPosix(
|
|
15958
|
+
const relDockerfile = toPosix(import_node_path61.default.relative(service.dir, dockerfilePath));
|
|
15959
|
+
const evidenceFile = toPosix(import_node_path61.default.relative(scanPath, dockerfilePath));
|
|
15868
15960
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
15869
15961
|
graph,
|
|
15870
15962
|
service.pkg.name,
|
|
@@ -15873,15 +15965,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15873
15965
|
);
|
|
15874
15966
|
nodesAdded += fn;
|
|
15875
15967
|
edgesAdded += fe;
|
|
15876
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
15968
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types50.EdgeType.RUNS_ON);
|
|
15877
15969
|
if (!graph.hasEdge(edgeId)) {
|
|
15878
15970
|
const edge = {
|
|
15879
15971
|
id: edgeId,
|
|
15880
15972
|
source: fileNodeId,
|
|
15881
15973
|
target: node.id,
|
|
15882
|
-
type:
|
|
15883
|
-
provenance:
|
|
15884
|
-
confidence: (0,
|
|
15974
|
+
type: import_types50.EdgeType.RUNS_ON,
|
|
15975
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15976
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15885
15977
|
evidence: {
|
|
15886
15978
|
file: evidenceFile,
|
|
15887
15979
|
...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
|
|
@@ -15896,15 +15988,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15896
15988
|
graph.addNode(portNode.id, portNode);
|
|
15897
15989
|
nodesAdded++;
|
|
15898
15990
|
}
|
|
15899
|
-
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id,
|
|
15991
|
+
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types50.EdgeType.CONNECTS_TO);
|
|
15900
15992
|
if (graph.hasEdge(portEdgeId)) continue;
|
|
15901
15993
|
const portEdge = {
|
|
15902
15994
|
id: portEdgeId,
|
|
15903
15995
|
source: fileNodeId,
|
|
15904
15996
|
target: portNode.id,
|
|
15905
|
-
type:
|
|
15906
|
-
provenance:
|
|
15907
|
-
confidence: (0,
|
|
15997
|
+
type: import_types50.EdgeType.CONNECTS_TO,
|
|
15998
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15999
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15908
16000
|
evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
|
|
15909
16001
|
};
|
|
15910
16002
|
graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
|
|
@@ -15917,8 +16009,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15917
16009
|
// src/extract/infra/terraform.ts
|
|
15918
16010
|
init_cjs_shims();
|
|
15919
16011
|
var import_node_fs28 = require("fs");
|
|
15920
|
-
var
|
|
15921
|
-
var
|
|
16012
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
16013
|
+
var import_types51 = require("@neat.is/types");
|
|
15922
16014
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
15923
16015
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
15924
16016
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
@@ -15928,11 +16020,11 @@ async function walkTfFiles(start, depth = 0, max = 5) {
|
|
|
15928
16020
|
for (const entry of entries) {
|
|
15929
16021
|
if (entry.isDirectory()) {
|
|
15930
16022
|
if (IGNORED_DIRS.has(entry.name) || entry.name === ".terraform") continue;
|
|
15931
|
-
const child =
|
|
16023
|
+
const child = import_node_path62.default.join(start, entry.name);
|
|
15932
16024
|
if (await isPythonVenvDir(child)) continue;
|
|
15933
16025
|
out.push(...await walkTfFiles(child, depth + 1, max));
|
|
15934
16026
|
} else if (entry.isFile() && entry.name.endsWith(".tf")) {
|
|
15935
|
-
out.push(
|
|
16027
|
+
out.push(import_node_path62.default.join(start, entry.name));
|
|
15936
16028
|
}
|
|
15937
16029
|
}
|
|
15938
16030
|
return out;
|
|
@@ -15964,7 +16056,7 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15964
16056
|
const files = await walkTfFiles(scanPath);
|
|
15965
16057
|
for (const file of files) {
|
|
15966
16058
|
const content = await import_node_fs28.promises.readFile(file, "utf8");
|
|
15967
|
-
const evidenceFile = toPosix(
|
|
16059
|
+
const evidenceFile = toPosix(import_node_path62.default.relative(scanPath, file));
|
|
15968
16060
|
const resources = [];
|
|
15969
16061
|
const byKey = /* @__PURE__ */ new Map();
|
|
15970
16062
|
RESOURCE_RE.lastIndex = 0;
|
|
@@ -15999,16 +16091,16 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15999
16091
|
if (!target) continue;
|
|
16000
16092
|
if (seen.has(target.nodeId)) continue;
|
|
16001
16093
|
seen.add(target.nodeId);
|
|
16002
|
-
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId,
|
|
16094
|
+
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types51.EdgeType.DEPENDS_ON);
|
|
16003
16095
|
if (graph.hasEdge(edgeId)) continue;
|
|
16004
16096
|
const line = lineAt2(content, resource.bodyOffset + ref.index);
|
|
16005
16097
|
const edge = {
|
|
16006
16098
|
id: edgeId,
|
|
16007
16099
|
source: resource.nodeId,
|
|
16008
16100
|
target: target.nodeId,
|
|
16009
|
-
type:
|
|
16010
|
-
provenance:
|
|
16011
|
-
confidence: (0,
|
|
16101
|
+
type: import_types51.EdgeType.DEPENDS_ON,
|
|
16102
|
+
provenance: import_types51.Provenance.EXTRACTED,
|
|
16103
|
+
confidence: (0, import_types51.confidenceForExtracted)("structural"),
|
|
16012
16104
|
evidence: { file: evidenceFile, line, snippet: key }
|
|
16013
16105
|
};
|
|
16014
16106
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -16022,8 +16114,9 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
16022
16114
|
// src/extract/infra/k8s.ts
|
|
16023
16115
|
init_cjs_shims();
|
|
16024
16116
|
var import_node_fs29 = require("fs");
|
|
16025
|
-
var
|
|
16117
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
16026
16118
|
var import_yaml3 = require("yaml");
|
|
16119
|
+
var import_types52 = require("@neat.is/types");
|
|
16027
16120
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
16028
16121
|
Service: "k8s-service",
|
|
16029
16122
|
Deployment: "k8s-deployment",
|
|
@@ -16033,6 +16126,7 @@ var K8S_KIND_TO_INFRA_KIND = {
|
|
|
16033
16126
|
Job: "k8s-job",
|
|
16034
16127
|
Ingress: "k8s-ingress"
|
|
16035
16128
|
};
|
|
16129
|
+
var WORKLOAD_KINDS = /* @__PURE__ */ new Set(["Deployment", "StatefulSet", "DaemonSet"]);
|
|
16036
16130
|
async function walkYamlFiles2(start, depth = 0, max = 5) {
|
|
16037
16131
|
if (depth > max) return [];
|
|
16038
16132
|
const out = [];
|
|
@@ -16040,17 +16134,18 @@ async function walkYamlFiles2(start, depth = 0, max = 5) {
|
|
|
16040
16134
|
for (const entry of entries) {
|
|
16041
16135
|
if (entry.isDirectory()) {
|
|
16042
16136
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
16043
|
-
const child =
|
|
16137
|
+
const child = import_node_path63.default.join(start, entry.name);
|
|
16044
16138
|
if (await isPythonVenvDir(child)) continue;
|
|
16045
16139
|
out.push(...await walkYamlFiles2(child, depth + 1, max));
|
|
16046
|
-
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(
|
|
16047
|
-
out.push(
|
|
16140
|
+
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path63.default.extname(entry.name))) {
|
|
16141
|
+
out.push(import_node_path63.default.join(start, entry.name));
|
|
16048
16142
|
}
|
|
16049
16143
|
}
|
|
16050
16144
|
return out;
|
|
16051
16145
|
}
|
|
16052
16146
|
async function addK8sResources(graph, scanPath) {
|
|
16053
16147
|
let nodesAdded = 0;
|
|
16148
|
+
let edgesAdded = 0;
|
|
16054
16149
|
const files = await walkYamlFiles2(scanPath);
|
|
16055
16150
|
for (const file of files) {
|
|
16056
16151
|
const content = await import_node_fs29.promises.readFile(file, "utf8");
|
|
@@ -16060,31 +16155,63 @@ async function addK8sResources(graph, scanPath) {
|
|
|
16060
16155
|
} catch {
|
|
16061
16156
|
continue;
|
|
16062
16157
|
}
|
|
16158
|
+
const relFile = toPosix(import_node_path63.default.relative(scanPath, file));
|
|
16063
16159
|
for (const doc of docs) {
|
|
16064
16160
|
if (!doc?.kind || !doc.metadata?.name) continue;
|
|
16065
16161
|
const infraKind = K8S_KIND_TO_INFRA_KIND[doc.kind];
|
|
16066
16162
|
if (!infraKind) continue;
|
|
16067
|
-
const
|
|
16068
|
-
const
|
|
16163
|
+
const name = doc.metadata.name;
|
|
16164
|
+
const isWorkload = WORKLOAD_KINDS.has(doc.kind);
|
|
16165
|
+
const image = isWorkload ? doc.spec?.template?.spec?.containers?.[0]?.image : void 0;
|
|
16166
|
+
const replicas = isWorkload && typeof doc.spec?.replicas === "number" ? doc.spec.replicas : void 0;
|
|
16167
|
+
const base = makeInfraNode(infraKind, name, "kubernetes");
|
|
16168
|
+
const node = {
|
|
16169
|
+
...base,
|
|
16170
|
+
...doc.metadata.namespace ? { namespace: doc.metadata.namespace } : {},
|
|
16171
|
+
...image ? { image } : {},
|
|
16172
|
+
...replicas !== void 0 ? { replicas } : {}
|
|
16173
|
+
};
|
|
16069
16174
|
if (!graph.hasNode(node.id)) {
|
|
16070
16175
|
graph.addNode(node.id, node);
|
|
16071
16176
|
nodesAdded++;
|
|
16072
16177
|
}
|
|
16178
|
+
if (isWorkload) {
|
|
16179
|
+
const svcId = (0, import_types52.serviceId)(name);
|
|
16180
|
+
if (graph.hasNode(svcId)) {
|
|
16181
|
+
const svc = graph.getNodeAttributes(svcId);
|
|
16182
|
+
graph.replaceNodeAttributes(svcId, {
|
|
16183
|
+
...svc,
|
|
16184
|
+
platform: svc.platform ?? "kubernetes",
|
|
16185
|
+
...image ? { declaredImage: image } : {},
|
|
16186
|
+
...replicas !== void 0 ? { declaredReplicas: replicas } : {}
|
|
16187
|
+
});
|
|
16188
|
+
edgesAdded += emitPlatformResourceEdge(
|
|
16189
|
+
graph,
|
|
16190
|
+
svcId,
|
|
16191
|
+
import_types52.EdgeType.RUNS_ON,
|
|
16192
|
+
infraKind,
|
|
16193
|
+
name,
|
|
16194
|
+
"kubernetes",
|
|
16195
|
+
relFile,
|
|
16196
|
+
lineContaining(content, image)
|
|
16197
|
+
).edgesAdded;
|
|
16198
|
+
}
|
|
16199
|
+
}
|
|
16073
16200
|
}
|
|
16074
16201
|
}
|
|
16075
|
-
return { nodesAdded, edgesAdded
|
|
16202
|
+
return { nodesAdded, edgesAdded };
|
|
16076
16203
|
}
|
|
16077
16204
|
|
|
16078
16205
|
// src/extract/infra/cloudflare.ts
|
|
16079
16206
|
init_cjs_shims();
|
|
16080
16207
|
var import_node_fs30 = require("fs");
|
|
16081
|
-
var
|
|
16208
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
16082
16209
|
var import_smol_toml3 = require("smol-toml");
|
|
16083
|
-
var
|
|
16210
|
+
var import_types53 = require("@neat.is/types");
|
|
16084
16211
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
16085
16212
|
async function readWranglerConfig(dir) {
|
|
16086
16213
|
for (const filename of WRANGLER_FILENAMES) {
|
|
16087
|
-
const abs =
|
|
16214
|
+
const abs = import_node_path64.default.join(dir, filename);
|
|
16088
16215
|
if (!await exists2(abs)) continue;
|
|
16089
16216
|
const raw = await import_node_fs30.promises.readFile(abs, "utf8");
|
|
16090
16217
|
const config = filename === "wrangler.toml" ? (0, import_smol_toml3.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
@@ -16128,8 +16255,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
|
|
|
16128
16255
|
source: anchorId,
|
|
16129
16256
|
target: node.id,
|
|
16130
16257
|
type: edgeType,
|
|
16131
|
-
provenance:
|
|
16132
|
-
confidence: (0,
|
|
16258
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
16259
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
16133
16260
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
16134
16261
|
};
|
|
16135
16262
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -16147,11 +16274,11 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16147
16274
|
try {
|
|
16148
16275
|
read = await readWranglerConfig(service.dir);
|
|
16149
16276
|
} catch (err) {
|
|
16150
|
-
recordExtractionError("infra cloudflare",
|
|
16277
|
+
recordExtractionError("infra cloudflare", import_node_path64.default.relative(scanPath, service.dir), err);
|
|
16151
16278
|
continue;
|
|
16152
16279
|
}
|
|
16153
16280
|
if (!read || !read.config.name) continue;
|
|
16154
|
-
const evidenceFile = toPosix(
|
|
16281
|
+
const evidenceFile = toPosix(import_node_path64.default.relative(scanPath, import_node_path64.default.join(service.dir, read.relFile)));
|
|
16155
16282
|
discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
|
|
16156
16283
|
}
|
|
16157
16284
|
for (const worker of discovered) {
|
|
@@ -16163,7 +16290,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16163
16290
|
}
|
|
16164
16291
|
let anchorId = service.node.id;
|
|
16165
16292
|
if (config.main) {
|
|
16166
|
-
const entryRelPath = toPosix(
|
|
16293
|
+
const entryRelPath = toPosix(import_node_path64.default.normalize(config.main));
|
|
16167
16294
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
16168
16295
|
graph,
|
|
16169
16296
|
service.pkg.name,
|
|
@@ -16190,15 +16317,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16190
16317
|
nodesAdded++;
|
|
16191
16318
|
}
|
|
16192
16319
|
if (runtimeNode.id !== anchorId) {
|
|
16193
|
-
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id,
|
|
16320
|
+
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types53.EdgeType.RUNS_ON);
|
|
16194
16321
|
if (!graph.hasEdge(runsOnId)) {
|
|
16195
16322
|
const edge = {
|
|
16196
16323
|
id: runsOnId,
|
|
16197
16324
|
source: anchorId,
|
|
16198
16325
|
target: runtimeNode.id,
|
|
16199
|
-
type:
|
|
16200
|
-
provenance:
|
|
16201
|
-
confidence: (0,
|
|
16326
|
+
type: import_types53.EdgeType.RUNS_ON,
|
|
16327
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
16328
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
16202
16329
|
evidence: {
|
|
16203
16330
|
file: evidenceFile,
|
|
16204
16331
|
...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
|
|
@@ -16212,7 +16339,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16212
16339
|
const result = addResourceEdge(
|
|
16213
16340
|
graph,
|
|
16214
16341
|
anchorId,
|
|
16215
|
-
|
|
16342
|
+
import_types53.EdgeType.CONNECTS_TO,
|
|
16216
16343
|
"cloudflare-route",
|
|
16217
16344
|
route,
|
|
16218
16345
|
evidenceFile,
|
|
@@ -16236,7 +16363,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16236
16363
|
const result = addResourceEdge(
|
|
16237
16364
|
graph,
|
|
16238
16365
|
anchorId,
|
|
16239
|
-
|
|
16366
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
16240
16367
|
group.kind,
|
|
16241
16368
|
name,
|
|
16242
16369
|
evidenceFile,
|
|
@@ -16250,7 +16377,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16250
16377
|
const result = addResourceEdge(
|
|
16251
16378
|
graph,
|
|
16252
16379
|
anchorId,
|
|
16253
|
-
|
|
16380
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
16254
16381
|
"cloudflare-cron",
|
|
16255
16382
|
cron,
|
|
16256
16383
|
evidenceFile,
|
|
@@ -16263,7 +16390,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16263
16390
|
const result = addResourceEdge(
|
|
16264
16391
|
graph,
|
|
16265
16392
|
anchorId,
|
|
16266
|
-
|
|
16393
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
16267
16394
|
"cloudflare-env-var",
|
|
16268
16395
|
varName,
|
|
16269
16396
|
evidenceFile,
|
|
@@ -16276,15 +16403,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16276
16403
|
if (!svc.service) continue;
|
|
16277
16404
|
const target = workerIndex.get(svc.service);
|
|
16278
16405
|
if (target && target.anchorId !== anchorId) {
|
|
16279
|
-
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId,
|
|
16406
|
+
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types53.EdgeType.CALLS);
|
|
16280
16407
|
if (!graph.hasEdge(edgeId)) {
|
|
16281
16408
|
const edge = {
|
|
16282
16409
|
id: edgeId,
|
|
16283
16410
|
source: anchorId,
|
|
16284
16411
|
target: target.anchorId,
|
|
16285
|
-
type:
|
|
16286
|
-
provenance:
|
|
16287
|
-
confidence: (0,
|
|
16412
|
+
type: import_types53.EdgeType.CALLS,
|
|
16413
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
16414
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
16288
16415
|
evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
|
|
16289
16416
|
};
|
|
16290
16417
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -16295,7 +16422,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16295
16422
|
const result = addResourceEdge(
|
|
16296
16423
|
graph,
|
|
16297
16424
|
anchorId,
|
|
16298
|
-
|
|
16425
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
16299
16426
|
"cloudflare-service-binding",
|
|
16300
16427
|
svc.service,
|
|
16301
16428
|
evidenceFile,
|
|
@@ -16311,12 +16438,12 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16311
16438
|
// src/extract/infra/vercel.ts
|
|
16312
16439
|
init_cjs_shims();
|
|
16313
16440
|
var import_node_fs31 = require("fs");
|
|
16314
|
-
var
|
|
16315
|
-
var
|
|
16441
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
16442
|
+
var import_types54 = require("@neat.is/types");
|
|
16316
16443
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
16317
16444
|
async function readVercelConfig(dir) {
|
|
16318
16445
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
16319
|
-
const abs =
|
|
16446
|
+
const abs = import_node_path65.default.join(dir, filename);
|
|
16320
16447
|
if (!await exists2(abs)) continue;
|
|
16321
16448
|
const raw = await import_node_fs31.promises.readFile(abs, "utf8");
|
|
16322
16449
|
const config = JSON.parse(maskCommentsInSource(raw));
|
|
@@ -16325,7 +16452,7 @@ async function readVercelConfig(dir) {
|
|
|
16325
16452
|
return null;
|
|
16326
16453
|
}
|
|
16327
16454
|
async function readLinkedProjectName(dir) {
|
|
16328
|
-
const abs =
|
|
16455
|
+
const abs = import_node_path65.default.join(dir, ".vercel", "project.json");
|
|
16329
16456
|
if (!await exists2(abs)) return void 0;
|
|
16330
16457
|
const parsed = JSON.parse(await import_node_fs31.promises.readFile(abs, "utf8"));
|
|
16331
16458
|
return typeof parsed.projectName === "string" ? parsed.projectName : void 0;
|
|
@@ -16343,7 +16470,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
16343
16470
|
read = await readVercelConfig(service.dir);
|
|
16344
16471
|
projectName = await readLinkedProjectName(service.dir);
|
|
16345
16472
|
} catch (err) {
|
|
16346
|
-
recordExtractionError("infra vercel",
|
|
16473
|
+
recordExtractionError("infra vercel", import_node_path65.default.relative(scanPath, service.dir), err);
|
|
16347
16474
|
continue;
|
|
16348
16475
|
}
|
|
16349
16476
|
if (!read && !projectName) continue;
|
|
@@ -16359,7 +16486,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
16359
16486
|
const anchorId = service.node.id;
|
|
16360
16487
|
if (!read) continue;
|
|
16361
16488
|
const { config, relFile, raw } = read;
|
|
16362
|
-
const evidenceFile = toPosix(
|
|
16489
|
+
const evidenceFile = toPosix(import_node_path65.default.relative(scanPath, import_node_path65.default.join(service.dir, relFile)));
|
|
16363
16490
|
const add = (edgeType, kind, name) => {
|
|
16364
16491
|
if (!name) return;
|
|
16365
16492
|
const result = emitPlatformResourceEdge(
|
|
@@ -16375,12 +16502,12 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
16375
16502
|
nodesAdded += result.nodesAdded;
|
|
16376
16503
|
edgesAdded += result.edgesAdded;
|
|
16377
16504
|
};
|
|
16378
|
-
add(
|
|
16379
|
-
for (const cron of config.crons ?? []) add(
|
|
16380
|
-
for (const varName of Object.keys(config.env ?? {})) add(
|
|
16381
|
-
for (const varName of Object.keys(config.build?.env ?? {})) add(
|
|
16505
|
+
add(import_types54.EdgeType.RUNS_ON, "vercel", "vercel");
|
|
16506
|
+
for (const cron of config.crons ?? []) add(import_types54.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
|
|
16507
|
+
for (const varName of Object.keys(config.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16508
|
+
for (const varName of Object.keys(config.build?.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16382
16509
|
for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
|
|
16383
|
-
add(
|
|
16510
|
+
add(import_types54.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
|
|
16384
16511
|
}
|
|
16385
16512
|
}
|
|
16386
16513
|
return { nodesAdded, edgesAdded };
|
|
@@ -16389,13 +16516,13 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
16389
16516
|
// src/extract/infra/railway.ts
|
|
16390
16517
|
init_cjs_shims();
|
|
16391
16518
|
var import_node_fs32 = require("fs");
|
|
16392
|
-
var
|
|
16519
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
16393
16520
|
var import_smol_toml4 = require("smol-toml");
|
|
16394
|
-
var
|
|
16521
|
+
var import_types55 = require("@neat.is/types");
|
|
16395
16522
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
16396
16523
|
async function readRailwayConfig(dir) {
|
|
16397
16524
|
for (const filename of RAILWAY_FILENAMES) {
|
|
16398
|
-
const abs =
|
|
16525
|
+
const abs = import_node_path66.default.join(dir, filename);
|
|
16399
16526
|
if (!await exists2(abs)) continue;
|
|
16400
16527
|
const raw = await import_node_fs32.promises.readFile(abs, "utf8");
|
|
16401
16528
|
const config = filename === "railway.toml" ? (0, import_smol_toml4.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
@@ -16411,7 +16538,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16411
16538
|
try {
|
|
16412
16539
|
read = await readRailwayConfig(service.dir);
|
|
16413
16540
|
} catch (err) {
|
|
16414
|
-
recordExtractionError("infra railway",
|
|
16541
|
+
recordExtractionError("infra railway", import_node_path66.default.relative(scanPath, service.dir), err);
|
|
16415
16542
|
continue;
|
|
16416
16543
|
}
|
|
16417
16544
|
if (!read) continue;
|
|
@@ -16421,7 +16548,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16421
16548
|
}
|
|
16422
16549
|
const anchorId = service.node.id;
|
|
16423
16550
|
const { config, relFile, raw } = read;
|
|
16424
|
-
const evidenceFile = toPosix(
|
|
16551
|
+
const evidenceFile = toPosix(import_node_path66.default.relative(scanPath, import_node_path66.default.join(service.dir, relFile)));
|
|
16425
16552
|
const add = (edgeType, kind, name) => {
|
|
16426
16553
|
if (!name) return;
|
|
16427
16554
|
const result = emitPlatformResourceEdge(
|
|
@@ -16437,9 +16564,9 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16437
16564
|
nodesAdded += result.nodesAdded;
|
|
16438
16565
|
edgesAdded += result.edgesAdded;
|
|
16439
16566
|
};
|
|
16440
|
-
add(
|
|
16441
|
-
add(
|
|
16442
|
-
add(
|
|
16567
|
+
add(import_types55.EdgeType.RUNS_ON, "railway", "railway");
|
|
16568
|
+
add(import_types55.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
|
|
16569
|
+
add(import_types55.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
|
|
16443
16570
|
}
|
|
16444
16571
|
return { nodesAdded, edgesAdded };
|
|
16445
16572
|
}
|
|
@@ -16447,12 +16574,12 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16447
16574
|
// src/extract/infra/supabase.ts
|
|
16448
16575
|
init_cjs_shims();
|
|
16449
16576
|
var import_node_fs33 = require("fs");
|
|
16450
|
-
var
|
|
16577
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
16451
16578
|
var import_smol_toml5 = require("smol-toml");
|
|
16452
|
-
var
|
|
16579
|
+
var import_types56 = require("@neat.is/types");
|
|
16453
16580
|
async function readSupabaseConfig(dir) {
|
|
16454
|
-
const relFile =
|
|
16455
|
-
const abs =
|
|
16581
|
+
const relFile = import_node_path67.default.join("supabase", "config.toml");
|
|
16582
|
+
const abs = import_node_path67.default.join(dir, relFile);
|
|
16456
16583
|
if (!await exists2(abs)) return null;
|
|
16457
16584
|
const raw = await import_node_fs33.promises.readFile(abs, "utf8");
|
|
16458
16585
|
const config = (0, import_smol_toml5.parse)(raw);
|
|
@@ -16466,7 +16593,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
16466
16593
|
try {
|
|
16467
16594
|
read = await readSupabaseConfig(service.dir);
|
|
16468
16595
|
} catch (err) {
|
|
16469
|
-
recordExtractionError("infra supabase",
|
|
16596
|
+
recordExtractionError("infra supabase", import_node_path67.default.relative(scanPath, service.dir), err);
|
|
16470
16597
|
continue;
|
|
16471
16598
|
}
|
|
16472
16599
|
if (!read) continue;
|
|
@@ -16481,7 +16608,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
16481
16608
|
});
|
|
16482
16609
|
}
|
|
16483
16610
|
const anchorId = service.node.id;
|
|
16484
|
-
const evidenceFile = toPosix(
|
|
16611
|
+
const evidenceFile = toPosix(import_node_path67.default.relative(scanPath, import_node_path67.default.join(service.dir, relFile)));
|
|
16485
16612
|
const add = (edgeType, kind, name) => {
|
|
16486
16613
|
if (!name) return;
|
|
16487
16614
|
const result = emitPlatformResourceEdge(
|
|
@@ -16497,10 +16624,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
16497
16624
|
nodesAdded += result.nodesAdded;
|
|
16498
16625
|
edgesAdded += result.edgesAdded;
|
|
16499
16626
|
};
|
|
16500
|
-
add(
|
|
16501
|
-
for (const fn of Object.keys(config.functions ?? {})) add(
|
|
16502
|
-
if (config.storage) add(
|
|
16503
|
-
if (config.auth) add(
|
|
16627
|
+
add(import_types56.EdgeType.RUNS_ON, "supabase", "supabase");
|
|
16628
|
+
for (const fn of Object.keys(config.functions ?? {})) add(import_types56.EdgeType.DEPENDS_ON, "supabase-function", fn);
|
|
16629
|
+
if (config.storage) add(import_types56.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
|
|
16630
|
+
if (config.auth) add(import_types56.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
|
|
16504
16631
|
}
|
|
16505
16632
|
return { nodesAdded, edgesAdded };
|
|
16506
16633
|
}
|
|
@@ -16523,18 +16650,18 @@ async function addInfra(graph, scanPath, services) {
|
|
|
16523
16650
|
|
|
16524
16651
|
// src/extract/zod-shapes.ts
|
|
16525
16652
|
init_cjs_shims();
|
|
16526
|
-
var
|
|
16527
|
-
var
|
|
16653
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
16654
|
+
var import_tree_sitter18 = __toESM(require("tree-sitter"), 1);
|
|
16528
16655
|
var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
|
|
16529
|
-
var
|
|
16656
|
+
var import_types57 = require("@neat.is/types");
|
|
16530
16657
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
16531
16658
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
16532
16659
|
function parserForExt4(ext) {
|
|
16533
|
-
const p = new
|
|
16660
|
+
const p = new import_tree_sitter18.default();
|
|
16534
16661
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript8.default);
|
|
16535
16662
|
return p;
|
|
16536
16663
|
}
|
|
16537
|
-
function
|
|
16664
|
+
function namedChildren6(node) {
|
|
16538
16665
|
const out = [];
|
|
16539
16666
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
16540
16667
|
const c = node.namedChild(i);
|
|
@@ -16544,7 +16671,7 @@ function namedChildren5(node) {
|
|
|
16544
16671
|
}
|
|
16545
16672
|
function stringLiteralText5(node) {
|
|
16546
16673
|
if (!node || node.type !== "string") return null;
|
|
16547
|
-
for (const child of
|
|
16674
|
+
for (const child of namedChildren6(node)) {
|
|
16548
16675
|
if (child.type === "string_fragment") return child.text;
|
|
16549
16676
|
}
|
|
16550
16677
|
return "";
|
|
@@ -16569,12 +16696,12 @@ function zodCallKind(call) {
|
|
|
16569
16696
|
function firstArg(call) {
|
|
16570
16697
|
const args = call.childForFieldName("arguments");
|
|
16571
16698
|
if (!args) return null;
|
|
16572
|
-
return
|
|
16699
|
+
return namedChildren6(args)[0] ?? null;
|
|
16573
16700
|
}
|
|
16574
16701
|
function fieldsFromObject(obj) {
|
|
16575
16702
|
const out = [];
|
|
16576
16703
|
const seen = /* @__PURE__ */ new Set();
|
|
16577
|
-
for (const child of
|
|
16704
|
+
for (const child of namedChildren6(obj)) {
|
|
16578
16705
|
if (child.type === "spread_element") return null;
|
|
16579
16706
|
if (child.type !== "pair") continue;
|
|
16580
16707
|
const key = child.childForFieldName("key");
|
|
@@ -16590,7 +16717,7 @@ function fieldsFromObject(obj) {
|
|
|
16590
16717
|
function membersFromEnum(arr) {
|
|
16591
16718
|
const out = [];
|
|
16592
16719
|
const seen = /* @__PURE__ */ new Set();
|
|
16593
|
-
for (const child of
|
|
16720
|
+
for (const child of namedChildren6(arr)) {
|
|
16594
16721
|
if (child.type !== "string") return null;
|
|
16595
16722
|
const value = stringLiteralText5(child);
|
|
16596
16723
|
if (value !== null && value !== "" && !seen.has(value)) {
|
|
@@ -16602,10 +16729,10 @@ function membersFromEnum(arr) {
|
|
|
16602
16729
|
}
|
|
16603
16730
|
function topLevelSchemas(root) {
|
|
16604
16731
|
const out = [];
|
|
16605
|
-
for (const stmt of
|
|
16732
|
+
for (const stmt of namedChildren6(root)) {
|
|
16606
16733
|
const decl = stmt.type === "export_statement" ? stmt.childForFieldName("declaration") : stmt;
|
|
16607
16734
|
if (decl?.type !== "lexical_declaration" && decl?.type !== "variable_declaration") continue;
|
|
16608
|
-
for (const declarator of
|
|
16735
|
+
for (const declarator of namedChildren6(decl)) {
|
|
16609
16736
|
if (declarator.type !== "variable_declarator") continue;
|
|
16610
16737
|
const name = declarator.childForFieldName("name");
|
|
16611
16738
|
const value = declarator.childForFieldName("value");
|
|
@@ -16618,7 +16745,7 @@ function topLevelSchemas(root) {
|
|
|
16618
16745
|
}
|
|
16619
16746
|
function zodShapesFromFile(file, serviceDir) {
|
|
16620
16747
|
if (!ZOD_IMPORT_RE.test(file.content)) return [];
|
|
16621
|
-
const tree = parseSource3(parserForExt4(
|
|
16748
|
+
const tree = parseSource3(parserForExt4(import_node_path68.default.extname(file.path)), file.content);
|
|
16622
16749
|
const out = [];
|
|
16623
16750
|
const seen = /* @__PURE__ */ new Set();
|
|
16624
16751
|
for (const { name, call } of topLevelSchemas(tree.rootNode)) {
|
|
@@ -16632,11 +16759,11 @@ function zodShapesFromFile(file, serviceDir) {
|
|
|
16632
16759
|
seen.add(name);
|
|
16633
16760
|
const line = call.startPosition.row + 1;
|
|
16634
16761
|
out.push({
|
|
16635
|
-
infraId: (0,
|
|
16762
|
+
infraId: (0, import_types57.infraId)("zod-schema", name),
|
|
16636
16763
|
name,
|
|
16637
16764
|
fields,
|
|
16638
16765
|
evidence: {
|
|
16639
|
-
file:
|
|
16766
|
+
file: import_node_path68.default.relative(serviceDir, file.path),
|
|
16640
16767
|
line,
|
|
16641
16768
|
snippet: snippet(file.content, line)
|
|
16642
16769
|
}
|
|
@@ -16667,7 +16794,7 @@ async function addZodShapes(graph, services) {
|
|
|
16667
16794
|
if (!graph.hasNode(shape.infraId)) {
|
|
16668
16795
|
const node = {
|
|
16669
16796
|
id: shape.infraId,
|
|
16670
|
-
type:
|
|
16797
|
+
type: import_types57.NodeType.InfraNode,
|
|
16671
16798
|
name: shape.name,
|
|
16672
16799
|
provider: "self",
|
|
16673
16800
|
kind: "zod-schema"
|
|
@@ -16677,14 +16804,14 @@ async function addZodShapes(graph, services) {
|
|
|
16677
16804
|
}
|
|
16678
16805
|
if (shape.fields.length > 0) {
|
|
16679
16806
|
const node = graph.getNodeAttributes(shape.infraId);
|
|
16680
|
-
if (node.type ===
|
|
16807
|
+
if (node.type === import_types57.NodeType.InfraNode) {
|
|
16681
16808
|
graph.replaceNodeAttributes(shape.infraId, {
|
|
16682
16809
|
...node,
|
|
16683
16810
|
columns: foldColumns(
|
|
16684
16811
|
node.columns,
|
|
16685
16812
|
shape.fields,
|
|
16686
|
-
|
|
16687
|
-
(0,
|
|
16813
|
+
import_types57.Provenance.EXTRACTED,
|
|
16814
|
+
(0, import_types57.confidenceForExtracted)("structural")
|
|
16688
16815
|
)
|
|
16689
16816
|
});
|
|
16690
16817
|
}
|
|
@@ -16698,15 +16825,15 @@ async function addZodShapes(graph, services) {
|
|
|
16698
16825
|
);
|
|
16699
16826
|
nodesAdded += n;
|
|
16700
16827
|
edgesAdded += e;
|
|
16701
|
-
const edgeId = (0,
|
|
16828
|
+
const edgeId = (0, import_types57.extractedEdgeId)(fileNodeId, shape.infraId, import_types57.EdgeType.CONTAINS);
|
|
16702
16829
|
if (!graph.hasEdge(edgeId)) {
|
|
16703
16830
|
const edge = {
|
|
16704
16831
|
id: edgeId,
|
|
16705
16832
|
source: fileNodeId,
|
|
16706
16833
|
target: shape.infraId,
|
|
16707
|
-
type:
|
|
16708
|
-
provenance:
|
|
16709
|
-
confidence: (0,
|
|
16834
|
+
type: import_types57.EdgeType.CONTAINS,
|
|
16835
|
+
provenance: import_types57.Provenance.EXTRACTED,
|
|
16836
|
+
confidence: (0, import_types57.confidenceForExtracted)("structural"),
|
|
16710
16837
|
evidence: shape.evidence
|
|
16711
16838
|
};
|
|
16712
16839
|
graph.addEdgeWithKey(edgeId, fileNodeId, shape.infraId, edge);
|
|
@@ -16720,7 +16847,7 @@ async function addZodShapes(graph, services) {
|
|
|
16720
16847
|
|
|
16721
16848
|
// src/extract/firestore-rules.ts
|
|
16722
16849
|
init_cjs_shims();
|
|
16723
|
-
var
|
|
16850
|
+
var import_types58 = require("@neat.is/types");
|
|
16724
16851
|
var FIRESTORE_COLLECTION_KIND = "firestore-collection";
|
|
16725
16852
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["write", "create", "update"]);
|
|
16726
16853
|
function stripComments(src) {
|
|
@@ -16860,7 +16987,7 @@ async function addFirestoreRules(graph, services) {
|
|
|
16860
16987
|
if (guards.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
16861
16988
|
graph.forEachNode((id, attrs) => {
|
|
16862
16989
|
const node = attrs;
|
|
16863
|
-
if (node.type !==
|
|
16990
|
+
if (node.type !== import_types58.NodeType.InfraNode) return;
|
|
16864
16991
|
if (node.kind !== FIRESTORE_COLLECTION_KIND) return;
|
|
16865
16992
|
const fields = guards.get(collectionKeyFromName(node.name));
|
|
16866
16993
|
if (!fields || fields.size === 0) return;
|
|
@@ -16873,17 +17000,17 @@ async function addFirestoreRules(graph, services) {
|
|
|
16873
17000
|
}
|
|
16874
17001
|
|
|
16875
17002
|
// src/extract/index.ts
|
|
16876
|
-
var
|
|
17003
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
16877
17004
|
|
|
16878
17005
|
// src/extract/retire.ts
|
|
16879
17006
|
init_cjs_shims();
|
|
16880
17007
|
var import_node_fs34 = require("fs");
|
|
16881
|
-
var
|
|
16882
|
-
var
|
|
17008
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
17009
|
+
var import_types59 = require("@neat.is/types");
|
|
16883
17010
|
function dropOrphanedFileNodes(graph) {
|
|
16884
17011
|
const orphans = [];
|
|
16885
17012
|
graph.forEachNode((id, attrs) => {
|
|
16886
|
-
if (attrs.type !==
|
|
17013
|
+
if (attrs.type !== import_types59.NodeType.FileNode) return;
|
|
16887
17014
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
16888
17015
|
orphans.push(id);
|
|
16889
17016
|
}
|
|
@@ -16896,14 +17023,14 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
|
|
|
16896
17023
|
const bases = [scanPath, ...serviceDirs];
|
|
16897
17024
|
graph.forEachEdge((id, attrs) => {
|
|
16898
17025
|
const edge = attrs;
|
|
16899
|
-
if (edge.provenance !==
|
|
17026
|
+
if (edge.provenance !== import_types59.Provenance.EXTRACTED) return;
|
|
16900
17027
|
const evidenceFile = edge.evidence?.file;
|
|
16901
17028
|
if (!evidenceFile) return;
|
|
16902
|
-
if (
|
|
17029
|
+
if (import_node_path69.default.isAbsolute(evidenceFile)) {
|
|
16903
17030
|
if (!(0, import_node_fs34.existsSync)(evidenceFile)) toDrop.push(id);
|
|
16904
17031
|
return;
|
|
16905
17032
|
}
|
|
16906
|
-
const found = bases.some((base) => (0, import_node_fs34.existsSync)(
|
|
17033
|
+
const found = bases.some((base) => (0, import_node_fs34.existsSync)(import_node_path69.default.join(base, evidenceFile)));
|
|
16907
17034
|
if (!found) toDrop.push(id);
|
|
16908
17035
|
});
|
|
16909
17036
|
for (const id of toDrop) graph.dropEdge(id);
|
|
@@ -16960,7 +17087,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
16960
17087
|
}
|
|
16961
17088
|
const droppedEntries = drainDroppedExtracted();
|
|
16962
17089
|
if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
|
|
16963
|
-
const rejectedPath =
|
|
17090
|
+
const rejectedPath = import_node_path70.default.join(import_node_path70.default.dirname(opts.errorsPath), "rejected.ndjson");
|
|
16964
17091
|
try {
|
|
16965
17092
|
await writeRejectedExtracted(droppedEntries, rejectedPath);
|
|
16966
17093
|
} catch (err) {
|
|
@@ -16994,7 +17121,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
16994
17121
|
|
|
16995
17122
|
// src/goodybag.ts
|
|
16996
17123
|
init_cjs_shims();
|
|
16997
|
-
var
|
|
17124
|
+
var import_types60 = require("@neat.is/types");
|
|
16998
17125
|
var CODE_FILEPATH_ATTR2 = "code.filepath";
|
|
16999
17126
|
var CODE_LINENO_ATTR2 = "code.lineno";
|
|
17000
17127
|
var BLAST_NEAREST_LIMIT = 5;
|
|
@@ -17019,7 +17146,7 @@ function locusOf(graph, ev) {
|
|
|
17019
17146
|
...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
|
|
17020
17147
|
...node?.name ? { symbol: node.name } : {},
|
|
17021
17148
|
service: node?.service ?? ev.service,
|
|
17022
|
-
provenance:
|
|
17149
|
+
provenance: import_types60.Provenance.OBSERVED
|
|
17023
17150
|
};
|
|
17024
17151
|
}
|
|
17025
17152
|
function locusFromNode(graph, nodeId) {
|
|
@@ -17035,7 +17162,7 @@ function locusFromNode(graph, nodeId) {
|
|
|
17035
17162
|
...typeof end === "number" ? { lineEnd: end } : {},
|
|
17036
17163
|
...n.qualname ? { symbol: shortLabel(graph, nodeId) } : {},
|
|
17037
17164
|
...n.service ? { service: n.service } : {},
|
|
17038
|
-
provenance:
|
|
17165
|
+
provenance: import_types60.Provenance.INFERRED
|
|
17039
17166
|
};
|
|
17040
17167
|
}
|
|
17041
17168
|
function promoteCauseLocus(graph, causeNode, incidents) {
|
|
@@ -17044,7 +17171,7 @@ function promoteCauseLocus(graph, causeNode, incidents) {
|
|
|
17044
17171
|
);
|
|
17045
17172
|
if (native) {
|
|
17046
17173
|
const l = locusOf(graph, native);
|
|
17047
|
-
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance:
|
|
17174
|
+
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types60.Provenance.INFERRED };
|
|
17048
17175
|
}
|
|
17049
17176
|
return locusFromNode(graph, causeNode);
|
|
17050
17177
|
}
|
|
@@ -17093,7 +17220,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
17093
17220
|
const chain = (rc.traversalPath ?? []).map((node, i) => ({
|
|
17094
17221
|
node,
|
|
17095
17222
|
grain: grainOf2(graph, node),
|
|
17096
|
-
provenance: provs[i] ?? provs[provs.length - 1] ??
|
|
17223
|
+
provenance: provs[i] ?? provs[provs.length - 1] ?? import_types60.Provenance.INFERRED
|
|
17097
17224
|
}));
|
|
17098
17225
|
rootCause = {
|
|
17099
17226
|
node: rc.rootCauseNode,
|
|
@@ -17123,7 +17250,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
17123
17250
|
kind: "incident",
|
|
17124
17251
|
id: errorEvent.id,
|
|
17125
17252
|
at: errorEvent.timestamp,
|
|
17126
|
-
incidentKind: (0,
|
|
17253
|
+
incidentKind: (0, import_types60.incidentKindOf)(errorEvent),
|
|
17127
17254
|
service: errorEvent.service,
|
|
17128
17255
|
affectedNode: affected,
|
|
17129
17256
|
message: errorEvent.errorMessage,
|
|
@@ -17140,12 +17267,12 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
17140
17267
|
...divergences.length > 0 ? { divergence: divergences } : {},
|
|
17141
17268
|
headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
|
|
17142
17269
|
};
|
|
17143
|
-
return
|
|
17270
|
+
return import_types60.IncidentCardSchema.parse(card);
|
|
17144
17271
|
}
|
|
17145
17272
|
|
|
17146
17273
|
// src/ask.ts
|
|
17147
17274
|
init_cjs_shims();
|
|
17148
|
-
var
|
|
17275
|
+
var import_types61 = require("@neat.is/types");
|
|
17149
17276
|
var DEFAULT_MAX_NODES = 3;
|
|
17150
17277
|
var MAX_FACTS_PER_SECTION = 6;
|
|
17151
17278
|
var INTENT_RULES = [
|
|
@@ -17373,7 +17500,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17373
17500
|
};
|
|
17374
17501
|
graph.forEachNode((id, attrs) => {
|
|
17375
17502
|
const node = attrs;
|
|
17376
|
-
if (node.type ===
|
|
17503
|
+
if (node.type === import_types61.NodeType.FrontierNode) return;
|
|
17377
17504
|
const name = nodeName(node);
|
|
17378
17505
|
const body = idBody(id);
|
|
17379
17506
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
@@ -17392,7 +17519,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17392
17519
|
const res = await searchIndex.search(question, 10);
|
|
17393
17520
|
if (res.provider !== "substring") {
|
|
17394
17521
|
for (const m of res.matches) {
|
|
17395
|
-
if (m.node.type ===
|
|
17522
|
+
if (m.node.type === import_types61.NodeType.FrontierNode) continue;
|
|
17396
17523
|
const already = best.get(m.node.id);
|
|
17397
17524
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
17398
17525
|
consider({
|
|
@@ -17430,7 +17557,7 @@ function edgeSignalNote(e) {
|
|
|
17430
17557
|
function buildRootCauseSection(graph, node, incidents, now) {
|
|
17431
17558
|
const result = getRootCause(graph, node, void 0, incidents, { now });
|
|
17432
17559
|
if (!result) return null;
|
|
17433
|
-
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ??
|
|
17560
|
+
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types61.Provenance.OBSERVED;
|
|
17434
17561
|
const facts = [
|
|
17435
17562
|
{
|
|
17436
17563
|
text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
|
|
@@ -17480,7 +17607,7 @@ function buildObservedSection(graph, node) {
|
|
|
17480
17607
|
if (result.observed && result.inboundObservedCount > 0) {
|
|
17481
17608
|
facts.push({
|
|
17482
17609
|
text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
|
|
17483
|
-
provenance:
|
|
17610
|
+
provenance: import_types61.Provenance.OBSERVED
|
|
17484
17611
|
});
|
|
17485
17612
|
} else {
|
|
17486
17613
|
return null;
|
|
@@ -17508,7 +17635,7 @@ function buildIncidentsSection(node, incidents) {
|
|
|
17508
17635
|
const facts = ordered.map((ev) => ({
|
|
17509
17636
|
text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
|
|
17510
17637
|
// ErrorEvents are observation records — OBSERVED by definition.
|
|
17511
|
-
provenance:
|
|
17638
|
+
provenance: import_types61.Provenance.OBSERVED
|
|
17512
17639
|
}));
|
|
17513
17640
|
return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
|
|
17514
17641
|
}
|
|
@@ -17568,7 +17695,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
17568
17695
|
}
|
|
17569
17696
|
const byKey = /* @__PURE__ */ new Map();
|
|
17570
17697
|
for (const ev of incidents) {
|
|
17571
|
-
const key = ev.affectedNode || (0,
|
|
17698
|
+
const key = ev.affectedNode || (0, import_types61.serviceId)(ev.service);
|
|
17572
17699
|
const cur = byKey.get(key);
|
|
17573
17700
|
if (!cur) {
|
|
17574
17701
|
byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
|
|
@@ -17583,7 +17710,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
17583
17710
|
const rows = [...byKey.values()].sort((a, b) => b.count - a.count || b.latest.localeCompare(a.latest) || a.key.localeCompare(b.key)).slice(0, MAX_FACTS_PER_SECTION);
|
|
17584
17711
|
const facts = rows.map((r) => ({
|
|
17585
17712
|
text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
|
|
17586
|
-
provenance:
|
|
17713
|
+
provenance: import_types61.Provenance.OBSERVED
|
|
17587
17714
|
}));
|
|
17588
17715
|
return {
|
|
17589
17716
|
heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
|
|
@@ -17596,7 +17723,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17596
17723
|
graph.forEachNode((_id, attrs) => {
|
|
17597
17724
|
const node = attrs;
|
|
17598
17725
|
nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
|
|
17599
|
-
if (node.type ===
|
|
17726
|
+
if (node.type === import_types61.NodeType.ServiceNode) services.push(node.id);
|
|
17600
17727
|
});
|
|
17601
17728
|
const edgeByProv = /* @__PURE__ */ new Map();
|
|
17602
17729
|
graph.forEachEdge((_id, attrs) => {
|
|
@@ -17608,10 +17735,10 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17608
17735
|
const shapeFacts = [
|
|
17609
17736
|
{ text: `${graph.order} nodes, ${graph.size} edges` },
|
|
17610
17737
|
{
|
|
17611
|
-
text: `${count(
|
|
17738
|
+
text: `${count(import_types61.NodeType.ServiceNode)} services, ${count(import_types61.NodeType.FileNode)} files, ${count(import_types61.NodeType.SymbolNode)} symbols, ${count(import_types61.NodeType.DatabaseNode)} databases`
|
|
17612
17739
|
}
|
|
17613
17740
|
];
|
|
17614
|
-
for (const p of [
|
|
17741
|
+
for (const p of [import_types61.Provenance.EXTRACTED, import_types61.Provenance.OBSERVED, import_types61.Provenance.INFERRED, import_types61.Provenance.STALE]) {
|
|
17615
17742
|
const n = edgeByProv.get(p) ?? 0;
|
|
17616
17743
|
if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
|
|
17617
17744
|
}
|
|
@@ -17628,7 +17755,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17628
17755
|
if (incidents && incidents.length > 0) {
|
|
17629
17756
|
const incCount = /* @__PURE__ */ new Map();
|
|
17630
17757
|
for (const ev of incidents) {
|
|
17631
|
-
const key = ev.affectedNode || (0,
|
|
17758
|
+
const key = ev.affectedNode || (0, import_types61.serviceId)(ev.service);
|
|
17632
17759
|
incCount.set(key, (incCount.get(key) ?? 0) + 1);
|
|
17633
17760
|
}
|
|
17634
17761
|
const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
|
|
@@ -17636,7 +17763,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17636
17763
|
heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
|
|
17637
17764
|
facts: top.map(([k, n]) => ({
|
|
17638
17765
|
text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
|
|
17639
|
-
provenance:
|
|
17766
|
+
provenance: import_types61.Provenance.OBSERVED
|
|
17640
17767
|
}))
|
|
17641
17768
|
});
|
|
17642
17769
|
}
|
|
@@ -17772,7 +17899,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
17772
17899
|
const provSet = /* @__PURE__ */ new Set();
|
|
17773
17900
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
17774
17901
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
17775
|
-
return
|
|
17902
|
+
return import_types61.AskResultSchema.parse({
|
|
17776
17903
|
question,
|
|
17777
17904
|
intent,
|
|
17778
17905
|
matched,
|
|
@@ -17865,8 +17992,8 @@ function canonicalJson(value) {
|
|
|
17865
17992
|
// src/persist.ts
|
|
17866
17993
|
init_cjs_shims();
|
|
17867
17994
|
var import_node_fs36 = require("fs");
|
|
17868
|
-
var
|
|
17869
|
-
var
|
|
17995
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
17996
|
+
var import_types62 = require("@neat.is/types");
|
|
17870
17997
|
var SCHEMA_VERSION = 7;
|
|
17871
17998
|
function migrateV1ToV2(payload) {
|
|
17872
17999
|
const nodes = payload.graph.nodes;
|
|
@@ -17890,7 +18017,7 @@ function migrateV5ToV6(payload) {
|
|
|
17890
18017
|
if (Array.isArray(nodes)) {
|
|
17891
18018
|
for (const node of nodes) {
|
|
17892
18019
|
const attrs = node.attributes;
|
|
17893
|
-
if (!attrs || attrs.type !==
|
|
18020
|
+
if (!attrs || attrs.type !== import_types62.NodeType.InfraNode) continue;
|
|
17894
18021
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
17895
18022
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
17896
18023
|
}
|
|
@@ -17906,12 +18033,12 @@ function migrateV2ToV3(payload) {
|
|
|
17906
18033
|
for (const edge of edges) {
|
|
17907
18034
|
const attrs = edge.attributes;
|
|
17908
18035
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
17909
|
-
attrs.provenance =
|
|
18036
|
+
attrs.provenance = import_types62.Provenance.OBSERVED;
|
|
17910
18037
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
17911
18038
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
17912
18039
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
17913
18040
|
if (type && source && target) {
|
|
17914
|
-
const newId = (0,
|
|
18041
|
+
const newId = (0, import_types62.observedEdgeId)(source, target, type);
|
|
17915
18042
|
attrs.id = newId;
|
|
17916
18043
|
if (edge.key) edge.key = newId;
|
|
17917
18044
|
}
|
|
@@ -17920,7 +18047,7 @@ function migrateV2ToV3(payload) {
|
|
|
17920
18047
|
return { ...payload, schemaVersion: 3 };
|
|
17921
18048
|
}
|
|
17922
18049
|
async function ensureDir(filePath) {
|
|
17923
|
-
await import_node_fs36.promises.mkdir(
|
|
18050
|
+
await import_node_fs36.promises.mkdir(import_node_path71.default.dirname(filePath), { recursive: true });
|
|
17924
18051
|
}
|
|
17925
18052
|
async function saveGraphToDisk(graph, outPath) {
|
|
17926
18053
|
await ensureDir(outPath);
|
|
@@ -18010,23 +18137,23 @@ function startPersistLoop(graph, outPath, opts = {}) {
|
|
|
18010
18137
|
|
|
18011
18138
|
// src/projects.ts
|
|
18012
18139
|
init_cjs_shims();
|
|
18013
|
-
var
|
|
18140
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
18014
18141
|
function pathsForProject(project, baseDir) {
|
|
18015
18142
|
if (project === DEFAULT_PROJECT) {
|
|
18016
18143
|
return {
|
|
18017
|
-
snapshotPath:
|
|
18018
|
-
errorsPath:
|
|
18019
|
-
staleEventsPath:
|
|
18020
|
-
embeddingsCachePath:
|
|
18021
|
-
policyViolationsPath:
|
|
18144
|
+
snapshotPath: import_node_path72.default.join(baseDir, "graph.json"),
|
|
18145
|
+
errorsPath: import_node_path72.default.join(baseDir, "errors.ndjson"),
|
|
18146
|
+
staleEventsPath: import_node_path72.default.join(baseDir, "stale-events.ndjson"),
|
|
18147
|
+
embeddingsCachePath: import_node_path72.default.join(baseDir, "embeddings.json"),
|
|
18148
|
+
policyViolationsPath: import_node_path72.default.join(baseDir, "policy-violations.ndjson")
|
|
18022
18149
|
};
|
|
18023
18150
|
}
|
|
18024
18151
|
return {
|
|
18025
|
-
snapshotPath:
|
|
18026
|
-
errorsPath:
|
|
18027
|
-
staleEventsPath:
|
|
18028
|
-
embeddingsCachePath:
|
|
18029
|
-
policyViolationsPath:
|
|
18152
|
+
snapshotPath: import_node_path72.default.join(baseDir, `${project}.json`),
|
|
18153
|
+
errorsPath: import_node_path72.default.join(baseDir, `errors.${project}.ndjson`),
|
|
18154
|
+
staleEventsPath: import_node_path72.default.join(baseDir, `stale-events.${project}.ndjson`),
|
|
18155
|
+
embeddingsCachePath: import_node_path72.default.join(baseDir, `embeddings.${project}.json`),
|
|
18156
|
+
policyViolationsPath: import_node_path72.default.join(baseDir, `policy-violations.${project}.ndjson`)
|
|
18030
18157
|
};
|
|
18031
18158
|
}
|
|
18032
18159
|
var Projects = class {
|
|
@@ -18068,18 +18195,18 @@ function parseExtraProjects(raw) {
|
|
|
18068
18195
|
init_cjs_shims();
|
|
18069
18196
|
var import_node_fs37 = require("fs");
|
|
18070
18197
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
18071
|
-
var
|
|
18072
|
-
var
|
|
18198
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
18199
|
+
var import_types63 = require("@neat.is/types");
|
|
18073
18200
|
function neatHome() {
|
|
18074
18201
|
const override = process.env.NEAT_HOME;
|
|
18075
|
-
if (override && override.length > 0) return
|
|
18076
|
-
return
|
|
18202
|
+
if (override && override.length > 0) return import_node_path73.default.resolve(override);
|
|
18203
|
+
return import_node_path73.default.join(import_node_os3.default.homedir(), ".neat");
|
|
18077
18204
|
}
|
|
18078
18205
|
function registryPath() {
|
|
18079
|
-
return
|
|
18206
|
+
return import_node_path73.default.join(neatHome(), "projects.json");
|
|
18080
18207
|
}
|
|
18081
18208
|
function daemonsDir() {
|
|
18082
|
-
return
|
|
18209
|
+
return import_node_path73.default.join(neatHome(), "daemons");
|
|
18083
18210
|
}
|
|
18084
18211
|
function isFiniteInt(v) {
|
|
18085
18212
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -18120,7 +18247,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
|
|
|
18120
18247
|
const out = [];
|
|
18121
18248
|
for (const name of names) {
|
|
18122
18249
|
if (!name.endsWith(".json")) continue;
|
|
18123
|
-
const file =
|
|
18250
|
+
const file = import_node_path73.default.join(dir, name);
|
|
18124
18251
|
let raw;
|
|
18125
18252
|
try {
|
|
18126
18253
|
raw = await import_node_fs37.promises.readFile(file, "utf8");
|
|
@@ -18159,7 +18286,7 @@ async function readRegistry() {
|
|
|
18159
18286
|
throw err;
|
|
18160
18287
|
}
|
|
18161
18288
|
const parsed = JSON.parse(raw);
|
|
18162
|
-
return
|
|
18289
|
+
return import_types63.RegistryFileSchema.parse(parsed);
|
|
18163
18290
|
}
|
|
18164
18291
|
async function getProject(name) {
|
|
18165
18292
|
const reg = await readRegistry();
|
|
@@ -18234,7 +18361,7 @@ init_auth();
|
|
|
18234
18361
|
// src/connectors-config.ts
|
|
18235
18362
|
init_cjs_shims();
|
|
18236
18363
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
18237
|
-
var
|
|
18364
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
18238
18365
|
var import_node_fs38 = require("fs");
|
|
18239
18366
|
var CONNECTORS_CONFIG_VERSION = 1;
|
|
18240
18367
|
var EnvRefUnsetError = class extends Error {
|
|
@@ -18249,11 +18376,11 @@ var EnvRefUnsetError = class extends Error {
|
|
|
18249
18376
|
};
|
|
18250
18377
|
function neatHome2() {
|
|
18251
18378
|
const override = process.env.NEAT_HOME;
|
|
18252
|
-
if (override && override.length > 0) return
|
|
18253
|
-
return
|
|
18379
|
+
if (override && override.length > 0) return import_node_path74.default.resolve(override);
|
|
18380
|
+
return import_node_path74.default.join(import_node_os4.default.homedir(), ".neat");
|
|
18254
18381
|
}
|
|
18255
18382
|
function connectorsConfigPath(home = neatHome2()) {
|
|
18256
|
-
return
|
|
18383
|
+
return import_node_path74.default.join(home, "connectors.json");
|
|
18257
18384
|
}
|
|
18258
18385
|
var MODE_MASK_LOOSER_THAN_0600 = 63;
|
|
18259
18386
|
async function warnIfModeLooserThan0600(file) {
|
|
@@ -18440,15 +18567,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
18440
18567
|
|
|
18441
18568
|
// src/connectors/index.ts
|
|
18442
18569
|
init_cjs_shims();
|
|
18443
|
-
var
|
|
18570
|
+
var import_types64 = require("@neat.is/types");
|
|
18444
18571
|
var NO_ENV = "unknown";
|
|
18445
18572
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
18446
18573
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
18447
18574
|
const sites = [];
|
|
18448
18575
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
18449
18576
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
18450
|
-
if (edge.provenance !==
|
|
18451
|
-
const parsed = (0,
|
|
18577
|
+
if (edge.provenance !== import_types64.Provenance.EXTRACTED) continue;
|
|
18578
|
+
const parsed = (0, import_types64.parseFileId)(edge.source);
|
|
18452
18579
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
18453
18580
|
const site = { relPath: edge.evidence.file };
|
|
18454
18581
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -18459,7 +18586,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
18459
18586
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
18460
18587
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
18461
18588
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
18462
|
-
if (attrs.type !==
|
|
18589
|
+
if (attrs.type !== import_types64.NodeType.RouteNode || !attrs.path) return void 0;
|
|
18463
18590
|
const site = { relPath: attrs.path };
|
|
18464
18591
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
18465
18592
|
return site;
|
|
@@ -18916,10 +19043,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
|
|
|
18916
19043
|
// src/connectors/supabase/map.ts
|
|
18917
19044
|
var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
|
|
18918
19045
|
var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
|
|
18919
|
-
function targetFromRestPath(
|
|
18920
|
-
const rpcMatch = REST_RPC_PATH_RE.exec(
|
|
19046
|
+
function targetFromRestPath(path77) {
|
|
19047
|
+
const rpcMatch = REST_RPC_PATH_RE.exec(path77);
|
|
18921
19048
|
if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
|
|
18922
|
-
const tableMatch = REST_TABLE_PATH_RE.exec(
|
|
19049
|
+
const tableMatch = REST_TABLE_PATH_RE.exec(path77);
|
|
18923
19050
|
if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
|
|
18924
19051
|
return null;
|
|
18925
19052
|
}
|
|
@@ -19030,23 +19157,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
19030
19157
|
|
|
19031
19158
|
// src/connectors/supabase/resolve.ts
|
|
19032
19159
|
init_cjs_shims();
|
|
19033
|
-
var
|
|
19160
|
+
var import_types66 = require("@neat.is/types");
|
|
19034
19161
|
function createSupabaseResolveTarget(graph, config) {
|
|
19035
19162
|
return (signal, _ctx) => {
|
|
19036
19163
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
19037
19164
|
return null;
|
|
19038
19165
|
}
|
|
19039
|
-
const subResourceId = (0,
|
|
19166
|
+
const subResourceId = (0, import_types66.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
19040
19167
|
if (graph.hasNode(subResourceId)) {
|
|
19041
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
19168
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types66.EdgeType.CALLS };
|
|
19042
19169
|
}
|
|
19043
|
-
const bareResourceId = (0,
|
|
19170
|
+
const bareResourceId = (0, import_types66.infraId)(signal.targetKind, signal.targetName);
|
|
19044
19171
|
if (graph.hasNode(bareResourceId)) {
|
|
19045
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
19172
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types66.EdgeType.CALLS };
|
|
19046
19173
|
}
|
|
19047
|
-
const projectLevelId = (0,
|
|
19174
|
+
const projectLevelId = (0, import_types66.infraId)("supabase", config.nodeRef);
|
|
19048
19175
|
if (graph.hasNode(projectLevelId)) {
|
|
19049
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
19176
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types66.EdgeType.CALLS };
|
|
19050
19177
|
}
|
|
19051
19178
|
return null;
|
|
19052
19179
|
};
|
|
@@ -19139,7 +19266,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
19139
19266
|
|
|
19140
19267
|
// src/connectors/railway/index.ts
|
|
19141
19268
|
init_cjs_shims();
|
|
19142
|
-
var
|
|
19269
|
+
var import_types70 = require("@neat.is/types");
|
|
19143
19270
|
|
|
19144
19271
|
// src/connectors/railway/client.ts
|
|
19145
19272
|
init_cjs_shims();
|
|
@@ -19290,7 +19417,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
19290
19417
|
const out = [];
|
|
19291
19418
|
graph.forEachNode((_id, attrs) => {
|
|
19292
19419
|
const node = attrs;
|
|
19293
|
-
if (node.type !==
|
|
19420
|
+
if (node.type !== import_types70.NodeType.RouteNode) return;
|
|
19294
19421
|
const route = attrs;
|
|
19295
19422
|
if (route.service !== serviceName) return;
|
|
19296
19423
|
out.push({
|
|
@@ -19394,12 +19521,12 @@ function createRailwayResolveTarget(config) {
|
|
|
19394
19521
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
19395
19522
|
if (!serviceName) return null;
|
|
19396
19523
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
19397
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
19524
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types70.EdgeType.CALLS };
|
|
19398
19525
|
}
|
|
19399
19526
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
19400
19527
|
const peerName = config.serviceNameById[signal.targetName];
|
|
19401
19528
|
if (!peerName) return null;
|
|
19402
|
-
return { targetNodeId: (0,
|
|
19529
|
+
return { targetNodeId: (0, import_types70.serviceId)(peerName), serviceName, edgeType: import_types70.EdgeType.CONNECTS_TO };
|
|
19403
19530
|
}
|
|
19404
19531
|
return null;
|
|
19405
19532
|
};
|
|
@@ -19523,9 +19650,9 @@ function parseFirebaseTargetName(targetName) {
|
|
|
19523
19650
|
const secondSep = rest.indexOf(FIELD_SEP);
|
|
19524
19651
|
if (secondSep === -1) return null;
|
|
19525
19652
|
const method = rest.slice(0, secondSep);
|
|
19526
|
-
const
|
|
19527
|
-
if (!resourceName || !method || !
|
|
19528
|
-
return { resourceName, method, path:
|
|
19653
|
+
const path77 = rest.slice(secondSep + 1);
|
|
19654
|
+
if (!resourceName || !method || !path77) return null;
|
|
19655
|
+
return { resourceName, method, path: path77 };
|
|
19529
19656
|
}
|
|
19530
19657
|
function resourceNameFor(type, labels) {
|
|
19531
19658
|
if (!labels) return null;
|
|
@@ -19563,14 +19690,14 @@ function mapLogEntryToSignal(entry) {
|
|
|
19563
19690
|
if (!req) return null;
|
|
19564
19691
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
19565
19692
|
const method = req.requestMethod.toUpperCase();
|
|
19566
|
-
const
|
|
19567
|
-
if (
|
|
19693
|
+
const path77 = pathFromRequestUrl(req.requestUrl);
|
|
19694
|
+
if (path77 === null) return null;
|
|
19568
19695
|
const timestamp = entry.timestamp;
|
|
19569
19696
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
19570
19697
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
|
|
19571
19698
|
return {
|
|
19572
19699
|
targetKind: resourceType,
|
|
19573
|
-
targetName: packFirebaseTargetName({ resourceName, method, path:
|
|
19700
|
+
targetName: packFirebaseTargetName({ resourceName, method, path: path77 }),
|
|
19574
19701
|
callCount: 1,
|
|
19575
19702
|
errorCount: isError ? 1 : 0,
|
|
19576
19703
|
lastObservedIso: timestamp
|
|
@@ -19587,7 +19714,7 @@ function mapLogEntriesToSignals(entries) {
|
|
|
19587
19714
|
|
|
19588
19715
|
// src/connectors/firebase/resolve.ts
|
|
19589
19716
|
init_cjs_shims();
|
|
19590
|
-
var
|
|
19717
|
+
var import_types71 = require("@neat.is/types");
|
|
19591
19718
|
function neatServiceNameFor(resourceType, resourceName, serviceMap) {
|
|
19592
19719
|
switch (resourceType) {
|
|
19593
19720
|
case "cloud_function":
|
|
@@ -19602,7 +19729,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
19602
19729
|
const entries = [];
|
|
19603
19730
|
graph.forEachNode((_id, attrs) => {
|
|
19604
19731
|
const node = attrs;
|
|
19605
|
-
if (node.type !==
|
|
19732
|
+
if (node.type !== import_types71.NodeType.RouteNode) return;
|
|
19606
19733
|
const route = attrs;
|
|
19607
19734
|
if (route.service !== serviceName) return;
|
|
19608
19735
|
entries.push({
|
|
@@ -19634,7 +19761,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
19634
19761
|
return {
|
|
19635
19762
|
targetNodeId: match.routeNodeId,
|
|
19636
19763
|
serviceName,
|
|
19637
|
-
edgeType:
|
|
19764
|
+
edgeType: import_types71.EdgeType.CALLS
|
|
19638
19765
|
};
|
|
19639
19766
|
};
|
|
19640
19767
|
}
|
|
@@ -19661,7 +19788,7 @@ init_cjs_shims();
|
|
|
19661
19788
|
|
|
19662
19789
|
// src/connectors/cloudflare/connector.ts
|
|
19663
19790
|
init_cjs_shims();
|
|
19664
|
-
var
|
|
19791
|
+
var import_types73 = require("@neat.is/types");
|
|
19665
19792
|
|
|
19666
19793
|
// src/connectors/cloudflare/client.ts
|
|
19667
19794
|
init_cjs_shims();
|
|
@@ -19777,7 +19904,7 @@ function mapEventToSignal(event) {
|
|
|
19777
19904
|
if (Number.isNaN(observedAt.getTime())) return null;
|
|
19778
19905
|
const statusCode = metadata?.statusCode;
|
|
19779
19906
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
19780
|
-
const
|
|
19907
|
+
const path77 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
19781
19908
|
return {
|
|
19782
19909
|
targetKind: CLOUDFLARE_TARGET_KIND,
|
|
19783
19910
|
targetName: scriptName,
|
|
@@ -19785,7 +19912,7 @@ function mapEventToSignal(event) {
|
|
|
19785
19912
|
errorCount: isError ? 1 : 0,
|
|
19786
19913
|
lastObservedIso: observedAt.toISOString(),
|
|
19787
19914
|
method,
|
|
19788
|
-
...
|
|
19915
|
+
...path77 ? { path: path77 } : {},
|
|
19789
19916
|
...typeof statusCode === "number" ? { statusCode } : {},
|
|
19790
19917
|
...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
|
|
19791
19918
|
};
|
|
@@ -19825,19 +19952,19 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
19825
19952
|
graph.forEachNode((id, attrs) => {
|
|
19826
19953
|
if (found) return;
|
|
19827
19954
|
const a = attrs;
|
|
19828
|
-
if (a.type ===
|
|
19955
|
+
if (a.type === import_types73.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
19829
19956
|
found = id;
|
|
19830
19957
|
}
|
|
19831
19958
|
});
|
|
19832
19959
|
return found;
|
|
19833
19960
|
}
|
|
19834
|
-
function findMatchingRouteNode(graph, serviceName, method,
|
|
19835
|
-
const normalizedPath = normalizePathTemplate(
|
|
19961
|
+
function findMatchingRouteNode(graph, serviceName, method, path77) {
|
|
19962
|
+
const normalizedPath = normalizePathTemplate(path77);
|
|
19836
19963
|
let found = null;
|
|
19837
19964
|
graph.forEachNode((id, attrs) => {
|
|
19838
19965
|
if (found) return;
|
|
19839
19966
|
const a = attrs;
|
|
19840
|
-
if (a.type !==
|
|
19967
|
+
if (a.type !== import_types73.NodeType.RouteNode || a.service !== serviceName) return;
|
|
19841
19968
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
19842
19969
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
19843
19970
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -19849,18 +19976,18 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
19849
19976
|
return (signal) => {
|
|
19850
19977
|
if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
|
|
19851
19978
|
const scriptName = signal.targetName;
|
|
19852
|
-
const { method, path:
|
|
19979
|
+
const { method, path: path77 } = signal;
|
|
19853
19980
|
const resolveRouteGrain = (serviceName, wholeFileId) => {
|
|
19854
|
-
if (!method || !
|
|
19855
|
-
return findMatchingRouteNode(graph, serviceName, method,
|
|
19981
|
+
if (!method || !path77) return wholeFileId;
|
|
19982
|
+
return findMatchingRouteNode(graph, serviceName, method, path77) ?? wholeFileId;
|
|
19856
19983
|
};
|
|
19857
19984
|
const mapping = config.workers?.[scriptName];
|
|
19858
19985
|
if (mapping) {
|
|
19859
|
-
const wholeFileId = (0,
|
|
19986
|
+
const wholeFileId = (0, import_types73.fileId)(mapping.service, mapping.entryFile);
|
|
19860
19987
|
return {
|
|
19861
19988
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
19862
19989
|
serviceName: mapping.service,
|
|
19863
|
-
edgeType:
|
|
19990
|
+
edgeType: import_types73.EdgeType.CALLS
|
|
19864
19991
|
};
|
|
19865
19992
|
}
|
|
19866
19993
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -19869,13 +19996,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
19869
19996
|
return {
|
|
19870
19997
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
19871
19998
|
serviceName: fileNode.service,
|
|
19872
|
-
edgeType:
|
|
19999
|
+
edgeType: import_types73.EdgeType.CALLS
|
|
19873
20000
|
};
|
|
19874
20001
|
}
|
|
19875
20002
|
return {
|
|
19876
|
-
targetNodeId: (0,
|
|
20003
|
+
targetNodeId: (0, import_types73.infraId)("cloudflare-worker", scriptName),
|
|
19877
20004
|
serviceName: scriptName,
|
|
19878
|
-
edgeType:
|
|
20005
|
+
edgeType: import_types73.EdgeType.CALLS,
|
|
19879
20006
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
19880
20007
|
};
|
|
19881
20008
|
};
|
|
@@ -20071,14 +20198,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
20071
20198
|
|
|
20072
20199
|
// src/connectors/neon/resolve.ts
|
|
20073
20200
|
init_cjs_shims();
|
|
20074
|
-
var
|
|
20201
|
+
var import_types77 = require("@neat.is/types");
|
|
20075
20202
|
function createNeonResolveTarget(config) {
|
|
20076
20203
|
return (signal) => {
|
|
20077
20204
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
20078
20205
|
return {
|
|
20079
|
-
targetNodeId: (0,
|
|
20206
|
+
targetNodeId: (0, import_types77.infraId)("sql-table", signal.targetName),
|
|
20080
20207
|
serviceName: config.serviceName,
|
|
20081
|
-
edgeType:
|
|
20208
|
+
edgeType: import_types77.EdgeType.CALLS,
|
|
20082
20209
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
20083
20210
|
};
|
|
20084
20211
|
};
|
|
@@ -20204,9 +20331,9 @@ function parseCloudRunTargetName(targetName) {
|
|
|
20204
20331
|
const secondSep = rest.indexOf(FIELD_SEP2);
|
|
20205
20332
|
if (secondSep === -1) return null;
|
|
20206
20333
|
const method = rest.slice(0, secondSep);
|
|
20207
|
-
const
|
|
20208
|
-
if (!serviceName || !method || !
|
|
20209
|
-
return { serviceName, method, path:
|
|
20334
|
+
const path77 = rest.slice(secondSep + 1);
|
|
20335
|
+
if (!serviceName || !method || !path77) return null;
|
|
20336
|
+
return { serviceName, method, path: path77 };
|
|
20210
20337
|
}
|
|
20211
20338
|
|
|
20212
20339
|
// src/connectors/cloud-run/map.ts
|
|
@@ -20235,14 +20362,14 @@ function mapLogEntryToSignal2(entry) {
|
|
|
20235
20362
|
if (!req) return null;
|
|
20236
20363
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
20237
20364
|
const method = req.requestMethod.toUpperCase();
|
|
20238
|
-
const
|
|
20239
|
-
if (
|
|
20365
|
+
const path77 = pathFromRequestUrl2(req.requestUrl);
|
|
20366
|
+
if (path77 === null) return null;
|
|
20240
20367
|
const timestamp = entry.timestamp;
|
|
20241
20368
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
20242
20369
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD4;
|
|
20243
20370
|
return {
|
|
20244
20371
|
targetKind: CLOUD_RUN_TARGET_KIND,
|
|
20245
|
-
targetName: packCloudRunTargetName({ serviceName, method, path:
|
|
20372
|
+
targetName: packCloudRunTargetName({ serviceName, method, path: path77 }),
|
|
20246
20373
|
callCount: 1,
|
|
20247
20374
|
errorCount: isError ? 1 : 0,
|
|
20248
20375
|
lastObservedIso: timestamp
|
|
@@ -20259,14 +20386,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
20259
20386
|
|
|
20260
20387
|
// src/connectors/cloud-run/resolve.ts
|
|
20261
20388
|
init_cjs_shims();
|
|
20262
|
-
var
|
|
20389
|
+
var import_types81 = require("@neat.is/types");
|
|
20263
20390
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
20264
20391
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
20265
20392
|
let found = null;
|
|
20266
20393
|
graph.forEachNode((_id, attrs) => {
|
|
20267
20394
|
if (found) return;
|
|
20268
20395
|
const node = attrs;
|
|
20269
|
-
if (node.type !==
|
|
20396
|
+
if (node.type !== import_types81.NodeType.RouteNode) return;
|
|
20270
20397
|
const route = attrs;
|
|
20271
20398
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
20272
20399
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -20281,23 +20408,23 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
20281
20408
|
if (signal.targetKind !== CLOUD_RUN_TARGET_KIND) return null;
|
|
20282
20409
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
20283
20410
|
if (!identity) return null;
|
|
20284
|
-
const { serviceName: gcpServiceName, method, path:
|
|
20411
|
+
const { serviceName: gcpServiceName, method, path: path77 } = identity;
|
|
20285
20412
|
const mappedService = config.serviceMap?.[gcpServiceName];
|
|
20286
20413
|
if (mappedService) {
|
|
20287
20414
|
const routeNodeId = findMatchingRouteNode2(
|
|
20288
20415
|
graph,
|
|
20289
20416
|
mappedService,
|
|
20290
20417
|
method,
|
|
20291
|
-
normalizePathTemplate(
|
|
20418
|
+
normalizePathTemplate(path77)
|
|
20292
20419
|
);
|
|
20293
20420
|
if (routeNodeId) {
|
|
20294
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
20421
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types81.EdgeType.CALLS };
|
|
20295
20422
|
}
|
|
20296
20423
|
}
|
|
20297
20424
|
return {
|
|
20298
|
-
targetNodeId: (0,
|
|
20425
|
+
targetNodeId: (0, import_types81.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
20299
20426
|
serviceName: mappedService ?? gcpServiceName,
|
|
20300
|
-
edgeType:
|
|
20427
|
+
edgeType: import_types81.EdgeType.CALLS,
|
|
20301
20428
|
ensureInfraNode: {
|
|
20302
20429
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
20303
20430
|
name: gcpServiceName,
|
|
@@ -20424,9 +20551,9 @@ function parseGcpLbTargetName(targetName) {
|
|
|
20424
20551
|
const secondSep = rest.indexOf(FIELD_SEP3);
|
|
20425
20552
|
if (secondSep === -1) return null;
|
|
20426
20553
|
const method = rest.slice(0, secondSep);
|
|
20427
|
-
const
|
|
20428
|
-
if (!backendServiceName || !method || !
|
|
20429
|
-
return { backendServiceName, method, path:
|
|
20554
|
+
const path77 = rest.slice(secondSep + 1);
|
|
20555
|
+
if (!backendServiceName || !method || !path77) return null;
|
|
20556
|
+
return { backendServiceName, method, path: path77 };
|
|
20430
20557
|
}
|
|
20431
20558
|
|
|
20432
20559
|
// src/connectors/gcp-lb/map.ts
|
|
@@ -20455,14 +20582,14 @@ function mapLogEntryToSignal3(entry) {
|
|
|
20455
20582
|
if (!req) return null;
|
|
20456
20583
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
20457
20584
|
const method = req.requestMethod.toUpperCase();
|
|
20458
|
-
const
|
|
20459
|
-
if (
|
|
20585
|
+
const path77 = pathFromRequestUrl3(req.requestUrl);
|
|
20586
|
+
if (path77 === null) return null;
|
|
20460
20587
|
const timestamp = entry.timestamp;
|
|
20461
20588
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
20462
20589
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD5;
|
|
20463
20590
|
return {
|
|
20464
20591
|
targetKind: GCP_LB_TARGET_KIND,
|
|
20465
|
-
targetName: packGcpLbTargetName({ backendServiceName, method, path:
|
|
20592
|
+
targetName: packGcpLbTargetName({ backendServiceName, method, path: path77 }),
|
|
20466
20593
|
callCount: 1,
|
|
20467
20594
|
errorCount: isError ? 1 : 0,
|
|
20468
20595
|
lastObservedIso: timestamp
|
|
@@ -20479,14 +20606,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
20479
20606
|
|
|
20480
20607
|
// src/connectors/gcp-lb/resolve.ts
|
|
20481
20608
|
init_cjs_shims();
|
|
20482
|
-
var
|
|
20609
|
+
var import_types85 = require("@neat.is/types");
|
|
20483
20610
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
20484
20611
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
20485
20612
|
let found = null;
|
|
20486
20613
|
graph.forEachNode((_id, attrs) => {
|
|
20487
20614
|
if (found) return;
|
|
20488
20615
|
const node = attrs;
|
|
20489
|
-
if (node.type !==
|
|
20616
|
+
if (node.type !== import_types85.NodeType.RouteNode) return;
|
|
20490
20617
|
const route = attrs;
|
|
20491
20618
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
20492
20619
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -20501,23 +20628,23 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
20501
20628
|
if (signal.targetKind !== GCP_LB_TARGET_KIND) return null;
|
|
20502
20629
|
const identity = parseGcpLbTargetName(signal.targetName);
|
|
20503
20630
|
if (!identity) return null;
|
|
20504
|
-
const { backendServiceName, method, path:
|
|
20631
|
+
const { backendServiceName, method, path: path77 } = identity;
|
|
20505
20632
|
const mappedService = config.backendServiceMap?.[backendServiceName];
|
|
20506
20633
|
if (mappedService) {
|
|
20507
20634
|
const routeNodeId = findMatchingRouteNode3(
|
|
20508
20635
|
graph,
|
|
20509
20636
|
mappedService,
|
|
20510
20637
|
method,
|
|
20511
|
-
normalizePathTemplate(
|
|
20638
|
+
normalizePathTemplate(path77)
|
|
20512
20639
|
);
|
|
20513
20640
|
if (routeNodeId) {
|
|
20514
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
20641
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
|
|
20515
20642
|
}
|
|
20516
20643
|
}
|
|
20517
20644
|
return {
|
|
20518
|
-
targetNodeId: (0,
|
|
20645
|
+
targetNodeId: (0, import_types85.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
20519
20646
|
serviceName: mappedService ?? backendServiceName,
|
|
20520
|
-
edgeType:
|
|
20647
|
+
edgeType: import_types85.EdgeType.CALLS,
|
|
20521
20648
|
ensureInfraNode: {
|
|
20522
20649
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
20523
20650
|
name: backendServiceName,
|
|
@@ -20558,7 +20685,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
20558
20685
|
|
|
20559
20686
|
// src/connectors/render/index.ts
|
|
20560
20687
|
init_cjs_shims();
|
|
20561
|
-
var
|
|
20688
|
+
var import_types88 = require("@neat.is/types");
|
|
20562
20689
|
|
|
20563
20690
|
// src/connectors/render/types.ts
|
|
20564
20691
|
init_cjs_shims();
|
|
@@ -20636,7 +20763,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
20636
20763
|
const out = [];
|
|
20637
20764
|
graph.forEachNode((_id, attrs) => {
|
|
20638
20765
|
const node = attrs;
|
|
20639
|
-
if (node.type !==
|
|
20766
|
+
if (node.type !== import_types88.NodeType.RouteNode) return;
|
|
20640
20767
|
const route = attrs;
|
|
20641
20768
|
if (route.service !== serviceName) return;
|
|
20642
20769
|
out.push({
|
|
@@ -20721,7 +20848,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
20721
20848
|
function createRenderResolveTarget(config) {
|
|
20722
20849
|
return (signal) => {
|
|
20723
20850
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
20724
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
20851
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types88.EdgeType.CALLS };
|
|
20725
20852
|
}
|
|
20726
20853
|
return null;
|
|
20727
20854
|
};
|
|
@@ -20859,21 +20986,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
20859
20986
|
|
|
20860
20987
|
// src/connectors/planetscale/resolve.ts
|
|
20861
20988
|
init_cjs_shims();
|
|
20862
|
-
var
|
|
20989
|
+
var import_types92 = require("@neat.is/types");
|
|
20863
20990
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
20864
20991
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
20865
20992
|
const databaseName = `${config.organization}/${config.database}`;
|
|
20866
20993
|
return (signal, _ctx) => {
|
|
20867
20994
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
20868
|
-
const tableId = (0,
|
|
20995
|
+
const tableId = (0, import_types92.infraId)("sql-table", signal.targetName);
|
|
20869
20996
|
if (graph.hasNode(tableId)) {
|
|
20870
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
20997
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types92.EdgeType.CALLS };
|
|
20871
20998
|
}
|
|
20872
|
-
const providerId = (0,
|
|
20999
|
+
const providerId = (0, import_types92.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
20873
21000
|
return {
|
|
20874
21001
|
targetNodeId: providerId,
|
|
20875
21002
|
serviceName: config.serviceName,
|
|
20876
|
-
edgeType:
|
|
21003
|
+
edgeType: import_types92.EdgeType.CALLS,
|
|
20877
21004
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
20878
21005
|
};
|
|
20879
21006
|
};
|
|
@@ -21138,7 +21265,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
21138
21265
|
|
|
21139
21266
|
// src/connectors/eas/resolve.ts
|
|
21140
21267
|
init_cjs_shims();
|
|
21141
|
-
var
|
|
21268
|
+
var import_types97 = require("@neat.is/types");
|
|
21142
21269
|
var NO_ENV2 = "unknown";
|
|
21143
21270
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
21144
21271
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -21154,8 +21281,8 @@ function configBasenamesForPhase(phase) {
|
|
|
21154
21281
|
function configNodeService(graph, configNodeId) {
|
|
21155
21282
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
21156
21283
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
21157
|
-
if (edge.type !==
|
|
21158
|
-
const parsed = (0,
|
|
21284
|
+
if (edge.type !== import_types97.EdgeType.CONFIGURED_BY) continue;
|
|
21285
|
+
const parsed = (0, import_types97.parseFileId)(edge.source);
|
|
21159
21286
|
if (parsed) return parsed.service;
|
|
21160
21287
|
}
|
|
21161
21288
|
return null;
|
|
@@ -21166,7 +21293,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
21166
21293
|
graph.forEachNode((id, attrs) => {
|
|
21167
21294
|
if (scoped) return;
|
|
21168
21295
|
const node = attrs;
|
|
21169
|
-
if (node.type !==
|
|
21296
|
+
if (node.type !== import_types97.NodeType.ConfigNode) return;
|
|
21170
21297
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
21171
21298
|
if (anyMatch === null) anyMatch = id;
|
|
21172
21299
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -21183,13 +21310,13 @@ function createEasResolveTarget(graph) {
|
|
|
21183
21310
|
if (basenames.length > 0) {
|
|
21184
21311
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
21185
21312
|
if (configNodeId) {
|
|
21186
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
21313
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types97.EdgeType.CALLS };
|
|
21187
21314
|
}
|
|
21188
21315
|
}
|
|
21189
21316
|
return {
|
|
21190
21317
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
21191
21318
|
serviceName,
|
|
21192
|
-
edgeType:
|
|
21319
|
+
edgeType: import_types97.EdgeType.CALLS
|
|
21193
21320
|
};
|
|
21194
21321
|
};
|
|
21195
21322
|
}
|
|
@@ -21904,11 +22031,11 @@ function registerRoutes(scope, ctx) {
|
|
|
21904
22031
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
21905
22032
|
const parsed = [];
|
|
21906
22033
|
for (const c of candidates) {
|
|
21907
|
-
const r =
|
|
22034
|
+
const r = import_types100.DivergenceTypeSchema.safeParse(c);
|
|
21908
22035
|
if (!r.success) {
|
|
21909
22036
|
return reply.code(400).send({
|
|
21910
22037
|
error: `unknown divergence type "${c}"`,
|
|
21911
|
-
allowed:
|
|
22038
|
+
allowed: import_types100.DivergenceTypeSchema.options
|
|
21912
22039
|
});
|
|
21913
22040
|
}
|
|
21914
22041
|
parsed.push(r.data);
|
|
@@ -22304,7 +22431,7 @@ function registerRoutes(scope, ctx) {
|
|
|
22304
22431
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
22305
22432
|
let violations = await log.readAll();
|
|
22306
22433
|
if (req.query.severity) {
|
|
22307
|
-
const sev =
|
|
22434
|
+
const sev = import_types100.PolicySeveritySchema.safeParse(req.query.severity);
|
|
22308
22435
|
if (!sev.success) {
|
|
22309
22436
|
return reply.code(400).send({
|
|
22310
22437
|
error: "invalid severity",
|
|
@@ -22343,7 +22470,7 @@ function registerRoutes(scope, ctx) {
|
|
|
22343
22470
|
scope.post("/policies/check", async (req, reply) => {
|
|
22344
22471
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
22345
22472
|
if (!proj) return;
|
|
22346
|
-
const parsed =
|
|
22473
|
+
const parsed = import_types100.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
22347
22474
|
if (!parsed.success) {
|
|
22348
22475
|
return reply.code(400).send({
|
|
22349
22476
|
error: "invalid /policies/check body",
|
|
@@ -22665,7 +22792,7 @@ init_otel_grpc();
|
|
|
22665
22792
|
// src/search.ts
|
|
22666
22793
|
init_cjs_shims();
|
|
22667
22794
|
var import_node_fs39 = require("fs");
|
|
22668
|
-
var
|
|
22795
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
22669
22796
|
var import_node_crypto4 = require("crypto");
|
|
22670
22797
|
var DEFAULT_LIMIT = 10;
|
|
22671
22798
|
var NOMIC_DIM = 768;
|
|
@@ -22828,7 +22955,7 @@ async function readCache(cachePath) {
|
|
|
22828
22955
|
}
|
|
22829
22956
|
}
|
|
22830
22957
|
async function writeCache(cachePath, cache) {
|
|
22831
|
-
await import_node_fs39.promises.mkdir(
|
|
22958
|
+
await import_node_fs39.promises.mkdir(import_node_path75.default.dirname(cachePath), { recursive: true });
|
|
22832
22959
|
await import_node_fs39.promises.writeFile(cachePath, JSON.stringify(cache));
|
|
22833
22960
|
}
|
|
22834
22961
|
var VectorIndex = class {
|
|
@@ -23043,14 +23170,14 @@ async function bootProject(registry, name, scanPath, baseDir) {
|
|
|
23043
23170
|
async function main() {
|
|
23044
23171
|
const baseDirEnv = process.env.NEAT_OUT_DIR;
|
|
23045
23172
|
const legacyOutPath = process.env.NEAT_OUT_PATH;
|
|
23046
|
-
const baseDir = baseDirEnv ?
|
|
23047
|
-
const defaultScanPath =
|
|
23173
|
+
const baseDir = baseDirEnv ? import_node_path76.default.resolve(baseDirEnv) : legacyOutPath ? import_node_path76.default.resolve(import_node_path76.default.dirname(legacyOutPath)) : import_node_path76.default.resolve("./neat-out");
|
|
23174
|
+
const defaultScanPath = import_node_path76.default.resolve(process.env.NEAT_SCAN_PATH ?? "./demo");
|
|
23048
23175
|
const registry = new Projects();
|
|
23049
23176
|
await bootProject(registry, DEFAULT_PROJECT, defaultScanPath, baseDir);
|
|
23050
23177
|
for (const name of parseExtraProjects(process.env.NEAT_PROJECTS)) {
|
|
23051
23178
|
const envKey = `NEAT_PROJECT_SCAN_PATH_${name.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
|
|
23052
23179
|
const projectScan = process.env[envKey];
|
|
23053
|
-
await bootProject(registry, name, projectScan ?
|
|
23180
|
+
await bootProject(registry, name, projectScan ? import_node_path76.default.resolve(projectScan) : void 0, baseDir);
|
|
23054
23181
|
}
|
|
23055
23182
|
const host = process.env.HOST ?? "0.0.0.0";
|
|
23056
23183
|
const port = Number(process.env.PORT ?? 8080);
|