@neat.is/core 0.8.1 → 0.8.2-dev.20260818
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-ZGZYZ33B.js → chunk-T4UGEMWN.js} +1072 -471
- package/dist/chunk-T4UGEMWN.js.map +1 -0
- package/dist/{chunk-RQTW7IV3.js → chunk-WLCHTXO3.js} +2 -2
- package/dist/cli.cjs +1648 -1044
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.cjs +1336 -732
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +1349 -745
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +1243 -639
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +4 -2
- package/dist/chunk-ZGZYZ33B.js.map +0 -1
- /package/dist/{chunk-RQTW7IV3.js.map → chunk-WLCHTXO3.js.map} +0 -0
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 path71 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
63
|
+
if (exactUnauthPaths.has(path71) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path71)) {
|
|
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_path50.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
196
|
+
return import_node_path50.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_path50, 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_path50 = __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 path71 = q === -1 ? v : v.slice(0, q);
|
|
417
|
+
if (path71.length > 0) return path71;
|
|
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_path51.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
|
|
480
|
+
const protoRoot = import_node_path51.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_path51.default.resolve(protoRoot, target);
|
|
483
483
|
root.loadSync(
|
|
484
484
|
"opentelemetry/proto/collector/trace/v1/trace_service.proto",
|
|
485
485
|
{ keepCase: true }
|
|
@@ -710,12 +710,12 @@ async function buildOtelReceiver(opts) {
|
|
|
710
710
|
};
|
|
711
711
|
return decorated;
|
|
712
712
|
}
|
|
713
|
-
var
|
|
713
|
+
var import_node_path51, import_node_url2, import_fastify, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody;
|
|
714
714
|
var init_otel = __esm({
|
|
715
715
|
"src/otel.ts"() {
|
|
716
716
|
"use strict";
|
|
717
717
|
init_cjs_shims();
|
|
718
|
-
|
|
718
|
+
import_node_path51 = __toESM(require("path"), 1);
|
|
719
719
|
import_node_url2 = require("url");
|
|
720
720
|
import_fastify = __toESM(require("fastify"), 1);
|
|
721
721
|
import_protobufjs = __toESM(require("protobufjs"), 1);
|
|
@@ -731,7 +731,7 @@ var init_otel = __esm({
|
|
|
731
731
|
|
|
732
732
|
// src/server.ts
|
|
733
733
|
init_cjs_shims();
|
|
734
|
-
var
|
|
734
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
735
735
|
|
|
736
736
|
// src/graph.ts
|
|
737
737
|
init_cjs_shims();
|
|
@@ -755,7 +755,7 @@ function getGraph(project = DEFAULT_PROJECT) {
|
|
|
755
755
|
init_cjs_shims();
|
|
756
756
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
757
757
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
758
|
-
var
|
|
758
|
+
var import_types88 = require("@neat.is/types");
|
|
759
759
|
|
|
760
760
|
// src/extend/index.ts
|
|
761
761
|
init_cjs_shims();
|
|
@@ -2015,7 +2015,7 @@ var import_node_fs5 = require("fs");
|
|
|
2015
2015
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
2016
2016
|
var import_yaml = require("yaml");
|
|
2017
2017
|
var import_types3 = require("@neat.is/types");
|
|
2018
|
-
var SERVICE_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs", ".ts", ".tsx", ".py", ".go", ".rb", ".php"]);
|
|
2018
|
+
var SERVICE_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs", ".ts", ".tsx", ".py", ".go", ".rb", ".php", ".cs", ".java"]);
|
|
2019
2019
|
var CONFIG_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".yaml", ".yml"]);
|
|
2020
2020
|
var JSON_CONFIG_FILENAMES = /* @__PURE__ */ new Set(["app.json", "app.config.json", "eas.json"]);
|
|
2021
2021
|
var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -2338,6 +2338,10 @@ function languageForPath(relPath) {
|
|
|
2338
2338
|
return "ruby";
|
|
2339
2339
|
case ".php":
|
|
2340
2340
|
return "php";
|
|
2341
|
+
case ".cs":
|
|
2342
|
+
return "csharp";
|
|
2343
|
+
case ".java":
|
|
2344
|
+
return "java";
|
|
2341
2345
|
case ".ts":
|
|
2342
2346
|
case ".tsx":
|
|
2343
2347
|
return "typescript";
|
|
@@ -2874,8 +2878,8 @@ function chiRoutesFromSource(source, parser) {
|
|
|
2874
2878
|
chiWalk(tree.rootNode, "", out);
|
|
2875
2879
|
return out;
|
|
2876
2880
|
}
|
|
2877
|
-
function stripChiRegex(
|
|
2878
|
-
return
|
|
2881
|
+
function stripChiRegex(path71) {
|
|
2882
|
+
return path71.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
|
|
2879
2883
|
}
|
|
2880
2884
|
function chiWalk(node, prefix, out) {
|
|
2881
2885
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
@@ -3547,9 +3551,9 @@ function rubyRocketRoute(args) {
|
|
|
3547
3551
|
if (!pair || pair.type !== "pair") continue;
|
|
3548
3552
|
const k = pair.childForFieldName("key");
|
|
3549
3553
|
if (k?.type !== "string") continue;
|
|
3550
|
-
const
|
|
3551
|
-
if (
|
|
3552
|
-
return { path:
|
|
3554
|
+
const path71 = rubyLiteral(k);
|
|
3555
|
+
if (path71 === null) continue;
|
|
3556
|
+
return { path: path71, target: rubyLiteral(pair.childForFieldName("value")) };
|
|
3553
3557
|
}
|
|
3554
3558
|
return null;
|
|
3555
3559
|
}
|
|
@@ -5592,29 +5596,29 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
5592
5596
|
toPromote.push({ frontierId: id, serviceId: target });
|
|
5593
5597
|
});
|
|
5594
5598
|
let promoted = 0;
|
|
5595
|
-
for (const { frontierId: frontierId2, serviceId:
|
|
5599
|
+
for (const { frontierId: frontierId2, serviceId: serviceId12 } of toPromote) {
|
|
5596
5600
|
if (opts.policies && opts.policies.length > 0 && opts.policyCtx) {
|
|
5597
5601
|
const gate = canPromoteFrontier(graph, frontierId2, opts.policies, opts.policyCtx);
|
|
5598
5602
|
if (!gate.allowed) {
|
|
5599
5603
|
continue;
|
|
5600
5604
|
}
|
|
5601
5605
|
}
|
|
5602
|
-
rewireFrontierEdges(graph, frontierId2,
|
|
5606
|
+
rewireFrontierEdges(graph, frontierId2, serviceId12);
|
|
5603
5607
|
graph.dropNode(frontierId2);
|
|
5604
5608
|
promoted++;
|
|
5605
5609
|
}
|
|
5606
5610
|
return promoted;
|
|
5607
5611
|
}
|
|
5608
|
-
function rewireFrontierEdges(graph, frontierId2,
|
|
5612
|
+
function rewireFrontierEdges(graph, frontierId2, serviceId12) {
|
|
5609
5613
|
const inbound = [...graph.inboundEdges(frontierId2)];
|
|
5610
5614
|
const outbound = [...graph.outboundEdges(frontierId2)];
|
|
5611
5615
|
for (const edgeId of inbound) {
|
|
5612
5616
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
5613
|
-
rebuildEdge(graph, edge, edge.source,
|
|
5617
|
+
rebuildEdge(graph, edge, edge.source, serviceId12, edgeId);
|
|
5614
5618
|
}
|
|
5615
5619
|
for (const edgeId of outbound) {
|
|
5616
5620
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
5617
|
-
rebuildEdge(graph, edge,
|
|
5621
|
+
rebuildEdge(graph, edge, serviceId12, edge.target, edgeId);
|
|
5618
5622
|
}
|
|
5619
5623
|
}
|
|
5620
5624
|
function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
@@ -5933,19 +5937,19 @@ function confidenceFromMix(edges, now = Date.now()) {
|
|
|
5933
5937
|
function longestIncomingWalk(graph, start, maxDepth) {
|
|
5934
5938
|
let best = { path: [start], edges: [] };
|
|
5935
5939
|
const visited = /* @__PURE__ */ new Set([start]);
|
|
5936
|
-
function step(node,
|
|
5937
|
-
if (
|
|
5938
|
-
best = { path: [...
|
|
5940
|
+
function step(node, path71, edges) {
|
|
5941
|
+
if (path71.length > best.path.length) {
|
|
5942
|
+
best = { path: [...path71], edges: [...edges] };
|
|
5939
5943
|
}
|
|
5940
|
-
if (
|
|
5944
|
+
if (path71.length - 1 >= maxDepth) return;
|
|
5941
5945
|
const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
|
|
5942
5946
|
for (const [srcId, edge] of incoming) {
|
|
5943
5947
|
if (visited.has(srcId)) continue;
|
|
5944
5948
|
visited.add(srcId);
|
|
5945
|
-
|
|
5949
|
+
path71.push(srcId);
|
|
5946
5950
|
edges.push(edge);
|
|
5947
|
-
step(srcId,
|
|
5948
|
-
|
|
5951
|
+
step(srcId, path71, edges);
|
|
5952
|
+
path71.pop();
|
|
5949
5953
|
edges.pop();
|
|
5950
5954
|
visited.delete(srcId);
|
|
5951
5955
|
}
|
|
@@ -5960,7 +5964,7 @@ function databaseRootCauseShape(graph, origin, walk9) {
|
|
|
5960
5964
|
for (const id of walk9.path) {
|
|
5961
5965
|
const owner = resolveOwningService(graph, id);
|
|
5962
5966
|
if (!owner) continue;
|
|
5963
|
-
const { id:
|
|
5967
|
+
const { id: serviceId12, svc } = owner;
|
|
5964
5968
|
const deps = svc.dependencies ?? {};
|
|
5965
5969
|
for (const pair of candidatePairs) {
|
|
5966
5970
|
const declared = deps[pair.driver];
|
|
@@ -5973,7 +5977,7 @@ function databaseRootCauseShape(graph, origin, walk9) {
|
|
|
5973
5977
|
);
|
|
5974
5978
|
if (!result.compatible) {
|
|
5975
5979
|
return {
|
|
5976
|
-
rootCauseNode:
|
|
5980
|
+
rootCauseNode: serviceId12,
|
|
5977
5981
|
rootCauseReason: result.reason ?? "incompatible driver",
|
|
5978
5982
|
...result.minDriverVersion ? {
|
|
5979
5983
|
fixRecommendation: `Upgrade ${svc.name} ${pair.driver} driver to >= ${result.minDriverVersion}`
|
|
@@ -5988,7 +5992,7 @@ function serviceRootCauseShape(graph, _origin, walk9) {
|
|
|
5988
5992
|
for (const id of walk9.path) {
|
|
5989
5993
|
const owner = resolveOwningService(graph, id);
|
|
5990
5994
|
if (!owner) continue;
|
|
5991
|
-
const { id:
|
|
5995
|
+
const { id: serviceId12, svc } = owner;
|
|
5992
5996
|
const deps = svc.dependencies ?? {};
|
|
5993
5997
|
const serviceNodeEngine = svc.nodeEngine;
|
|
5994
5998
|
for (const constraint of nodeEngineConstraints()) {
|
|
@@ -5997,7 +6001,7 @@ function serviceRootCauseShape(graph, _origin, walk9) {
|
|
|
5997
6001
|
const result = checkNodeEngineConstraint(constraint, declared, serviceNodeEngine);
|
|
5998
6002
|
if (!result.compatible && result.reason) {
|
|
5999
6003
|
return {
|
|
6000
|
-
rootCauseNode:
|
|
6004
|
+
rootCauseNode: serviceId12,
|
|
6001
6005
|
rootCauseReason: result.reason,
|
|
6002
6006
|
...result.requiredNodeVersion ? {
|
|
6003
6007
|
fixRecommendation: `Bump ${svc.name}'s engines.node to >= ${result.requiredNodeVersion}`
|
|
@@ -6012,7 +6016,7 @@ function serviceRootCauseShape(graph, _origin, walk9) {
|
|
|
6012
6016
|
const result = checkPackageConflict(conflict, declared, requiredDeclared);
|
|
6013
6017
|
if (!result.compatible && result.reason) {
|
|
6014
6018
|
return {
|
|
6015
|
-
rootCauseNode:
|
|
6019
|
+
rootCauseNode: serviceId12,
|
|
6016
6020
|
rootCauseReason: result.reason,
|
|
6017
6021
|
fixRecommendation: `Upgrade ${svc.name}'s ${conflict.requires.name} to >= ${conflict.requires.minVersion}`
|
|
6018
6022
|
};
|
|
@@ -6113,9 +6117,9 @@ function rootCauseFromIncidents(nodeId, incidents, errorEvent) {
|
|
|
6113
6117
|
function isFailingCallEdge(e) {
|
|
6114
6118
|
return e.type === import_types8.EdgeType.CALLS && (e.signal?.errorCount ?? 0) > 0;
|
|
6115
6119
|
}
|
|
6116
|
-
function callSourcesForService(graph,
|
|
6117
|
-
const ids = [
|
|
6118
|
-
for (const edgeId of graph.outboundEdges(
|
|
6120
|
+
function callSourcesForService(graph, serviceId12) {
|
|
6121
|
+
const ids = [serviceId12];
|
|
6122
|
+
for (const edgeId of graph.outboundEdges(serviceId12)) {
|
|
6119
6123
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6120
6124
|
if (e.type !== import_types8.EdgeType.CONTAINS) continue;
|
|
6121
6125
|
const tgt = graph.getNodeAttributes(e.target);
|
|
@@ -6139,9 +6143,9 @@ function failingCallDominates(e, id, curEdge, curId) {
|
|
|
6139
6143
|
}
|
|
6140
6144
|
return id < curId;
|
|
6141
6145
|
}
|
|
6142
|
-
function dominantFailingCall(graph,
|
|
6146
|
+
function dominantFailingCall(graph, serviceId12, visited) {
|
|
6143
6147
|
let best = null;
|
|
6144
|
-
for (const src of callSourcesForService(graph,
|
|
6148
|
+
for (const src of callSourcesForService(graph, serviceId12)) {
|
|
6145
6149
|
for (const edgeId of graph.outboundEdges(src)) {
|
|
6146
6150
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6147
6151
|
if (!isFailingCallEdge(e)) continue;
|
|
@@ -6156,26 +6160,26 @@ function dominantFailingCall(graph, serviceId9, visited) {
|
|
|
6156
6160
|
return best;
|
|
6157
6161
|
}
|
|
6158
6162
|
function followFailingCallChain(graph, originServiceId, maxDepth) {
|
|
6159
|
-
const
|
|
6163
|
+
const path71 = [originServiceId];
|
|
6160
6164
|
const edges = [];
|
|
6161
6165
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
6162
6166
|
let current = originServiceId;
|
|
6163
6167
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
6164
6168
|
const hop = dominantFailingCall(graph, current, visited);
|
|
6165
6169
|
if (!hop) break;
|
|
6166
|
-
|
|
6170
|
+
path71.push(hop.nextService);
|
|
6167
6171
|
edges.push(hop.edge);
|
|
6168
6172
|
visited.add(hop.nextService);
|
|
6169
6173
|
current = hop.nextService;
|
|
6170
6174
|
}
|
|
6171
6175
|
if (edges.length === 0) return null;
|
|
6172
|
-
return { path:
|
|
6176
|
+
return { path: path71, edges, culprit: current };
|
|
6173
6177
|
}
|
|
6174
6178
|
function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
6175
6179
|
const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
|
|
6176
6180
|
if (!chain) return null;
|
|
6177
6181
|
const culprit = chain.culprit;
|
|
6178
|
-
const
|
|
6182
|
+
const path71 = [...chain.path];
|
|
6179
6183
|
const edgeProvenances = chain.edges.map((e) => e.provenance);
|
|
6180
6184
|
const baseConfidence = confidenceFromMix(chain.edges);
|
|
6181
6185
|
const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
|
|
@@ -6183,14 +6187,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
6183
6187
|
if (loc) {
|
|
6184
6188
|
let rootCauseNode = culprit;
|
|
6185
6189
|
if (loc.fileNode) {
|
|
6186
|
-
|
|
6190
|
+
path71.push(loc.fileNode);
|
|
6187
6191
|
edgeProvenances.push(import_types8.Provenance.OBSERVED);
|
|
6188
6192
|
rootCauseNode = loc.fileNode;
|
|
6189
6193
|
}
|
|
6190
6194
|
return import_types8.RootCauseResultSchema.parse({
|
|
6191
6195
|
rootCauseNode,
|
|
6192
6196
|
rootCauseReason: loc.rootCauseReason,
|
|
6193
|
-
traversalPath:
|
|
6197
|
+
traversalPath: path71,
|
|
6194
6198
|
edgeProvenances,
|
|
6195
6199
|
confidence,
|
|
6196
6200
|
...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
|
|
@@ -6202,7 +6206,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
6202
6206
|
return import_types8.RootCauseResultSchema.parse({
|
|
6203
6207
|
rootCauseNode: culprit,
|
|
6204
6208
|
rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
|
|
6205
|
-
traversalPath:
|
|
6209
|
+
traversalPath: path71,
|
|
6206
6210
|
edgeProvenances,
|
|
6207
6211
|
confidence,
|
|
6208
6212
|
fixRecommendation: `Inspect ${culpritName}'s failing handler`
|
|
@@ -6638,10 +6642,10 @@ function enrichWithNavigation(graph, errorNodeId, legacy, incidents, now) {
|
|
|
6638
6642
|
let traversalPath = legacy.traversalPath;
|
|
6639
6643
|
let edgeProvenances = legacy.edgeProvenances;
|
|
6640
6644
|
if (top.node !== seedNode) {
|
|
6641
|
-
const
|
|
6642
|
-
if (
|
|
6643
|
-
traversalPath =
|
|
6644
|
-
edgeProvenances =
|
|
6645
|
+
const path71 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
|
|
6646
|
+
if (path71) {
|
|
6647
|
+
traversalPath = path71.nodes;
|
|
6648
|
+
edgeProvenances = path71.edges.map((e) => e.provenance);
|
|
6645
6649
|
} else {
|
|
6646
6650
|
traversalPath = [errorNodeId, top.node];
|
|
6647
6651
|
edgeProvenances = [top.provenance ?? import_types8.Provenance.OBSERVED];
|
|
@@ -7053,11 +7057,11 @@ init_cjs_shims();
|
|
|
7053
7057
|
|
|
7054
7058
|
// src/extract/services.ts
|
|
7055
7059
|
init_cjs_shims();
|
|
7056
|
-
var
|
|
7057
|
-
var
|
|
7060
|
+
var import_node_fs17 = require("fs");
|
|
7061
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
7058
7062
|
var import_ignore = __toESM(require("ignore"), 1);
|
|
7059
7063
|
var import_minimatch2 = require("minimatch");
|
|
7060
|
-
var
|
|
7064
|
+
var import_types16 = require("@neat.is/types");
|
|
7061
7065
|
|
|
7062
7066
|
// src/extract/python.ts
|
|
7063
7067
|
init_cjs_shims();
|
|
@@ -7250,19 +7254,234 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7250
7254
|
return { pkg, dir, node };
|
|
7251
7255
|
}
|
|
7252
7256
|
|
|
7253
|
-
// src/extract/
|
|
7257
|
+
// src/extract/csharp.ts
|
|
7254
7258
|
init_cjs_shims();
|
|
7255
7259
|
var import_node_fs13 = require("fs");
|
|
7256
7260
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
7261
|
+
var import_types13 = require("@neat.is/types");
|
|
7262
|
+
var CSHARP_PROJECT_EXTS = /* @__PURE__ */ new Set([".csproj", ".sln"]);
|
|
7263
|
+
async function projectFiles(dir) {
|
|
7264
|
+
const entries = await import_node_fs13.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
7265
|
+
const out = [];
|
|
7266
|
+
for (const entry of entries) {
|
|
7267
|
+
if (!entry.isFile()) continue;
|
|
7268
|
+
if (CSHARP_PROJECT_EXTS.has(import_node_path15.default.extname(entry.name).toLowerCase())) out.push(entry.name);
|
|
7269
|
+
}
|
|
7270
|
+
return out.sort();
|
|
7271
|
+
}
|
|
7272
|
+
var NESTED_PROJECT_DIR = "src";
|
|
7273
|
+
async function resolveProjectDir(dir) {
|
|
7274
|
+
if ((await projectFiles(dir)).length > 0) return dir;
|
|
7275
|
+
const nested = import_node_path15.default.join(dir, NESTED_PROJECT_DIR);
|
|
7276
|
+
if ((await projectFiles(nested)).length > 0) return nested;
|
|
7277
|
+
return null;
|
|
7278
|
+
}
|
|
7279
|
+
async function hasCsharpProject(dir) {
|
|
7280
|
+
return await resolveProjectDir(dir) !== null;
|
|
7281
|
+
}
|
|
7282
|
+
function parseCsproj(source) {
|
|
7283
|
+
const dependencies = {};
|
|
7284
|
+
const re = /<PackageReference\b([^>]*?)\/?>/g;
|
|
7285
|
+
let m;
|
|
7286
|
+
while ((m = re.exec(source)) !== null) {
|
|
7287
|
+
const attrs = m[1] ?? "";
|
|
7288
|
+
const include = attrs.match(/\bInclude\s*=\s*"([^"]+)"/)?.[1];
|
|
7289
|
+
if (!include) continue;
|
|
7290
|
+
const version = attrs.match(/\bVersion\s*=\s*"([^"]+)"/)?.[1];
|
|
7291
|
+
dependencies[include] = version ?? "";
|
|
7292
|
+
}
|
|
7293
|
+
return { dependencies };
|
|
7294
|
+
}
|
|
7295
|
+
async function discoverCsharpService(scanPath, dir) {
|
|
7296
|
+
const projectDir = await resolveProjectDir(dir);
|
|
7297
|
+
if (projectDir === null) return null;
|
|
7298
|
+
const projects = await projectFiles(projectDir);
|
|
7299
|
+
const csproj = projects.find((p) => p.toLowerCase().endsWith(".csproj"));
|
|
7300
|
+
const name = csproj ? import_node_path15.default.basename(csproj, import_node_path15.default.extname(csproj)) : import_node_path15.default.basename(dir);
|
|
7301
|
+
let dependencies = {};
|
|
7302
|
+
if (csproj) {
|
|
7303
|
+
const raw = await import_node_fs13.promises.readFile(import_node_path15.default.join(projectDir, csproj), "utf8").catch(() => "");
|
|
7304
|
+
dependencies = parseCsproj(raw).dependencies;
|
|
7305
|
+
}
|
|
7306
|
+
const pkg = { name, dependencies };
|
|
7307
|
+
const node = {
|
|
7308
|
+
id: (0, import_types13.serviceId)(name),
|
|
7309
|
+
type: import_types13.NodeType.ServiceNode,
|
|
7310
|
+
name,
|
|
7311
|
+
language: "csharp",
|
|
7312
|
+
dependencies,
|
|
7313
|
+
// Anchor on the directory that holds the project and its `.cs` files, so file
|
|
7314
|
+
// attribution reaches the source whether it sits at the root or under `src/`.
|
|
7315
|
+
repoPath: import_node_path15.default.relative(scanPath, projectDir)
|
|
7316
|
+
};
|
|
7317
|
+
return { pkg, dir: projectDir, node };
|
|
7318
|
+
}
|
|
7319
|
+
|
|
7320
|
+
// src/extract/java.ts
|
|
7321
|
+
init_cjs_shims();
|
|
7322
|
+
var import_node_fs14 = require("fs");
|
|
7323
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
7324
|
+
var import_types14 = require("@neat.is/types");
|
|
7325
|
+
var JAVA_MANIFESTS = ["pom.xml", "build.gradle", "build.gradle.kts"];
|
|
7326
|
+
async function hasJavaManifest(dir) {
|
|
7327
|
+
for (const manifest of JAVA_MANIFESTS) {
|
|
7328
|
+
if (await exists2(import_node_path16.default.join(dir, manifest))) return true;
|
|
7329
|
+
}
|
|
7330
|
+
return false;
|
|
7331
|
+
}
|
|
7332
|
+
function parsePomXml(source) {
|
|
7333
|
+
const dependencies = {};
|
|
7334
|
+
const depBlock = /<dependency\b[^>]*>([\s\S]*?)<\/dependency>/g;
|
|
7335
|
+
let d;
|
|
7336
|
+
while ((d = depBlock.exec(source)) !== null) {
|
|
7337
|
+
const body = d[1] ?? "";
|
|
7338
|
+
const groupId = body.match(/<groupId>\s*([^<]+?)\s*<\/groupId>/)?.[1];
|
|
7339
|
+
const artifactId = body.match(/<artifactId>\s*([^<]+?)\s*<\/artifactId>/)?.[1];
|
|
7340
|
+
if (!groupId || !artifactId) continue;
|
|
7341
|
+
const version = body.match(/<version>\s*([^<]+?)\s*<\/version>/)?.[1];
|
|
7342
|
+
dependencies[`${groupId}:${artifactId}`] = version ?? "";
|
|
7343
|
+
}
|
|
7344
|
+
const withoutBlocks = source.replace(/<parent\b[^>]*>[\s\S]*?<\/parent>/g, "").replace(/<dependencyManagement\b[^>]*>[\s\S]*?<\/dependencyManagement>/g, "").replace(/<dependencies\b[^>]*>[\s\S]*?<\/dependencies>/g, "").replace(/<build\b[^>]*>[\s\S]*?<\/build>/g, "");
|
|
7345
|
+
const name = withoutBlocks.match(/<artifactId>\s*([^<]+?)\s*<\/artifactId>/)?.[1];
|
|
7346
|
+
return { name, dependencies };
|
|
7347
|
+
}
|
|
7348
|
+
var GRADLE_CONFIGS = "implementation|api|compileOnly|runtimeOnly|compileOnlyApi|testImplementation|testRuntimeOnly|testCompileOnly|annotationProcessor|developmentOnly|runtimeClasspath";
|
|
7349
|
+
function parseGradle(source) {
|
|
7350
|
+
const dependencies = {};
|
|
7351
|
+
const re = new RegExp(`\\b(?:${GRADLE_CONFIGS})\\s*\\(?\\s*(['"])([^'"]+)\\1`, "g");
|
|
7352
|
+
let m;
|
|
7353
|
+
while ((m = re.exec(source)) !== null) {
|
|
7354
|
+
const coord = m[2] ?? "";
|
|
7355
|
+
const parts = coord.split(":");
|
|
7356
|
+
if (parts.length < 2 || !parts[0] || !parts[1]) continue;
|
|
7357
|
+
const key = `${parts[0]}:${parts[1]}`;
|
|
7358
|
+
dependencies[key] = parts.slice(2).join(":");
|
|
7359
|
+
}
|
|
7360
|
+
return { dependencies };
|
|
7361
|
+
}
|
|
7362
|
+
async function discoverJavaService(scanPath, dir) {
|
|
7363
|
+
const pomPath = import_node_path16.default.join(dir, "pom.xml");
|
|
7364
|
+
const gradlePath = import_node_path16.default.join(dir, "build.gradle");
|
|
7365
|
+
const gradleKtsPath = import_node_path16.default.join(dir, "build.gradle.kts");
|
|
7366
|
+
let manifest = null;
|
|
7367
|
+
if (await exists2(pomPath)) {
|
|
7368
|
+
manifest = parsePomXml(await import_node_fs14.promises.readFile(pomPath, "utf8").catch(() => ""));
|
|
7369
|
+
} else if (await exists2(gradlePath)) {
|
|
7370
|
+
manifest = parseGradle(await import_node_fs14.promises.readFile(gradlePath, "utf8").catch(() => ""));
|
|
7371
|
+
} else if (await exists2(gradleKtsPath)) {
|
|
7372
|
+
manifest = parseGradle(await import_node_fs14.promises.readFile(gradleKtsPath, "utf8").catch(() => ""));
|
|
7373
|
+
}
|
|
7374
|
+
if (!manifest) return null;
|
|
7375
|
+
const name = manifest.name?.trim() || import_node_path16.default.basename(dir);
|
|
7376
|
+
const dependencies = manifest.dependencies;
|
|
7377
|
+
const pkg = { name, dependencies };
|
|
7378
|
+
const node = {
|
|
7379
|
+
id: (0, import_types14.serviceId)(name),
|
|
7380
|
+
type: import_types14.NodeType.ServiceNode,
|
|
7381
|
+
name,
|
|
7382
|
+
language: "java",
|
|
7383
|
+
dependencies,
|
|
7384
|
+
repoPath: import_node_path16.default.relative(scanPath, dir)
|
|
7385
|
+
};
|
|
7386
|
+
return { pkg, dir, node };
|
|
7387
|
+
}
|
|
7388
|
+
|
|
7389
|
+
// src/extract/dockerfile-service.ts
|
|
7390
|
+
init_cjs_shims();
|
|
7391
|
+
var import_node_fs15 = require("fs");
|
|
7392
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
7393
|
+
var import_types15 = require("@neat.is/types");
|
|
7394
|
+
function languageForSourceExt(ext) {
|
|
7395
|
+
switch (ext) {
|
|
7396
|
+
case ".py":
|
|
7397
|
+
return "python";
|
|
7398
|
+
case ".go":
|
|
7399
|
+
return "go";
|
|
7400
|
+
case ".rb":
|
|
7401
|
+
return "ruby";
|
|
7402
|
+
case ".php":
|
|
7403
|
+
return "php";
|
|
7404
|
+
case ".cs":
|
|
7405
|
+
return "csharp";
|
|
7406
|
+
case ".java":
|
|
7407
|
+
return "java";
|
|
7408
|
+
case ".ts":
|
|
7409
|
+
case ".tsx":
|
|
7410
|
+
return "typescript";
|
|
7411
|
+
case ".js":
|
|
7412
|
+
case ".mjs":
|
|
7413
|
+
case ".cjs":
|
|
7414
|
+
return "javascript";
|
|
7415
|
+
default:
|
|
7416
|
+
return null;
|
|
7417
|
+
}
|
|
7418
|
+
}
|
|
7419
|
+
var LANGUAGE_PRECEDENCE = ["typescript", "javascript", "python", "go", "ruby", "php", "csharp", "java"];
|
|
7420
|
+
async function inferServiceLanguage(dir) {
|
|
7421
|
+
const entries = await import_node_fs15.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
7422
|
+
const counts = /* @__PURE__ */ new Map();
|
|
7423
|
+
for (const entry of entries) {
|
|
7424
|
+
if (!entry.isFile()) continue;
|
|
7425
|
+
if (isNeatAuthoredSourceFile(entry.name)) continue;
|
|
7426
|
+
const ext = import_node_path17.default.extname(entry.name).toLowerCase();
|
|
7427
|
+
if (!SERVICE_FILE_EXTENSIONS.has(ext)) continue;
|
|
7428
|
+
const lang = languageForSourceExt(ext);
|
|
7429
|
+
if (!lang) continue;
|
|
7430
|
+
counts.set(lang, (counts.get(lang) ?? 0) + 1);
|
|
7431
|
+
}
|
|
7432
|
+
if (counts.size === 0) return null;
|
|
7433
|
+
let best = null;
|
|
7434
|
+
let bestCount = -1;
|
|
7435
|
+
for (const lang of LANGUAGE_PRECEDENCE) {
|
|
7436
|
+
const c = counts.get(lang) ?? 0;
|
|
7437
|
+
if (c > bestCount) {
|
|
7438
|
+
best = lang;
|
|
7439
|
+
bestCount = c;
|
|
7440
|
+
}
|
|
7441
|
+
}
|
|
7442
|
+
return best;
|
|
7443
|
+
}
|
|
7444
|
+
async function hasLanguageManifest(dir) {
|
|
7445
|
+
return await exists2(import_node_path17.default.join(dir, "package.json")) || await exists2(import_node_path17.default.join(dir, "pyproject.toml")) || await exists2(import_node_path17.default.join(dir, "requirements.txt")) || await exists2(import_node_path17.default.join(dir, "setup.py")) || await exists2(import_node_path17.default.join(dir, "go.mod")) || await exists2(import_node_path17.default.join(dir, "Gemfile")) || await exists2(import_node_path17.default.join(dir, "composer.json")) || // C#'s marker is a glob (`*.csproj` / `*.sln`), so it reads the directory
|
|
7446
|
+
// rather than probing a fixed filename (ADR-196).
|
|
7447
|
+
await hasCsharpProject(dir) || // Java keys on a Maven / Gradle build manifest (ADR-197).
|
|
7448
|
+
await hasJavaManifest(dir);
|
|
7449
|
+
}
|
|
7450
|
+
async function hasDockerfileDeclaredService(dir) {
|
|
7451
|
+
if (!await exists2(import_node_path17.default.join(dir, "Dockerfile"))) return false;
|
|
7452
|
+
return await inferServiceLanguage(dir) !== null;
|
|
7453
|
+
}
|
|
7454
|
+
async function discoverDockerfileService(scanPath, dir) {
|
|
7455
|
+
if (!await exists2(import_node_path17.default.join(dir, "Dockerfile"))) return null;
|
|
7456
|
+
if (await hasLanguageManifest(dir)) return null;
|
|
7457
|
+
const language = await inferServiceLanguage(dir);
|
|
7458
|
+
if (!language) return null;
|
|
7459
|
+
const name = import_node_path17.default.basename(dir);
|
|
7460
|
+
const pkg = { name, dependencies: {} };
|
|
7461
|
+
const node = {
|
|
7462
|
+
id: (0, import_types15.serviceId)(name),
|
|
7463
|
+
type: import_types15.NodeType.ServiceNode,
|
|
7464
|
+
name,
|
|
7465
|
+
language,
|
|
7466
|
+
dependencies: {},
|
|
7467
|
+
repoPath: import_node_path17.default.relative(scanPath, dir)
|
|
7468
|
+
};
|
|
7469
|
+
return { pkg, dir, node };
|
|
7470
|
+
}
|
|
7471
|
+
|
|
7472
|
+
// src/extract/owners.ts
|
|
7473
|
+
init_cjs_shims();
|
|
7474
|
+
var import_node_fs16 = require("fs");
|
|
7475
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
7257
7476
|
var import_minimatch = require("minimatch");
|
|
7258
7477
|
async function loadCodeowners(scanPath) {
|
|
7259
7478
|
const candidates = [
|
|
7260
|
-
|
|
7261
|
-
|
|
7479
|
+
import_node_path18.default.join(scanPath, "CODEOWNERS"),
|
|
7480
|
+
import_node_path18.default.join(scanPath, ".github", "CODEOWNERS")
|
|
7262
7481
|
];
|
|
7263
7482
|
for (const file of candidates) {
|
|
7264
7483
|
if (await exists2(file)) {
|
|
7265
|
-
const raw = await
|
|
7484
|
+
const raw = await import_node_fs16.promises.readFile(file, "utf8");
|
|
7266
7485
|
return parseCodeowners(raw);
|
|
7267
7486
|
}
|
|
7268
7487
|
}
|
|
@@ -7280,7 +7499,7 @@ function parseCodeowners(raw) {
|
|
|
7280
7499
|
return { rules };
|
|
7281
7500
|
}
|
|
7282
7501
|
function matchOwner(file, repoPath) {
|
|
7283
|
-
const normalized = repoPath.split(
|
|
7502
|
+
const normalized = repoPath.split(import_node_path18.default.sep).join("/");
|
|
7284
7503
|
for (const rule of file.rules) {
|
|
7285
7504
|
if (matchesPattern(rule.pattern, normalized)) return rule.owners;
|
|
7286
7505
|
}
|
|
@@ -7296,7 +7515,7 @@ function matchesPattern(rawPattern, repoPath) {
|
|
|
7296
7515
|
return false;
|
|
7297
7516
|
}
|
|
7298
7517
|
async function readPackageJsonAuthor(serviceDir) {
|
|
7299
|
-
const pkgPath =
|
|
7518
|
+
const pkgPath = import_node_path18.default.join(serviceDir, "package.json");
|
|
7300
7519
|
if (!await exists2(pkgPath)) return null;
|
|
7301
7520
|
try {
|
|
7302
7521
|
const pkg = await readJson(pkgPath);
|
|
@@ -7333,33 +7552,36 @@ function workspaceGlobs(pkg) {
|
|
|
7333
7552
|
return null;
|
|
7334
7553
|
}
|
|
7335
7554
|
async function hasPythonManifest(dir) {
|
|
7336
|
-
return await exists2(
|
|
7555
|
+
return await exists2(import_node_path19.default.join(dir, "pyproject.toml")) || await exists2(import_node_path19.default.join(dir, "requirements.txt")) || await exists2(import_node_path19.default.join(dir, "setup.py"));
|
|
7337
7556
|
}
|
|
7338
7557
|
async function hasGoManifest(dir) {
|
|
7339
|
-
return exists2(
|
|
7558
|
+
return exists2(import_node_path19.default.join(dir, "go.mod"));
|
|
7340
7559
|
}
|
|
7341
7560
|
async function hasRubyManifest(dir) {
|
|
7342
|
-
return exists2(
|
|
7561
|
+
return exists2(import_node_path19.default.join(dir, "Gemfile"));
|
|
7343
7562
|
}
|
|
7344
7563
|
async function hasPhpManifest(dir) {
|
|
7345
|
-
return exists2(
|
|
7564
|
+
return exists2(import_node_path19.default.join(dir, "composer.json"));
|
|
7565
|
+
}
|
|
7566
|
+
async function hasCsharpManifest(dir) {
|
|
7567
|
+
return hasCsharpProject(dir);
|
|
7346
7568
|
}
|
|
7347
7569
|
async function loadGitignore(scanPath) {
|
|
7348
|
-
const gitignorePath =
|
|
7570
|
+
const gitignorePath = import_node_path19.default.join(scanPath, ".gitignore");
|
|
7349
7571
|
if (!await exists2(gitignorePath)) return null;
|
|
7350
|
-
const raw = await
|
|
7572
|
+
const raw = await import_node_fs17.promises.readFile(gitignorePath, "utf8");
|
|
7351
7573
|
return (0, import_ignore.default)().add(raw);
|
|
7352
7574
|
}
|
|
7353
7575
|
async function walkDirs(start, scanPath, options, visit) {
|
|
7354
7576
|
async function recurse(current, depth) {
|
|
7355
7577
|
if (depth > options.maxDepth) return;
|
|
7356
|
-
const entries = await
|
|
7578
|
+
const entries = await import_node_fs17.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
7357
7579
|
for (const entry of entries) {
|
|
7358
7580
|
if (!entry.isDirectory()) continue;
|
|
7359
7581
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
7360
|
-
const child =
|
|
7582
|
+
const child = import_node_path19.default.join(current, entry.name);
|
|
7361
7583
|
if (options.ig) {
|
|
7362
|
-
const rel =
|
|
7584
|
+
const rel = import_node_path19.default.relative(scanPath, child).split(import_node_path19.default.sep).join("/");
|
|
7363
7585
|
if (rel && options.ig.ignores(rel + "/")) continue;
|
|
7364
7586
|
}
|
|
7365
7587
|
if (await isPythonVenvDir(child)) continue;
|
|
@@ -7375,8 +7597,8 @@ async function expandWorkspaceGlobs(scanPath, globs) {
|
|
|
7375
7597
|
for (const raw of globs) {
|
|
7376
7598
|
const pattern = raw.replace(/^\.\//, "");
|
|
7377
7599
|
if (!pattern.includes("*")) {
|
|
7378
|
-
const candidate =
|
|
7379
|
-
if (await exists2(
|
|
7600
|
+
const candidate = import_node_path19.default.join(scanPath, pattern);
|
|
7601
|
+
if (await exists2(import_node_path19.default.join(candidate, "package.json"))) found.add(candidate);
|
|
7380
7602
|
continue;
|
|
7381
7603
|
}
|
|
7382
7604
|
const segments = pattern.split("/");
|
|
@@ -7385,13 +7607,13 @@ async function expandWorkspaceGlobs(scanPath, globs) {
|
|
|
7385
7607
|
if (seg.includes("*")) break;
|
|
7386
7608
|
staticSegments.push(seg);
|
|
7387
7609
|
}
|
|
7388
|
-
const start =
|
|
7610
|
+
const start = import_node_path19.default.join(scanPath, ...staticSegments);
|
|
7389
7611
|
if (!await exists2(start)) continue;
|
|
7390
7612
|
const hasDoubleStar = pattern.includes("**");
|
|
7391
7613
|
const walkDepth = hasDoubleStar ? scanDepth : Math.max(0, segments.length - staticSegments.length - 1);
|
|
7392
7614
|
await walkDirs(start, scanPath, { maxDepth: walkDepth, ig: null }, async (dir) => {
|
|
7393
|
-
const rel =
|
|
7394
|
-
if ((0, import_minimatch2.minimatch)(rel, pattern) && await exists2(
|
|
7615
|
+
const rel = import_node_path19.default.relative(scanPath, dir).split(import_node_path19.default.sep).join("/");
|
|
7616
|
+
if ((0, import_minimatch2.minimatch)(rel, pattern) && await exists2(import_node_path19.default.join(dir, "package.json"))) {
|
|
7395
7617
|
found.add(dir);
|
|
7396
7618
|
}
|
|
7397
7619
|
});
|
|
@@ -7414,31 +7636,31 @@ function detectJsFramework(pkg) {
|
|
|
7414
7636
|
async function detectJsServiceLanguage(dir, pkg) {
|
|
7415
7637
|
const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
7416
7638
|
if (deps["typescript"] !== void 0) return "typescript";
|
|
7417
|
-
const entries = await
|
|
7639
|
+
const entries = await import_node_fs17.promises.readdir(dir).catch(() => []);
|
|
7418
7640
|
if (entries.some((name) => /^tsconfig(\..+)?\.json$/.test(name))) return "typescript";
|
|
7419
7641
|
return "javascript";
|
|
7420
7642
|
}
|
|
7421
7643
|
async function discoverNodeService(scanPath, dir) {
|
|
7422
|
-
const pkgPath =
|
|
7644
|
+
const pkgPath = import_node_path19.default.join(dir, "package.json");
|
|
7423
7645
|
if (!await exists2(pkgPath)) return null;
|
|
7424
7646
|
let pkg;
|
|
7425
7647
|
try {
|
|
7426
7648
|
pkg = await readJson(pkgPath);
|
|
7427
7649
|
} catch (err) {
|
|
7428
|
-
recordExtractionError("services",
|
|
7650
|
+
recordExtractionError("services", import_node_path19.default.relative(scanPath, pkgPath), err);
|
|
7429
7651
|
return null;
|
|
7430
7652
|
}
|
|
7431
7653
|
if (!pkg.name) return null;
|
|
7432
7654
|
const framework = detectJsFramework(pkg);
|
|
7433
7655
|
const language = await detectJsServiceLanguage(dir, pkg);
|
|
7434
7656
|
const node = {
|
|
7435
|
-
id: (0,
|
|
7436
|
-
type:
|
|
7657
|
+
id: (0, import_types16.serviceId)(pkg.name),
|
|
7658
|
+
type: import_types16.NodeType.ServiceNode,
|
|
7437
7659
|
name: pkg.name,
|
|
7438
7660
|
language,
|
|
7439
7661
|
version: pkg.version,
|
|
7440
7662
|
dependencies: pkg.dependencies ?? {},
|
|
7441
|
-
repoPath:
|
|
7663
|
+
repoPath: import_node_path19.default.relative(scanPath, dir),
|
|
7442
7664
|
...pkg.engines?.node ? { nodeEngine: pkg.engines.node } : {},
|
|
7443
7665
|
...framework ? { framework } : {}
|
|
7444
7666
|
};
|
|
@@ -7449,18 +7671,18 @@ async function discoverPyService(scanPath, dir) {
|
|
|
7449
7671
|
if (!py) return null;
|
|
7450
7672
|
const pkg = pythonToPackage(py);
|
|
7451
7673
|
const node = {
|
|
7452
|
-
id: (0,
|
|
7453
|
-
type:
|
|
7674
|
+
id: (0, import_types16.serviceId)(py.name),
|
|
7675
|
+
type: import_types16.NodeType.ServiceNode,
|
|
7454
7676
|
name: py.name,
|
|
7455
7677
|
language: "python",
|
|
7456
7678
|
version: py.version,
|
|
7457
7679
|
dependencies: py.dependencies,
|
|
7458
|
-
repoPath:
|
|
7680
|
+
repoPath: import_node_path19.default.relative(scanPath, dir)
|
|
7459
7681
|
};
|
|
7460
7682
|
return { pkg, dir, node };
|
|
7461
7683
|
}
|
|
7462
7684
|
async function discoverServices(scanPath) {
|
|
7463
|
-
const rootPkgPath =
|
|
7685
|
+
const rootPkgPath = import_node_path19.default.join(scanPath, "package.json");
|
|
7464
7686
|
let rootPkg = null;
|
|
7465
7687
|
if (await exists2(rootPkgPath)) {
|
|
7466
7688
|
try {
|
|
@@ -7468,7 +7690,7 @@ async function discoverServices(scanPath) {
|
|
|
7468
7690
|
} catch (err) {
|
|
7469
7691
|
recordExtractionError(
|
|
7470
7692
|
"services workspaces",
|
|
7471
|
-
|
|
7693
|
+
import_node_path19.default.relative(scanPath, rootPkgPath),
|
|
7472
7694
|
err
|
|
7473
7695
|
);
|
|
7474
7696
|
}
|
|
@@ -7480,7 +7702,7 @@ async function discoverServices(scanPath) {
|
|
|
7480
7702
|
} else {
|
|
7481
7703
|
if (rootPkg && rootPkg.name) {
|
|
7482
7704
|
candidateDirs.push(scanPath);
|
|
7483
|
-
} else if (await hasPythonManifest(scanPath) || await hasGoManifest(scanPath) || await hasRubyManifest(scanPath) || await hasPhpManifest(scanPath)) {
|
|
7705
|
+
} else if (await hasPythonManifest(scanPath) || await hasGoManifest(scanPath) || await hasRubyManifest(scanPath) || await hasPhpManifest(scanPath) || await hasCsharpManifest(scanPath) || await hasJavaManifest(scanPath)) {
|
|
7484
7706
|
candidateDirs.push(scanPath);
|
|
7485
7707
|
}
|
|
7486
7708
|
const ig = await loadGitignore(scanPath);
|
|
@@ -7489,9 +7711,11 @@ async function discoverServices(scanPath) {
|
|
|
7489
7711
|
scanPath,
|
|
7490
7712
|
{ maxDepth: parseScanDepth(), ig },
|
|
7491
7713
|
async (dir) => {
|
|
7492
|
-
if (await exists2(
|
|
7714
|
+
if (await exists2(import_node_path19.default.join(dir, "package.json"))) {
|
|
7493
7715
|
candidateDirs.push(dir);
|
|
7494
|
-
} else if (await hasPythonManifest(dir) || await hasGoManifest(dir) || await hasRubyManifest(dir) || await hasPhpManifest(dir)) {
|
|
7716
|
+
} else if (await hasPythonManifest(dir) || await hasGoManifest(dir) || await hasRubyManifest(dir) || await hasPhpManifest(dir) || await hasCsharpManifest(dir) || await hasJavaManifest(dir)) {
|
|
7717
|
+
candidateDirs.push(dir);
|
|
7718
|
+
} else if (await hasDockerfileDeclaredService(dir)) {
|
|
7495
7719
|
candidateDirs.push(dir);
|
|
7496
7720
|
}
|
|
7497
7721
|
}
|
|
@@ -7499,14 +7723,17 @@ async function discoverServices(scanPath) {
|
|
|
7499
7723
|
}
|
|
7500
7724
|
candidateDirs.sort();
|
|
7501
7725
|
const seen = /* @__PURE__ */ new Map();
|
|
7726
|
+
const seenDirs = /* @__PURE__ */ new Set();
|
|
7502
7727
|
const out = [];
|
|
7503
7728
|
for (const dir of candidateDirs) {
|
|
7504
|
-
const service = await discoverNodeService(scanPath, dir) ?? await discoverPyService(scanPath, dir) ?? await discoverGoService(scanPath, dir) ?? await discoverRubyService(scanPath, dir) ?? await discoverPhpService(scanPath, dir);
|
|
7729
|
+
const service = await discoverNodeService(scanPath, dir) ?? await discoverPyService(scanPath, dir) ?? await discoverGoService(scanPath, dir) ?? await discoverRubyService(scanPath, dir) ?? await discoverPhpService(scanPath, dir) ?? await discoverCsharpService(scanPath, dir) ?? await discoverJavaService(scanPath, dir) ?? await discoverDockerfileService(scanPath, dir);
|
|
7505
7730
|
if (!service) continue;
|
|
7731
|
+
if (seenDirs.has(service.dir)) continue;
|
|
7732
|
+
seenDirs.add(service.dir);
|
|
7506
7733
|
const existingDir = seen.get(service.node.name);
|
|
7507
7734
|
if (existingDir !== void 0) {
|
|
7508
|
-
const a =
|
|
7509
|
-
const b =
|
|
7735
|
+
const a = import_node_path19.default.relative(scanPath, existingDir) || ".";
|
|
7736
|
+
const b = import_node_path19.default.relative(scanPath, dir) || ".";
|
|
7510
7737
|
console.warn(
|
|
7511
7738
|
`[neat] duplicate package name "${service.node.name}" \u2014 keeping ${a}, ignoring ${b}`
|
|
7512
7739
|
);
|
|
@@ -7543,20 +7770,20 @@ function addServiceNodes(graph, services) {
|
|
|
7543
7770
|
|
|
7544
7771
|
// src/extract/aliases.ts
|
|
7545
7772
|
init_cjs_shims();
|
|
7546
|
-
var
|
|
7547
|
-
var
|
|
7773
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
7774
|
+
var import_node_fs18 = require("fs");
|
|
7548
7775
|
var import_yaml2 = require("yaml");
|
|
7549
|
-
var
|
|
7776
|
+
var import_types17 = require("@neat.is/types");
|
|
7550
7777
|
var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
7551
7778
|
"Service",
|
|
7552
7779
|
"Deployment",
|
|
7553
7780
|
"StatefulSet",
|
|
7554
7781
|
"DaemonSet"
|
|
7555
7782
|
]);
|
|
7556
|
-
function addAliases(graph,
|
|
7557
|
-
if (!graph.hasNode(
|
|
7558
|
-
const node = graph.getNodeAttributes(
|
|
7559
|
-
if (node.type !==
|
|
7783
|
+
function addAliases(graph, serviceId12, candidates) {
|
|
7784
|
+
if (!graph.hasNode(serviceId12)) return;
|
|
7785
|
+
const node = graph.getNodeAttributes(serviceId12);
|
|
7786
|
+
if (node.type !== import_types17.NodeType.ServiceNode) return;
|
|
7560
7787
|
const set = new Set(node.aliases ?? []);
|
|
7561
7788
|
for (const c of candidates) {
|
|
7562
7789
|
if (!c) continue;
|
|
@@ -7565,20 +7792,20 @@ function addAliases(graph, serviceId9, candidates) {
|
|
|
7565
7792
|
}
|
|
7566
7793
|
if (set.size === 0) return;
|
|
7567
7794
|
const updated = { ...node, aliases: [...set].sort() };
|
|
7568
|
-
graph.replaceNodeAttributes(
|
|
7795
|
+
graph.replaceNodeAttributes(serviceId12, updated);
|
|
7569
7796
|
}
|
|
7570
7797
|
function indexServicesByName(services) {
|
|
7571
7798
|
const map = /* @__PURE__ */ new Map();
|
|
7572
7799
|
for (const s of services) {
|
|
7573
7800
|
map.set(s.node.name, s.node.id);
|
|
7574
|
-
map.set(
|
|
7801
|
+
map.set(import_node_path20.default.basename(s.dir), s.node.id);
|
|
7575
7802
|
}
|
|
7576
7803
|
return map;
|
|
7577
7804
|
}
|
|
7578
7805
|
async function collectComposeAliases(graph, scanPath, serviceIndex) {
|
|
7579
7806
|
let composePath = null;
|
|
7580
7807
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
7581
|
-
const abs =
|
|
7808
|
+
const abs = import_node_path20.default.join(scanPath, name);
|
|
7582
7809
|
if (await exists2(abs)) {
|
|
7583
7810
|
composePath = abs;
|
|
7584
7811
|
break;
|
|
@@ -7591,19 +7818,19 @@ async function collectComposeAliases(graph, scanPath, serviceIndex) {
|
|
|
7591
7818
|
} catch (err) {
|
|
7592
7819
|
recordExtractionError(
|
|
7593
7820
|
"aliases compose",
|
|
7594
|
-
|
|
7821
|
+
import_node_path20.default.relative(scanPath, composePath),
|
|
7595
7822
|
err
|
|
7596
7823
|
);
|
|
7597
7824
|
return;
|
|
7598
7825
|
}
|
|
7599
7826
|
if (!compose?.services) return;
|
|
7600
7827
|
for (const [composeName, svc] of Object.entries(compose.services)) {
|
|
7601
|
-
const
|
|
7602
|
-
if (!
|
|
7828
|
+
const serviceId12 = serviceIndex.get(composeName);
|
|
7829
|
+
if (!serviceId12) continue;
|
|
7603
7830
|
const aliases = /* @__PURE__ */ new Set([composeName]);
|
|
7604
7831
|
if (svc.container_name) aliases.add(svc.container_name);
|
|
7605
7832
|
if (svc.hostname) aliases.add(svc.hostname);
|
|
7606
|
-
addAliases(graph,
|
|
7833
|
+
addAliases(graph, serviceId12, aliases);
|
|
7607
7834
|
}
|
|
7608
7835
|
}
|
|
7609
7836
|
var LABEL_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -7634,11 +7861,11 @@ function parseDockerfileLabels(content) {
|
|
|
7634
7861
|
}
|
|
7635
7862
|
async function collectDockerfileAliases(graph, services) {
|
|
7636
7863
|
for (const service of services) {
|
|
7637
|
-
const dockerfilePath =
|
|
7864
|
+
const dockerfilePath = import_node_path20.default.join(service.dir, "Dockerfile");
|
|
7638
7865
|
if (!await exists2(dockerfilePath)) continue;
|
|
7639
7866
|
let content;
|
|
7640
7867
|
try {
|
|
7641
|
-
content = await
|
|
7868
|
+
content = await import_node_fs18.promises.readFile(dockerfilePath, "utf8");
|
|
7642
7869
|
} catch (err) {
|
|
7643
7870
|
recordExtractionError("aliases dockerfile", dockerfilePath, err);
|
|
7644
7871
|
continue;
|
|
@@ -7650,15 +7877,15 @@ async function collectDockerfileAliases(graph, services) {
|
|
|
7650
7877
|
async function walkYamlFiles(start, depth = 0, max = 5) {
|
|
7651
7878
|
if (depth > max) return [];
|
|
7652
7879
|
const out = [];
|
|
7653
|
-
const entries = await
|
|
7880
|
+
const entries = await import_node_fs18.promises.readdir(start, { withFileTypes: true }).catch(() => []);
|
|
7654
7881
|
for (const entry of entries) {
|
|
7655
7882
|
if (entry.isDirectory()) {
|
|
7656
7883
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
7657
|
-
const child =
|
|
7884
|
+
const child = import_node_path20.default.join(start, entry.name);
|
|
7658
7885
|
if (await isPythonVenvDir(child)) continue;
|
|
7659
7886
|
out.push(...await walkYamlFiles(child, depth + 1, max));
|
|
7660
|
-
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(
|
|
7661
|
-
out.push(
|
|
7887
|
+
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path20.default.extname(entry.name))) {
|
|
7888
|
+
out.push(import_node_path20.default.join(start, entry.name));
|
|
7662
7889
|
}
|
|
7663
7890
|
}
|
|
7664
7891
|
return out;
|
|
@@ -7685,7 +7912,7 @@ function k8sServiceTarget(doc, byName) {
|
|
|
7685
7912
|
async function collectK8sAliases(graph, scanPath, serviceIndex) {
|
|
7686
7913
|
const files = await walkYamlFiles(scanPath);
|
|
7687
7914
|
for (const file of files) {
|
|
7688
|
-
const content = await
|
|
7915
|
+
const content = await import_node_fs18.promises.readFile(file, "utf8");
|
|
7689
7916
|
let docs;
|
|
7690
7917
|
try {
|
|
7691
7918
|
docs = (0, import_yaml2.parseAllDocuments)(content).map((d) => d.toJSON());
|
|
@@ -7710,14 +7937,14 @@ async function addServiceAliases(graph, scanPath, services) {
|
|
|
7710
7937
|
|
|
7711
7938
|
// src/extract/files.ts
|
|
7712
7939
|
init_cjs_shims();
|
|
7713
|
-
var
|
|
7940
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
7714
7941
|
async function addFiles(graph, services) {
|
|
7715
7942
|
let nodesAdded = 0;
|
|
7716
7943
|
let edgesAdded = 0;
|
|
7717
7944
|
for (const service of services) {
|
|
7718
7945
|
const filePaths = await walkSourceFiles(service.dir);
|
|
7719
7946
|
for (const filePath of filePaths) {
|
|
7720
|
-
const relPath = toPosix(
|
|
7947
|
+
const relPath = toPosix(import_node_path21.default.relative(service.dir, filePath));
|
|
7721
7948
|
const { nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
7722
7949
|
graph,
|
|
7723
7950
|
service.pkg.name,
|
|
@@ -7733,11 +7960,17 @@ async function addFiles(graph, services) {
|
|
|
7733
7960
|
|
|
7734
7961
|
// src/extract/symbols.ts
|
|
7735
7962
|
init_cjs_shims();
|
|
7736
|
-
var
|
|
7963
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
7737
7964
|
var import_tree_sitter3 = __toESM(require("tree-sitter"), 1);
|
|
7738
7965
|
var import_tree_sitter_javascript3 = __toESM(require("tree-sitter-javascript"), 1);
|
|
7739
7966
|
var import_tree_sitter_typescript = __toESM(require("tree-sitter-typescript"), 1);
|
|
7740
|
-
var
|
|
7967
|
+
var import_tree_sitter_python3 = __toESM(require("tree-sitter-python"), 1);
|
|
7968
|
+
var import_tree_sitter_go3 = __toESM(require("tree-sitter-go"), 1);
|
|
7969
|
+
var import_tree_sitter_ruby2 = __toESM(require("tree-sitter-ruby"), 1);
|
|
7970
|
+
var import_tree_sitter_php2 = __toESM(require("tree-sitter-php"), 1);
|
|
7971
|
+
var import_tree_sitter_c_sharp = __toESM(require("tree-sitter-c-sharp"), 1);
|
|
7972
|
+
var import_tree_sitter_java = __toESM(require("tree-sitter-java"), 1);
|
|
7973
|
+
var import_types18 = require("@neat.is/types");
|
|
7741
7974
|
var PARSE_CHUNK3 = 16384;
|
|
7742
7975
|
var GRAMMAR_BY_EXT = {
|
|
7743
7976
|
".ts": import_tree_sitter_typescript.default.typescript,
|
|
@@ -7747,6 +7980,15 @@ var GRAMMAR_BY_EXT = {
|
|
|
7747
7980
|
".mjs": import_tree_sitter_javascript3.default,
|
|
7748
7981
|
".cjs": import_tree_sitter_javascript3.default
|
|
7749
7982
|
};
|
|
7983
|
+
var SYMBOL_GRAMMAR_BY_EXT = {
|
|
7984
|
+
...GRAMMAR_BY_EXT,
|
|
7985
|
+
".py": import_tree_sitter_python3.default,
|
|
7986
|
+
".go": import_tree_sitter_go3.default,
|
|
7987
|
+
".rb": import_tree_sitter_ruby2.default,
|
|
7988
|
+
".php": import_tree_sitter_php2.default.php_only,
|
|
7989
|
+
".cs": import_tree_sitter_c_sharp.default,
|
|
7990
|
+
".java": import_tree_sitter_java.default
|
|
7991
|
+
};
|
|
7750
7992
|
function parseSource3(parser, source) {
|
|
7751
7993
|
return parser.parse(
|
|
7752
7994
|
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK3)
|
|
@@ -7807,14 +8049,375 @@ function collectSymbolDefs(root) {
|
|
|
7807
8049
|
break;
|
|
7808
8050
|
}
|
|
7809
8051
|
}
|
|
7810
|
-
for (let i = 0; i < node.namedChildCount; i++) {
|
|
7811
|
-
const child = node.namedChild(i);
|
|
7812
|
-
if (child) visit(child, classCtx);
|
|
7813
|
-
}
|
|
8052
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
8053
|
+
const child = node.namedChild(i);
|
|
8054
|
+
if (child) visit(child, classCtx);
|
|
8055
|
+
}
|
|
8056
|
+
};
|
|
8057
|
+
visit(root, void 0);
|
|
8058
|
+
return out;
|
|
8059
|
+
}
|
|
8060
|
+
function collectPythonSymbolDefs(root) {
|
|
8061
|
+
const out = [];
|
|
8062
|
+
const push = (kind, qualname, node) => {
|
|
8063
|
+
out.push({
|
|
8064
|
+
kind,
|
|
8065
|
+
qualname,
|
|
8066
|
+
startLine: node.startPosition.row + 1,
|
|
8067
|
+
endLine: node.endPosition.row + 1
|
|
8068
|
+
});
|
|
8069
|
+
};
|
|
8070
|
+
const visit = (node, classCtx) => {
|
|
8071
|
+
switch (node.type) {
|
|
8072
|
+
case "function_definition": {
|
|
8073
|
+
const name = node.childForFieldName("name")?.text;
|
|
8074
|
+
if (name) {
|
|
8075
|
+
if (classCtx) {
|
|
8076
|
+
const kind = name === "__init__" ? "constructor" : "method";
|
|
8077
|
+
push(kind, `${classCtx}.${name}`, node);
|
|
8078
|
+
} else {
|
|
8079
|
+
push("function", name, node);
|
|
8080
|
+
}
|
|
8081
|
+
}
|
|
8082
|
+
const body = node.childForFieldName("body");
|
|
8083
|
+
if (body) {
|
|
8084
|
+
for (let i = 0; i < body.namedChildCount; i++) {
|
|
8085
|
+
const child = body.namedChild(i);
|
|
8086
|
+
if (child) visit(child, void 0);
|
|
8087
|
+
}
|
|
8088
|
+
}
|
|
8089
|
+
return;
|
|
8090
|
+
}
|
|
8091
|
+
case "class_definition": {
|
|
8092
|
+
const name = node.childForFieldName("name")?.text;
|
|
8093
|
+
if (name) push("class", name, node);
|
|
8094
|
+
const body = node.childForFieldName("body");
|
|
8095
|
+
if (body) {
|
|
8096
|
+
for (let i = 0; i < body.namedChildCount; i++) {
|
|
8097
|
+
const child = body.namedChild(i);
|
|
8098
|
+
if (child) visit(child, name ?? classCtx);
|
|
8099
|
+
}
|
|
8100
|
+
}
|
|
8101
|
+
return;
|
|
8102
|
+
}
|
|
8103
|
+
case "decorated_definition": {
|
|
8104
|
+
const def = node.childForFieldName("definition");
|
|
8105
|
+
if (def) visit(def, classCtx);
|
|
8106
|
+
return;
|
|
8107
|
+
}
|
|
8108
|
+
}
|
|
8109
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
8110
|
+
const child = node.namedChild(i);
|
|
8111
|
+
if (child) visit(child, classCtx);
|
|
8112
|
+
}
|
|
8113
|
+
};
|
|
8114
|
+
visit(root, void 0);
|
|
8115
|
+
return out;
|
|
8116
|
+
}
|
|
8117
|
+
function goReceiverType(node) {
|
|
8118
|
+
const receiver = node.childForFieldName("receiver");
|
|
8119
|
+
if (!receiver) return void 0;
|
|
8120
|
+
for (let i = 0; i < receiver.namedChildCount; i++) {
|
|
8121
|
+
const param = receiver.namedChild(i);
|
|
8122
|
+
if (param?.type !== "parameter_declaration") continue;
|
|
8123
|
+
let typeNode = param.childForFieldName("type");
|
|
8124
|
+
if (typeNode?.type === "pointer_type") typeNode = typeNode.namedChild(0) ?? typeNode;
|
|
8125
|
+
if (typeNode?.type === "generic_type") {
|
|
8126
|
+
typeNode = typeNode.childForFieldName("type") ?? typeNode.namedChild(0) ?? typeNode;
|
|
8127
|
+
}
|
|
8128
|
+
if (typeNode?.type === "type_identifier") return typeNode.text;
|
|
8129
|
+
return typeNode?.text;
|
|
8130
|
+
}
|
|
8131
|
+
return void 0;
|
|
8132
|
+
}
|
|
8133
|
+
function collectGoSymbolDefs(root) {
|
|
8134
|
+
const out = [];
|
|
8135
|
+
const push = (kind, qualname, node) => {
|
|
8136
|
+
out.push({
|
|
8137
|
+
kind,
|
|
8138
|
+
qualname,
|
|
8139
|
+
startLine: node.startPosition.row + 1,
|
|
8140
|
+
endLine: node.endPosition.row + 1
|
|
8141
|
+
});
|
|
8142
|
+
};
|
|
8143
|
+
const visit = (node) => {
|
|
8144
|
+
switch (node.type) {
|
|
8145
|
+
case "function_declaration": {
|
|
8146
|
+
const name = node.childForFieldName("name")?.text;
|
|
8147
|
+
if (name) push("function", name, node);
|
|
8148
|
+
break;
|
|
8149
|
+
}
|
|
8150
|
+
case "method_declaration": {
|
|
8151
|
+
const name = node.childForFieldName("name")?.text;
|
|
8152
|
+
if (name) {
|
|
8153
|
+
const recv = goReceiverType(node);
|
|
8154
|
+
push("method", recv ? `${recv}.${name}` : name, node);
|
|
8155
|
+
}
|
|
8156
|
+
break;
|
|
8157
|
+
}
|
|
8158
|
+
}
|
|
8159
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
8160
|
+
const child = node.namedChild(i);
|
|
8161
|
+
if (child) visit(child);
|
|
8162
|
+
}
|
|
8163
|
+
};
|
|
8164
|
+
visit(root);
|
|
8165
|
+
return out;
|
|
8166
|
+
}
|
|
8167
|
+
function collectRubySymbolDefs(root) {
|
|
8168
|
+
const out = [];
|
|
8169
|
+
const push = (kind, qualname, node) => {
|
|
8170
|
+
out.push({
|
|
8171
|
+
kind,
|
|
8172
|
+
qualname,
|
|
8173
|
+
startLine: node.startPosition.row + 1,
|
|
8174
|
+
endLine: node.endPosition.row + 1
|
|
8175
|
+
});
|
|
8176
|
+
};
|
|
8177
|
+
const nameText = (node) => node.childForFieldName("name")?.text.replace(/::/g, ".");
|
|
8178
|
+
const walkBody = (node, ctx) => {
|
|
8179
|
+
const body = node.childForFieldName("body");
|
|
8180
|
+
if (!body) return;
|
|
8181
|
+
for (let i = 0; i < body.namedChildCount; i++) {
|
|
8182
|
+
const child = body.namedChild(i);
|
|
8183
|
+
if (child) visit(child, ctx);
|
|
8184
|
+
}
|
|
8185
|
+
};
|
|
8186
|
+
const visit = (node, classCtx) => {
|
|
8187
|
+
switch (node.type) {
|
|
8188
|
+
case "method":
|
|
8189
|
+
case "singleton_method": {
|
|
8190
|
+
const name = node.childForFieldName("name")?.text;
|
|
8191
|
+
if (name) {
|
|
8192
|
+
if (classCtx) {
|
|
8193
|
+
const kind = node.type === "method" && name === "initialize" ? "constructor" : "method";
|
|
8194
|
+
push(kind, `${classCtx}.${name}`, node);
|
|
8195
|
+
} else {
|
|
8196
|
+
push("function", name, node);
|
|
8197
|
+
}
|
|
8198
|
+
}
|
|
8199
|
+
walkBody(node, void 0);
|
|
8200
|
+
return;
|
|
8201
|
+
}
|
|
8202
|
+
case "class":
|
|
8203
|
+
case "module": {
|
|
8204
|
+
const name = nameText(node);
|
|
8205
|
+
if (name) push("class", classCtx ? `${classCtx}.${name}` : name, node);
|
|
8206
|
+
walkBody(node, name ? classCtx ? `${classCtx}.${name}` : name : classCtx);
|
|
8207
|
+
return;
|
|
8208
|
+
}
|
|
8209
|
+
}
|
|
8210
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
8211
|
+
const child = node.namedChild(i);
|
|
8212
|
+
if (child) visit(child, classCtx);
|
|
8213
|
+
}
|
|
8214
|
+
};
|
|
8215
|
+
visit(root, void 0);
|
|
8216
|
+
return out;
|
|
8217
|
+
}
|
|
8218
|
+
function collectPhpSymbolDefs(root) {
|
|
8219
|
+
const out = [];
|
|
8220
|
+
const push = (kind, qualname, node) => {
|
|
8221
|
+
out.push({
|
|
8222
|
+
kind,
|
|
8223
|
+
qualname,
|
|
8224
|
+
startLine: node.startPosition.row + 1,
|
|
8225
|
+
endLine: node.endPosition.row + 1
|
|
8226
|
+
});
|
|
8227
|
+
};
|
|
8228
|
+
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
8229
|
+
const join = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8230
|
+
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8231
|
+
let ns = nsCtx;
|
|
8232
|
+
for (let i = 0; i < container.namedChildCount; i++) {
|
|
8233
|
+
const child = container.namedChild(i);
|
|
8234
|
+
if (!child) continue;
|
|
8235
|
+
if (child.type === "namespace_definition" && !child.childForFieldName("body")) {
|
|
8236
|
+
const nameNode = child.childForFieldName("name");
|
|
8237
|
+
if (nameNode) ns = dot(nameNode.text);
|
|
8238
|
+
continue;
|
|
8239
|
+
}
|
|
8240
|
+
visit(child, ns, classCtx);
|
|
8241
|
+
}
|
|
8242
|
+
};
|
|
8243
|
+
const walkBody = (node, nsCtx, classCtx) => {
|
|
8244
|
+
const body = node.childForFieldName("body");
|
|
8245
|
+
if (body) walkChildren(body, nsCtx, classCtx);
|
|
8246
|
+
};
|
|
8247
|
+
const visit = (node, nsCtx, classCtx) => {
|
|
8248
|
+
switch (node.type) {
|
|
8249
|
+
case "function_definition": {
|
|
8250
|
+
const name = node.childForFieldName("name")?.text;
|
|
8251
|
+
if (name) push("function", join(nsCtx, name), node);
|
|
8252
|
+
walkBody(node, nsCtx, void 0);
|
|
8253
|
+
return;
|
|
8254
|
+
}
|
|
8255
|
+
case "class_declaration":
|
|
8256
|
+
case "trait_declaration":
|
|
8257
|
+
case "interface_declaration": {
|
|
8258
|
+
const name = node.childForFieldName("name")?.text;
|
|
8259
|
+
const full = name ? join(nsCtx, name) : classCtx;
|
|
8260
|
+
if (name) push("class", full, node);
|
|
8261
|
+
walkBody(node, nsCtx, full);
|
|
8262
|
+
return;
|
|
8263
|
+
}
|
|
8264
|
+
case "method_declaration": {
|
|
8265
|
+
const name = node.childForFieldName("name")?.text;
|
|
8266
|
+
if (name) {
|
|
8267
|
+
const kind = name === "__construct" ? "constructor" : "method";
|
|
8268
|
+
push(kind, join(classCtx ?? nsCtx, name), node);
|
|
8269
|
+
}
|
|
8270
|
+
return;
|
|
8271
|
+
}
|
|
8272
|
+
case "namespace_definition": {
|
|
8273
|
+
const nameNode = node.childForFieldName("name");
|
|
8274
|
+
const ns = nameNode ? dot(nameNode.text) : nsCtx;
|
|
8275
|
+
walkBody(node, ns, classCtx);
|
|
8276
|
+
return;
|
|
8277
|
+
}
|
|
8278
|
+
}
|
|
8279
|
+
walkChildren(node, nsCtx, classCtx);
|
|
8280
|
+
};
|
|
8281
|
+
walkChildren(root, void 0, void 0);
|
|
8282
|
+
return out;
|
|
8283
|
+
}
|
|
8284
|
+
function collectCsharpSymbolDefs(root) {
|
|
8285
|
+
const out = [];
|
|
8286
|
+
const push = (kind, qualname, node) => {
|
|
8287
|
+
out.push({
|
|
8288
|
+
kind,
|
|
8289
|
+
qualname,
|
|
8290
|
+
startLine: node.startPosition.row + 1,
|
|
8291
|
+
endLine: node.endPosition.row + 1
|
|
8292
|
+
});
|
|
8293
|
+
};
|
|
8294
|
+
const join = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8295
|
+
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8296
|
+
let ns = nsCtx;
|
|
8297
|
+
for (let i = 0; i < container.namedChildCount; i++) {
|
|
8298
|
+
const child = container.namedChild(i);
|
|
8299
|
+
if (!child) continue;
|
|
8300
|
+
if (child.type === "file_scoped_namespace_declaration") {
|
|
8301
|
+
const nameNode = child.childForFieldName("name");
|
|
8302
|
+
if (nameNode) ns = join(nsCtx, nameNode.text);
|
|
8303
|
+
continue;
|
|
8304
|
+
}
|
|
8305
|
+
visit(child, ns, classCtx);
|
|
8306
|
+
}
|
|
8307
|
+
};
|
|
8308
|
+
const walkBody = (node, nsCtx, classCtx) => {
|
|
8309
|
+
const body = node.childForFieldName("body");
|
|
8310
|
+
if (body) walkChildren(body, nsCtx, classCtx);
|
|
8311
|
+
};
|
|
8312
|
+
const visit = (node, nsCtx, classCtx) => {
|
|
8313
|
+
switch (node.type) {
|
|
8314
|
+
case "namespace_declaration": {
|
|
8315
|
+
const nameNode = node.childForFieldName("name");
|
|
8316
|
+
const ns = nameNode ? join(nsCtx, nameNode.text) : nsCtx;
|
|
8317
|
+
walkBody(node, ns, classCtx);
|
|
8318
|
+
return;
|
|
8319
|
+
}
|
|
8320
|
+
case "class_declaration":
|
|
8321
|
+
case "interface_declaration":
|
|
8322
|
+
case "struct_declaration":
|
|
8323
|
+
case "record_declaration": {
|
|
8324
|
+
const name = node.childForFieldName("name")?.text;
|
|
8325
|
+
const full = name ? join(classCtx ?? nsCtx, name) : classCtx;
|
|
8326
|
+
if (name) push("class", full, node);
|
|
8327
|
+
walkBody(node, nsCtx, full);
|
|
8328
|
+
return;
|
|
8329
|
+
}
|
|
8330
|
+
case "method_declaration": {
|
|
8331
|
+
const name = node.childForFieldName("name")?.text;
|
|
8332
|
+
if (name) push("method", join(classCtx ?? nsCtx, name), node);
|
|
8333
|
+
return;
|
|
8334
|
+
}
|
|
8335
|
+
case "constructor_declaration": {
|
|
8336
|
+
const name = node.childForFieldName("name")?.text;
|
|
8337
|
+
if (name) push("constructor", join(classCtx ?? nsCtx, name), node);
|
|
8338
|
+
return;
|
|
8339
|
+
}
|
|
8340
|
+
}
|
|
8341
|
+
walkChildren(node, nsCtx, classCtx);
|
|
8342
|
+
};
|
|
8343
|
+
walkChildren(root, void 0, void 0);
|
|
8344
|
+
return out;
|
|
8345
|
+
}
|
|
8346
|
+
function collectJavaSymbolDefs(root) {
|
|
8347
|
+
const out = [];
|
|
8348
|
+
const push = (kind, qualname, node) => {
|
|
8349
|
+
out.push({
|
|
8350
|
+
kind,
|
|
8351
|
+
qualname,
|
|
8352
|
+
startLine: node.startPosition.row + 1,
|
|
8353
|
+
endLine: node.endPosition.row + 1
|
|
8354
|
+
});
|
|
8355
|
+
};
|
|
8356
|
+
const join = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8357
|
+
let pkg;
|
|
8358
|
+
for (let i = 0; i < root.namedChildCount; i++) {
|
|
8359
|
+
const child = root.namedChild(i);
|
|
8360
|
+
if (child?.type === "package_declaration") {
|
|
8361
|
+
pkg = child.namedChild(0)?.text;
|
|
8362
|
+
break;
|
|
8363
|
+
}
|
|
8364
|
+
}
|
|
8365
|
+
const walkChildren = (container, classCtx) => {
|
|
8366
|
+
for (let i = 0; i < container.namedChildCount; i++) {
|
|
8367
|
+
const child = container.namedChild(i);
|
|
8368
|
+
if (child) visit(child, classCtx);
|
|
8369
|
+
}
|
|
8370
|
+
};
|
|
8371
|
+
const walkBody = (node, classCtx) => {
|
|
8372
|
+
const body = node.childForFieldName("body");
|
|
8373
|
+
if (body) walkChildren(body, classCtx);
|
|
8374
|
+
};
|
|
8375
|
+
const visit = (node, classCtx) => {
|
|
8376
|
+
switch (node.type) {
|
|
8377
|
+
case "class_declaration":
|
|
8378
|
+
case "interface_declaration":
|
|
8379
|
+
case "enum_declaration":
|
|
8380
|
+
case "record_declaration": {
|
|
8381
|
+
const name = node.childForFieldName("name")?.text;
|
|
8382
|
+
const full = name ? join(classCtx ?? pkg, name) : classCtx;
|
|
8383
|
+
if (name) push("class", full, node);
|
|
8384
|
+
walkBody(node, full);
|
|
8385
|
+
return;
|
|
8386
|
+
}
|
|
8387
|
+
case "method_declaration": {
|
|
8388
|
+
const name = node.childForFieldName("name")?.text;
|
|
8389
|
+
if (name) push("method", join(classCtx ?? pkg, name), node);
|
|
8390
|
+
return;
|
|
8391
|
+
}
|
|
8392
|
+
case "constructor_declaration": {
|
|
8393
|
+
const name = node.childForFieldName("name")?.text;
|
|
8394
|
+
if (name) push("constructor", join(classCtx ?? pkg, name), node);
|
|
8395
|
+
return;
|
|
8396
|
+
}
|
|
8397
|
+
}
|
|
8398
|
+
walkChildren(node, classCtx);
|
|
7814
8399
|
};
|
|
7815
|
-
|
|
8400
|
+
walkChildren(root, void 0);
|
|
7816
8401
|
return out;
|
|
7817
8402
|
}
|
|
8403
|
+
function collectSymbolDefsForExt(ext, root) {
|
|
8404
|
+
switch (ext) {
|
|
8405
|
+
case ".py":
|
|
8406
|
+
return collectPythonSymbolDefs(root);
|
|
8407
|
+
case ".go":
|
|
8408
|
+
return collectGoSymbolDefs(root);
|
|
8409
|
+
case ".rb":
|
|
8410
|
+
return collectRubySymbolDefs(root);
|
|
8411
|
+
case ".php":
|
|
8412
|
+
return collectPhpSymbolDefs(root);
|
|
8413
|
+
case ".cs":
|
|
8414
|
+
return collectCsharpSymbolDefs(root);
|
|
8415
|
+
case ".java":
|
|
8416
|
+
return collectJavaSymbolDefs(root);
|
|
8417
|
+
default:
|
|
8418
|
+
return collectSymbolDefs(root);
|
|
8419
|
+
}
|
|
8420
|
+
}
|
|
7818
8421
|
function disambiguate(defs) {
|
|
7819
8422
|
const counts = /* @__PURE__ */ new Map();
|
|
7820
8423
|
for (const def of defs) counts.set(def.qualname, (counts.get(def.qualname) ?? 0) + 1);
|
|
@@ -7829,7 +8432,7 @@ function disambiguate(defs) {
|
|
|
7829
8432
|
async function addSymbols(graph, services) {
|
|
7830
8433
|
const parsers = /* @__PURE__ */ new Map();
|
|
7831
8434
|
const parserForExt5 = (ext) => {
|
|
7832
|
-
const grammar =
|
|
8435
|
+
const grammar = SYMBOL_GRAMMAR_BY_EXT[ext];
|
|
7833
8436
|
if (!grammar) return null;
|
|
7834
8437
|
let parser = parsers.get(ext);
|
|
7835
8438
|
if (!parser) {
|
|
@@ -7844,13 +8447,14 @@ async function addSymbols(graph, services) {
|
|
|
7844
8447
|
for (const service of services) {
|
|
7845
8448
|
const files = await loadSourceFiles(service.dir);
|
|
7846
8449
|
for (const file of files) {
|
|
7847
|
-
const
|
|
8450
|
+
const ext = import_node_path22.default.extname(file.path);
|
|
8451
|
+
const parser = parserForExt5(ext);
|
|
7848
8452
|
if (!parser) continue;
|
|
7849
|
-
const relPath = toPosix(
|
|
8453
|
+
const relPath = toPosix(import_node_path22.default.relative(service.dir, file.path));
|
|
7850
8454
|
let defs;
|
|
7851
8455
|
try {
|
|
7852
8456
|
const tree = parseSource3(parser, file.content);
|
|
7853
|
-
defs =
|
|
8457
|
+
defs = collectSymbolDefsForExt(ext, tree.rootNode);
|
|
7854
8458
|
} catch (err) {
|
|
7855
8459
|
recordExtractionError("symbol extraction", file.path, err);
|
|
7856
8460
|
continue;
|
|
@@ -7865,11 +8469,11 @@ async function addSymbols(graph, services) {
|
|
|
7865
8469
|
nodesAdded += fn;
|
|
7866
8470
|
edgesAdded += fe;
|
|
7867
8471
|
for (const { def, disambiguator } of disambiguate(defs)) {
|
|
7868
|
-
const sid = (0,
|
|
8472
|
+
const sid = (0, import_types18.symbolId)(service.pkg.name, relPath, def.qualname, disambiguator);
|
|
7869
8473
|
if (!graph.hasNode(sid)) {
|
|
7870
8474
|
const node = {
|
|
7871
8475
|
id: sid,
|
|
7872
|
-
type:
|
|
8476
|
+
type: import_types18.NodeType.SymbolNode,
|
|
7873
8477
|
kind: def.kind,
|
|
7874
8478
|
qualname: def.qualname,
|
|
7875
8479
|
span: { startLine: def.startLine, endLine: def.endLine },
|
|
@@ -7880,15 +8484,15 @@ async function addSymbols(graph, services) {
|
|
|
7880
8484
|
graph.addNode(sid, node);
|
|
7881
8485
|
nodesAdded++;
|
|
7882
8486
|
}
|
|
7883
|
-
const containsId = (0,
|
|
8487
|
+
const containsId = (0, import_types18.extractedEdgeId)(fileNodeId, sid, import_types18.EdgeType.CONTAINS);
|
|
7884
8488
|
if (!graph.hasEdge(containsId)) {
|
|
7885
8489
|
const edge = {
|
|
7886
8490
|
id: containsId,
|
|
7887
8491
|
source: fileNodeId,
|
|
7888
8492
|
target: sid,
|
|
7889
|
-
type:
|
|
7890
|
-
provenance:
|
|
7891
|
-
confidence: (0,
|
|
8493
|
+
type: import_types18.EdgeType.CONTAINS,
|
|
8494
|
+
provenance: import_types18.Provenance.EXTRACTED,
|
|
8495
|
+
confidence: (0, import_types18.confidenceForExtracted)("structural"),
|
|
7892
8496
|
evidence: {
|
|
7893
8497
|
file: relPath,
|
|
7894
8498
|
line: def.startLine,
|
|
@@ -7906,9 +8510,9 @@ async function addSymbols(graph, services) {
|
|
|
7906
8510
|
|
|
7907
8511
|
// src/extract/symbol-edges.ts
|
|
7908
8512
|
init_cjs_shims();
|
|
7909
|
-
var
|
|
8513
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
7910
8514
|
var import_tree_sitter4 = __toESM(require("tree-sitter"), 1);
|
|
7911
|
-
var
|
|
8515
|
+
var import_types19 = require("@neat.is/types");
|
|
7912
8516
|
function extendsInfo(classHeritage) {
|
|
7913
8517
|
for (let i = 0; i < classHeritage.namedChildCount; i++) {
|
|
7914
8518
|
const child = classHeritage.namedChild(i);
|
|
@@ -8013,10 +8617,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
8013
8617
|
const tsPaths = await loadTsPathConfig(service.dir);
|
|
8014
8618
|
const files = await loadSourceFiles(service.dir);
|
|
8015
8619
|
for (const file of files) {
|
|
8016
|
-
const parser = parserForExt5(
|
|
8620
|
+
const parser = parserForExt5(import_node_path23.default.extname(file.path));
|
|
8017
8621
|
if (!parser) continue;
|
|
8018
|
-
const relPath = toPosix(
|
|
8019
|
-
const fileDir =
|
|
8622
|
+
const relPath = toPosix(import_node_path23.default.relative(service.dir, file.path));
|
|
8623
|
+
const fileDir = import_node_path23.default.dirname(file.path);
|
|
8020
8624
|
let root;
|
|
8021
8625
|
try {
|
|
8022
8626
|
root = parseSource3(parser, file.content).rootNode;
|
|
@@ -8026,7 +8630,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
8026
8630
|
}
|
|
8027
8631
|
const disambiguated = disambiguate(collectSymbolDefs(root));
|
|
8028
8632
|
const locals = disambiguated.map(({ def, disambiguator }) => ({
|
|
8029
|
-
sid: (0,
|
|
8633
|
+
sid: (0, import_types19.symbolId)(serviceName, relPath, def.qualname, disambiguator),
|
|
8030
8634
|
qualname: def.qualname,
|
|
8031
8635
|
kind: def.kind,
|
|
8032
8636
|
startLine: def.startLine,
|
|
@@ -8055,10 +8659,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
8055
8659
|
if (local) return local.kind === wantKind ? local.sid : null;
|
|
8056
8660
|
const imp = resolvedImports.get(name);
|
|
8057
8661
|
if (imp) {
|
|
8058
|
-
const candidate = (0,
|
|
8662
|
+
const candidate = (0, import_types19.symbolId)(serviceName, imp.targetRelPath, imp.importedName);
|
|
8059
8663
|
if (graph.hasNode(candidate)) {
|
|
8060
8664
|
const node = graph.getNodeAttributes(candidate);
|
|
8061
|
-
if (node.type ===
|
|
8665
|
+
if (node.type === import_types19.NodeType.SymbolNode && node.kind === wantKind) return candidate;
|
|
8062
8666
|
}
|
|
8063
8667
|
}
|
|
8064
8668
|
return null;
|
|
@@ -8085,7 +8689,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
8085
8689
|
sourceSid: self.sid,
|
|
8086
8690
|
targetName: ext.name,
|
|
8087
8691
|
wantKind: "class",
|
|
8088
|
-
edgeType:
|
|
8692
|
+
edgeType: import_types19.EdgeType.INHERITS,
|
|
8089
8693
|
line: ext.line
|
|
8090
8694
|
});
|
|
8091
8695
|
}
|
|
@@ -8094,7 +8698,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
8094
8698
|
sourceSid: self.sid,
|
|
8095
8699
|
targetName: impl.name,
|
|
8096
8700
|
wantKind: "class",
|
|
8097
|
-
edgeType:
|
|
8701
|
+
edgeType: import_types19.EdgeType.IMPLEMENTS,
|
|
8098
8702
|
line: impl.line
|
|
8099
8703
|
});
|
|
8100
8704
|
}
|
|
@@ -8110,7 +8714,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
8110
8714
|
sourceSid: caller.sid,
|
|
8111
8715
|
targetName: fn.text,
|
|
8112
8716
|
wantKind: "function",
|
|
8113
|
-
edgeType:
|
|
8717
|
+
edgeType: import_types19.EdgeType.CALLS,
|
|
8114
8718
|
line
|
|
8115
8719
|
});
|
|
8116
8720
|
}
|
|
@@ -8126,15 +8730,15 @@ async function addSymbolEdges(graph, services) {
|
|
|
8126
8730
|
const targetSid = resolveTarget(req.targetName, req.wantKind);
|
|
8127
8731
|
if (!targetSid) continue;
|
|
8128
8732
|
if (targetSid === req.sourceSid) continue;
|
|
8129
|
-
const edgeId = (0,
|
|
8733
|
+
const edgeId = (0, import_types19.extractedEdgeId)(req.sourceSid, targetSid, req.edgeType);
|
|
8130
8734
|
if (graph.hasEdge(edgeId)) continue;
|
|
8131
8735
|
const edge = {
|
|
8132
8736
|
id: edgeId,
|
|
8133
8737
|
source: req.sourceSid,
|
|
8134
8738
|
target: targetSid,
|
|
8135
8739
|
type: req.edgeType,
|
|
8136
|
-
provenance:
|
|
8137
|
-
confidence: (0,
|
|
8740
|
+
provenance: import_types19.Provenance.EXTRACTED,
|
|
8741
|
+
confidence: (0, import_types19.confidenceForExtracted)("structural"),
|
|
8138
8742
|
evidence: {
|
|
8139
8743
|
file: relPath,
|
|
8140
8744
|
line: req.line,
|
|
@@ -8151,9 +8755,9 @@ async function addSymbolEdges(graph, services) {
|
|
|
8151
8755
|
|
|
8152
8756
|
// src/extract/actions.ts
|
|
8153
8757
|
init_cjs_shims();
|
|
8154
|
-
var
|
|
8758
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
8155
8759
|
var import_tree_sitter5 = __toESM(require("tree-sitter"), 1);
|
|
8156
|
-
var
|
|
8760
|
+
var import_types20 = require("@neat.is/types");
|
|
8157
8761
|
function stringLiteralText2(node) {
|
|
8158
8762
|
for (let i = 0; i < node.childCount; i++) {
|
|
8159
8763
|
const child = node.child(i);
|
|
@@ -8298,9 +8902,9 @@ async function addServerActions(graph, services) {
|
|
|
8298
8902
|
const files = await loadSourceFiles(service.dir);
|
|
8299
8903
|
for (const file of files) {
|
|
8300
8904
|
if (isTestPath(file.path)) continue;
|
|
8301
|
-
const parser = parserForExt5(
|
|
8905
|
+
const parser = parserForExt5(import_node_path24.default.extname(file.path));
|
|
8302
8906
|
if (!parser) continue;
|
|
8303
|
-
const relPath = toPosix(
|
|
8907
|
+
const relPath = toPosix(import_node_path24.default.relative(service.dir, file.path));
|
|
8304
8908
|
let root;
|
|
8305
8909
|
try {
|
|
8306
8910
|
root = parseSource3(parser, file.content).rootNode;
|
|
@@ -8323,11 +8927,11 @@ async function addServerActions(graph, services) {
|
|
|
8323
8927
|
nodesAdded += fn;
|
|
8324
8928
|
edgesAdded += fe;
|
|
8325
8929
|
for (const action of actions) {
|
|
8326
|
-
const aid = (0,
|
|
8930
|
+
const aid = (0, import_types20.serverActionId)(service.pkg.name, relPath, action.exportName);
|
|
8327
8931
|
if (!graph.hasNode(aid)) {
|
|
8328
8932
|
const node = {
|
|
8329
8933
|
id: aid,
|
|
8330
|
-
type:
|
|
8934
|
+
type: import_types20.NodeType.ServerActionNode,
|
|
8331
8935
|
name: action.exportName,
|
|
8332
8936
|
service: service.pkg.name,
|
|
8333
8937
|
module: relPath,
|
|
@@ -8339,15 +8943,15 @@ async function addServerActions(graph, services) {
|
|
|
8339
8943
|
graph.addNode(aid, node);
|
|
8340
8944
|
nodesAdded++;
|
|
8341
8945
|
}
|
|
8342
|
-
const containsId = (0,
|
|
8946
|
+
const containsId = (0, import_types20.extractedEdgeId)(fileNodeId, aid, import_types20.EdgeType.CONTAINS);
|
|
8343
8947
|
if (!graph.hasEdge(containsId)) {
|
|
8344
8948
|
const edge = {
|
|
8345
8949
|
id: containsId,
|
|
8346
8950
|
source: fileNodeId,
|
|
8347
8951
|
target: aid,
|
|
8348
|
-
type:
|
|
8349
|
-
provenance:
|
|
8350
|
-
confidence: (0,
|
|
8952
|
+
type: import_types20.EdgeType.CONTAINS,
|
|
8953
|
+
provenance: import_types20.Provenance.EXTRACTED,
|
|
8954
|
+
confidence: (0, import_types20.confidenceForExtracted)("structural"),
|
|
8351
8955
|
evidence: {
|
|
8352
8956
|
file: relPath,
|
|
8353
8957
|
line: action.line,
|
|
@@ -8361,10 +8965,10 @@ async function addServerActions(graph, services) {
|
|
|
8361
8965
|
}
|
|
8362
8966
|
for (const file of files) {
|
|
8363
8967
|
if (isTestPath(file.path)) continue;
|
|
8364
|
-
const parser = parserForExt5(
|
|
8968
|
+
const parser = parserForExt5(import_node_path24.default.extname(file.path));
|
|
8365
8969
|
if (!parser) continue;
|
|
8366
|
-
const relPath = toPosix(
|
|
8367
|
-
const fileDir =
|
|
8970
|
+
const relPath = toPosix(import_node_path24.default.relative(service.dir, file.path));
|
|
8971
|
+
const fileDir = import_node_path24.default.dirname(file.path);
|
|
8368
8972
|
let root;
|
|
8369
8973
|
try {
|
|
8370
8974
|
root = parseSource3(parser, file.content).rootNode;
|
|
@@ -8377,7 +8981,7 @@ async function addServerActions(graph, services) {
|
|
|
8377
8981
|
for (const [local, binding] of bindings) {
|
|
8378
8982
|
const target = await resolveJsImport(binding.specifier, fileDir, service.dir, tsPaths);
|
|
8379
8983
|
if (!target) continue;
|
|
8380
|
-
const aid = (0,
|
|
8984
|
+
const aid = (0, import_types20.serverActionId)(service.pkg.name, target, binding.importedName);
|
|
8381
8985
|
if (graph.hasNode(aid)) actionBindings.set(local, aid);
|
|
8382
8986
|
}
|
|
8383
8987
|
if (actionBindings.size === 0) continue;
|
|
@@ -8392,15 +8996,15 @@ async function addServerActions(graph, services) {
|
|
|
8392
8996
|
nodesAdded += ensured.nodesAdded;
|
|
8393
8997
|
edgesAdded += ensured.edgesAdded;
|
|
8394
8998
|
}
|
|
8395
|
-
const callsId = (0,
|
|
8999
|
+
const callsId = (0, import_types20.extractedEdgeId)(clientFileId, aid, import_types20.EdgeType.CALLS);
|
|
8396
9000
|
if (graph.hasEdge(callsId)) continue;
|
|
8397
9001
|
const edge = {
|
|
8398
9002
|
id: callsId,
|
|
8399
9003
|
source: clientFileId,
|
|
8400
9004
|
target: aid,
|
|
8401
|
-
type:
|
|
8402
|
-
provenance:
|
|
8403
|
-
confidence: (0,
|
|
9005
|
+
type: import_types20.EdgeType.CALLS,
|
|
9006
|
+
provenance: import_types20.Provenance.EXTRACTED,
|
|
9007
|
+
confidence: (0, import_types20.confidenceForExtracted)("structural"),
|
|
8404
9008
|
evidence: {
|
|
8405
9009
|
file: relPath,
|
|
8406
9010
|
line,
|
|
@@ -8417,14 +9021,14 @@ async function addServerActions(graph, services) {
|
|
|
8417
9021
|
|
|
8418
9022
|
// src/extract/databases/index.ts
|
|
8419
9023
|
init_cjs_shims();
|
|
8420
|
-
var
|
|
8421
|
-
var
|
|
9024
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
9025
|
+
var import_types21 = require("@neat.is/types");
|
|
8422
9026
|
|
|
8423
9027
|
// src/extract/databases/db-config-yaml.ts
|
|
8424
9028
|
init_cjs_shims();
|
|
8425
|
-
var
|
|
9029
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
8426
9030
|
async function parse(serviceDir) {
|
|
8427
|
-
const yamlPath =
|
|
9031
|
+
const yamlPath = import_node_path25.default.join(serviceDir, "db-config.yaml");
|
|
8428
9032
|
if (!await exists2(yamlPath)) return [];
|
|
8429
9033
|
const raw = await readYaml(yamlPath);
|
|
8430
9034
|
return [
|
|
@@ -8442,13 +9046,13 @@ var dbConfigYamlParser = { name: "db-config.yaml", parse };
|
|
|
8442
9046
|
|
|
8443
9047
|
// src/extract/databases/dotenv.ts
|
|
8444
9048
|
init_cjs_shims();
|
|
8445
|
-
var
|
|
8446
|
-
var
|
|
9049
|
+
var import_node_fs20 = require("fs");
|
|
9050
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
8447
9051
|
|
|
8448
9052
|
// src/extract/databases/shared.ts
|
|
8449
9053
|
init_cjs_shims();
|
|
8450
|
-
var
|
|
8451
|
-
var
|
|
9054
|
+
var import_node_fs19 = require("fs");
|
|
9055
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
8452
9056
|
function schemeToEngine(scheme) {
|
|
8453
9057
|
const s = scheme.toLowerCase().split("+")[0];
|
|
8454
9058
|
switch (s) {
|
|
@@ -8487,18 +9091,18 @@ function parseConnectionString(url) {
|
|
|
8487
9091
|
}
|
|
8488
9092
|
async function readIfExists(filePath) {
|
|
8489
9093
|
try {
|
|
8490
|
-
return await
|
|
9094
|
+
return await import_node_fs19.promises.readFile(filePath, "utf8");
|
|
8491
9095
|
} catch {
|
|
8492
9096
|
return null;
|
|
8493
9097
|
}
|
|
8494
9098
|
}
|
|
8495
9099
|
async function resolveEnvVar(serviceDir, name) {
|
|
8496
|
-
const entries = await
|
|
9100
|
+
const entries = await import_node_fs19.promises.readdir(serviceDir, { withFileTypes: true }).catch(() => []);
|
|
8497
9101
|
const envNames = entries.filter((e) => e.isFile() && (e.name === ".env" || e.name.startsWith(".env."))).map((e) => e.name);
|
|
8498
9102
|
const rank = (n) => n === ".env.local" ? 0 : n === ".env" ? 1 : 2;
|
|
8499
9103
|
envNames.sort((a, b) => rank(a) - rank(b) || a.localeCompare(b));
|
|
8500
9104
|
for (const fileName of envNames) {
|
|
8501
|
-
const content = await readIfExists(
|
|
9105
|
+
const content = await readIfExists(import_node_path26.default.join(serviceDir, fileName));
|
|
8502
9106
|
if (!content) continue;
|
|
8503
9107
|
for (const line of content.split("\n")) {
|
|
8504
9108
|
const trimmed = line.trim();
|
|
@@ -8517,7 +9121,7 @@ async function resolveEnvVar(serviceDir, name) {
|
|
|
8517
9121
|
}
|
|
8518
9122
|
async function findFirst(serviceDir, candidates) {
|
|
8519
9123
|
for (const rel of candidates) {
|
|
8520
|
-
const abs =
|
|
9124
|
+
const abs = import_node_path26.default.join(serviceDir, rel);
|
|
8521
9125
|
const content = await readIfExists(abs);
|
|
8522
9126
|
if (content !== null) return abs;
|
|
8523
9127
|
}
|
|
@@ -8575,15 +9179,15 @@ function parseDotenvLine(line) {
|
|
|
8575
9179
|
return { key, value };
|
|
8576
9180
|
}
|
|
8577
9181
|
async function parse2(serviceDir) {
|
|
8578
|
-
const entries = await
|
|
9182
|
+
const entries = await import_node_fs20.promises.readdir(serviceDir, { withFileTypes: true }).catch(() => []);
|
|
8579
9183
|
const configs = [];
|
|
8580
9184
|
const seen = /* @__PURE__ */ new Set();
|
|
8581
9185
|
for (const entry of entries) {
|
|
8582
9186
|
if (!entry.isFile()) continue;
|
|
8583
9187
|
const match = isConfigFile(entry.name);
|
|
8584
9188
|
if (!match.match || match.fileType !== "env") continue;
|
|
8585
|
-
const filePath =
|
|
8586
|
-
const content = await
|
|
9189
|
+
const filePath = import_node_path27.default.join(serviceDir, entry.name);
|
|
9190
|
+
const content = await import_node_fs20.promises.readFile(filePath, "utf8");
|
|
8587
9191
|
for (const line of content.split("\n")) {
|
|
8588
9192
|
const parsed = parseDotenvLine(line);
|
|
8589
9193
|
if (!parsed) continue;
|
|
@@ -8602,9 +9206,9 @@ var dotenvParser = { name: ".env", parse: parse2 };
|
|
|
8602
9206
|
|
|
8603
9207
|
// src/extract/databases/prisma.ts
|
|
8604
9208
|
init_cjs_shims();
|
|
8605
|
-
var
|
|
9209
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
8606
9210
|
async function parse3(serviceDir) {
|
|
8607
|
-
const schemaPath =
|
|
9211
|
+
const schemaPath = import_node_path28.default.join(serviceDir, "prisma", "schema.prisma");
|
|
8608
9212
|
const content = await readIfExists(schemaPath);
|
|
8609
9213
|
if (!content) return [];
|
|
8610
9214
|
const block = content.match(/datasource\s+\w+\s*\{([^}]*)\}/s);
|
|
@@ -8762,10 +9366,10 @@ var knexParser = { name: "knex", parse: parse5 };
|
|
|
8762
9366
|
|
|
8763
9367
|
// src/extract/databases/ormconfig.ts
|
|
8764
9368
|
init_cjs_shims();
|
|
8765
|
-
var
|
|
9369
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
8766
9370
|
async function parse6(serviceDir) {
|
|
8767
9371
|
for (const candidate of ["ormconfig.json", "ormconfig.yaml", "ormconfig.yml"]) {
|
|
8768
|
-
const abs =
|
|
9372
|
+
const abs = import_node_path29.default.join(serviceDir, candidate);
|
|
8769
9373
|
if (!await exists2(abs)) continue;
|
|
8770
9374
|
const raw = candidate.endsWith(".json") ? await readJson(abs) : await readYaml(abs);
|
|
8771
9375
|
const entries = Array.isArray(raw) ? raw : [raw];
|
|
@@ -8825,9 +9429,9 @@ var typeormParser = { name: "typeorm", parse: parse7 };
|
|
|
8825
9429
|
|
|
8826
9430
|
// src/extract/databases/sequelize.ts
|
|
8827
9431
|
init_cjs_shims();
|
|
8828
|
-
var
|
|
9432
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
8829
9433
|
async function parse8(serviceDir) {
|
|
8830
|
-
const configPath =
|
|
9434
|
+
const configPath = import_node_path30.default.join(serviceDir, "config", "config.json");
|
|
8831
9435
|
if (!await exists2(configPath)) return [];
|
|
8832
9436
|
const raw = await readJson(configPath);
|
|
8833
9437
|
const out = [];
|
|
@@ -8854,7 +9458,7 @@ var sequelizeParser = { name: "sequelize", parse: parse8 };
|
|
|
8854
9458
|
|
|
8855
9459
|
// src/extract/databases/docker-compose.ts
|
|
8856
9460
|
init_cjs_shims();
|
|
8857
|
-
var
|
|
9461
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
8858
9462
|
function portFromService(svc) {
|
|
8859
9463
|
for (const raw of svc.ports ?? []) {
|
|
8860
9464
|
const str = String(raw);
|
|
@@ -8881,7 +9485,7 @@ function databaseFromEnv(svc) {
|
|
|
8881
9485
|
}
|
|
8882
9486
|
async function parse9(serviceDir) {
|
|
8883
9487
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
8884
|
-
const abs =
|
|
9488
|
+
const abs = import_node_path31.default.join(serviceDir, name);
|
|
8885
9489
|
if (!await exists2(abs)) continue;
|
|
8886
9490
|
const raw = await readYaml(abs);
|
|
8887
9491
|
if (!raw?.services) return [];
|
|
@@ -8922,8 +9526,8 @@ function compatibleDriversFor(engine) {
|
|
|
8922
9526
|
}
|
|
8923
9527
|
function toDatabaseNode(config) {
|
|
8924
9528
|
return {
|
|
8925
|
-
id: (0,
|
|
8926
|
-
type:
|
|
9529
|
+
id: (0, import_types21.databaseId)(config.host),
|
|
9530
|
+
type: import_types21.NodeType.DatabaseNode,
|
|
8927
9531
|
name: config.database || config.host,
|
|
8928
9532
|
engine: config.engine,
|
|
8929
9533
|
engineVersion: config.engineVersion,
|
|
@@ -9053,7 +9657,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
9053
9657
|
discoveredVia: mergedDiscoveredVia
|
|
9054
9658
|
});
|
|
9055
9659
|
}
|
|
9056
|
-
const relConfigFile = toPosix(
|
|
9660
|
+
const relConfigFile = toPosix(import_node_path32.default.relative(service.dir, config.sourceFile));
|
|
9057
9661
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
9058
9662
|
graph,
|
|
9059
9663
|
service.pkg.name,
|
|
@@ -9062,14 +9666,14 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
9062
9666
|
);
|
|
9063
9667
|
nodesAdded += fn;
|
|
9064
9668
|
edgesAdded += fe;
|
|
9065
|
-
const evidenceFile = toPosix(
|
|
9669
|
+
const evidenceFile = toPosix(import_node_path32.default.relative(scanPath, config.sourceFile));
|
|
9066
9670
|
const edge = {
|
|
9067
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id,
|
|
9671
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id, import_types21.EdgeType.CONNECTS_TO),
|
|
9068
9672
|
source: fileNodeId,
|
|
9069
9673
|
target: dbNode.id,
|
|
9070
|
-
type:
|
|
9071
|
-
provenance:
|
|
9072
|
-
confidence: (0,
|
|
9674
|
+
type: import_types21.EdgeType.CONNECTS_TO,
|
|
9675
|
+
provenance: import_types21.Provenance.EXTRACTED,
|
|
9676
|
+
confidence: (0, import_types21.confidenceForExtracted)("structural"),
|
|
9073
9677
|
evidence: { file: evidenceFile }
|
|
9074
9678
|
};
|
|
9075
9679
|
if (!graph.hasEdge(edge.id)) {
|
|
@@ -9080,26 +9684,26 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
9080
9684
|
if (allConfigs.length === 1) {
|
|
9081
9685
|
const primary = allConfigs[0];
|
|
9082
9686
|
service.node.dbConnectionTarget = primary.port ? `${primary.host}:${primary.port}` : primary.host;
|
|
9083
|
-
const relPath =
|
|
9084
|
-
const cfgId = (0,
|
|
9687
|
+
const relPath = import_node_path32.default.relative(scanPath, primary.sourceFile);
|
|
9688
|
+
const cfgId = (0, import_types21.configId)(relPath);
|
|
9085
9689
|
if (!graph.hasNode(cfgId)) {
|
|
9086
9690
|
const cfgNode = {
|
|
9087
9691
|
id: cfgId,
|
|
9088
|
-
type:
|
|
9089
|
-
name:
|
|
9692
|
+
type: import_types21.NodeType.ConfigNode,
|
|
9693
|
+
name: import_node_path32.default.basename(primary.sourceFile),
|
|
9090
9694
|
path: relPath,
|
|
9091
|
-
fileType: isConfigFile(
|
|
9695
|
+
fileType: isConfigFile(import_node_path32.default.basename(primary.sourceFile)).fileType || "config"
|
|
9092
9696
|
};
|
|
9093
9697
|
graph.addNode(cfgId, cfgNode);
|
|
9094
9698
|
nodesAdded++;
|
|
9095
9699
|
}
|
|
9096
9700
|
const cfgEdge = {
|
|
9097
|
-
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId,
|
|
9701
|
+
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId, import_types21.EdgeType.CONFIGURED_BY),
|
|
9098
9702
|
source: service.node.id,
|
|
9099
9703
|
target: cfgId,
|
|
9100
|
-
type:
|
|
9101
|
-
provenance:
|
|
9102
|
-
confidence: (0,
|
|
9704
|
+
type: import_types21.EdgeType.CONFIGURED_BY,
|
|
9705
|
+
provenance: import_types21.Provenance.EXTRACTED,
|
|
9706
|
+
confidence: (0, import_types21.confidenceForExtracted)("structural"),
|
|
9103
9707
|
evidence: { file: toPosix(relPath) }
|
|
9104
9708
|
};
|
|
9105
9709
|
if (!graph.hasEdge(cfgEdge.id)) {
|
|
@@ -9129,15 +9733,15 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
9129
9733
|
|
|
9130
9734
|
// src/extract/configs.ts
|
|
9131
9735
|
init_cjs_shims();
|
|
9132
|
-
var
|
|
9133
|
-
var
|
|
9134
|
-
var
|
|
9736
|
+
var import_node_fs21 = require("fs");
|
|
9737
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
9738
|
+
var import_types22 = require("@neat.is/types");
|
|
9135
9739
|
async function walkConfigFiles(dir) {
|
|
9136
9740
|
const out = [];
|
|
9137
9741
|
async function walk9(current) {
|
|
9138
|
-
const entries = await
|
|
9742
|
+
const entries = await import_node_fs21.promises.readdir(current, { withFileTypes: true });
|
|
9139
9743
|
for (const entry of entries) {
|
|
9140
|
-
const full =
|
|
9744
|
+
const full = import_node_path33.default.join(current, entry.name);
|
|
9141
9745
|
if (entry.isDirectory()) {
|
|
9142
9746
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
9143
9747
|
if (await isPythonVenvDir(full)) continue;
|
|
@@ -9156,19 +9760,19 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
9156
9760
|
for (const service of services) {
|
|
9157
9761
|
const configFiles = await walkConfigFiles(service.dir);
|
|
9158
9762
|
for (const file of configFiles) {
|
|
9159
|
-
const relPath =
|
|
9763
|
+
const relPath = import_node_path33.default.relative(scanPath, file);
|
|
9160
9764
|
const node = {
|
|
9161
|
-
id: (0,
|
|
9162
|
-
type:
|
|
9163
|
-
name:
|
|
9765
|
+
id: (0, import_types22.configId)(relPath),
|
|
9766
|
+
type: import_types22.NodeType.ConfigNode,
|
|
9767
|
+
name: import_node_path33.default.basename(file),
|
|
9164
9768
|
path: relPath,
|
|
9165
|
-
fileType: isConfigFile(
|
|
9769
|
+
fileType: isConfigFile(import_node_path33.default.basename(file)).fileType
|
|
9166
9770
|
};
|
|
9167
9771
|
if (!graph.hasNode(node.id)) {
|
|
9168
9772
|
graph.addNode(node.id, node);
|
|
9169
9773
|
nodesAdded++;
|
|
9170
9774
|
}
|
|
9171
|
-
const relToService = toPosix(
|
|
9775
|
+
const relToService = toPosix(import_node_path33.default.relative(service.dir, file));
|
|
9172
9776
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
9173
9777
|
graph,
|
|
9174
9778
|
service.pkg.name,
|
|
@@ -9178,13 +9782,13 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
9178
9782
|
nodesAdded += fn;
|
|
9179
9783
|
edgesAdded += fe;
|
|
9180
9784
|
const edge = {
|
|
9181
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
9785
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types22.EdgeType.CONFIGURED_BY),
|
|
9182
9786
|
source: fileNodeId,
|
|
9183
9787
|
target: node.id,
|
|
9184
|
-
type:
|
|
9185
|
-
provenance:
|
|
9186
|
-
confidence: (0,
|
|
9187
|
-
evidence: { file: relPath.split(
|
|
9788
|
+
type: import_types22.EdgeType.CONFIGURED_BY,
|
|
9789
|
+
provenance: import_types22.Provenance.EXTRACTED,
|
|
9790
|
+
confidence: (0, import_types22.confidenceForExtracted)("structural"),
|
|
9791
|
+
evidence: { file: relPath.split(import_node_path33.default.sep).join("/") }
|
|
9188
9792
|
};
|
|
9189
9793
|
if (!graph.hasEdge(edge.id)) {
|
|
9190
9794
|
graph.addEdgeWithKey(edge.id, edge.source, edge.target, edge);
|
|
@@ -9197,9 +9801,9 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
9197
9801
|
|
|
9198
9802
|
// src/extract/proto.ts
|
|
9199
9803
|
init_cjs_shims();
|
|
9200
|
-
var
|
|
9201
|
-
var
|
|
9202
|
-
var
|
|
9804
|
+
var import_node_fs22 = require("fs");
|
|
9805
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
9806
|
+
var import_types23 = require("@neat.is/types");
|
|
9203
9807
|
var PROTO_EXTENSION = ".proto";
|
|
9204
9808
|
function packageOf(content) {
|
|
9205
9809
|
const m = content.match(/^\s*package\s+([A-Za-z_][A-Za-z0-9_.]*)\s*;/m);
|
|
@@ -9238,14 +9842,14 @@ function grpcMethodsFromProto(content, fqPackage) {
|
|
|
9238
9842
|
async function walkProtoFiles(dir) {
|
|
9239
9843
|
const out = [];
|
|
9240
9844
|
async function walk9(current) {
|
|
9241
|
-
const entries = await
|
|
9845
|
+
const entries = await import_node_fs22.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
9242
9846
|
for (const entry of entries) {
|
|
9243
|
-
const full =
|
|
9847
|
+
const full = import_node_path34.default.join(current, entry.name);
|
|
9244
9848
|
if (entry.isDirectory()) {
|
|
9245
9849
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
9246
9850
|
if (await isPythonVenvDir(full)) continue;
|
|
9247
9851
|
await walk9(full);
|
|
9248
|
-
} else if (entry.isFile() &&
|
|
9852
|
+
} else if (entry.isFile() && import_node_path34.default.extname(entry.name) === PROTO_EXTENSION) {
|
|
9249
9853
|
out.push(full);
|
|
9250
9854
|
}
|
|
9251
9855
|
}
|
|
@@ -9260,10 +9864,10 @@ async function addGrpcMethods(graph, services) {
|
|
|
9260
9864
|
const protoPaths = await walkProtoFiles(service.dir);
|
|
9261
9865
|
for (const protoPath of protoPaths) {
|
|
9262
9866
|
if (isTestPath(protoPath)) continue;
|
|
9263
|
-
const relFile = toPosix(
|
|
9867
|
+
const relFile = toPosix(import_node_path34.default.relative(service.dir, protoPath));
|
|
9264
9868
|
let content;
|
|
9265
9869
|
try {
|
|
9266
|
-
content = await
|
|
9870
|
+
content = await import_node_fs22.promises.readFile(protoPath, "utf8");
|
|
9267
9871
|
} catch (err) {
|
|
9268
9872
|
recordExtractionError("proto extraction", protoPath, err);
|
|
9269
9873
|
continue;
|
|
@@ -9277,11 +9881,11 @@ async function addGrpcMethods(graph, services) {
|
|
|
9277
9881
|
}
|
|
9278
9882
|
if (methods.length === 0) continue;
|
|
9279
9883
|
for (const method of methods) {
|
|
9280
|
-
const mid = (0,
|
|
9884
|
+
const mid = (0, import_types23.grpcMethodId)(method.rpcService, method.rpcMethod);
|
|
9281
9885
|
if (!graph.hasNode(mid)) {
|
|
9282
9886
|
const node = {
|
|
9283
9887
|
id: mid,
|
|
9284
|
-
type:
|
|
9888
|
+
type: import_types23.NodeType.GrpcMethodNode,
|
|
9285
9889
|
name: `${method.rpcService}/${method.rpcMethod}`,
|
|
9286
9890
|
rpcService: method.rpcService,
|
|
9287
9891
|
rpcMethod: method.rpcMethod,
|
|
@@ -9292,15 +9896,15 @@ async function addGrpcMethods(graph, services) {
|
|
|
9292
9896
|
graph.addNode(mid, node);
|
|
9293
9897
|
nodesAdded++;
|
|
9294
9898
|
}
|
|
9295
|
-
const containsId = (0,
|
|
9899
|
+
const containsId = (0, import_types23.extractedEdgeId)(service.node.id, mid, import_types23.EdgeType.CONTAINS);
|
|
9296
9900
|
if (!graph.hasEdge(containsId)) {
|
|
9297
9901
|
const edge = {
|
|
9298
9902
|
id: containsId,
|
|
9299
9903
|
source: service.node.id,
|
|
9300
9904
|
target: mid,
|
|
9301
|
-
type:
|
|
9302
|
-
provenance:
|
|
9303
|
-
confidence: (0,
|
|
9905
|
+
type: import_types23.EdgeType.CONTAINS,
|
|
9906
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
9907
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9304
9908
|
evidence: {
|
|
9305
9909
|
file: relFile,
|
|
9306
9910
|
line: method.line,
|
|
@@ -9318,16 +9922,16 @@ async function addGrpcMethods(graph, services) {
|
|
|
9318
9922
|
|
|
9319
9923
|
// src/extract/calls/index.ts
|
|
9320
9924
|
init_cjs_shims();
|
|
9321
|
-
var
|
|
9925
|
+
var import_types41 = require("@neat.is/types");
|
|
9322
9926
|
|
|
9323
9927
|
// src/extract/calls/http.ts
|
|
9324
9928
|
init_cjs_shims();
|
|
9325
|
-
var
|
|
9929
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
9326
9930
|
var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
9327
9931
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
9328
9932
|
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
9329
|
-
var
|
|
9330
|
-
var
|
|
9933
|
+
var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
|
|
9934
|
+
var import_types24 = require("@neat.is/types");
|
|
9331
9935
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
9332
9936
|
var JSX_EXTERNAL_LINK_TAGS = /* @__PURE__ */ new Set(["a", "Link", "NavLink", "ExternalLink", "Anchor"]);
|
|
9333
9937
|
function isInsideJsxExternalLink(node) {
|
|
@@ -9383,7 +9987,7 @@ var GRAMMAR_BY_EXT2 = {
|
|
|
9383
9987
|
".jsx": import_tree_sitter_javascript4.default,
|
|
9384
9988
|
".mjs": import_tree_sitter_javascript4.default,
|
|
9385
9989
|
".cjs": import_tree_sitter_javascript4.default,
|
|
9386
|
-
".py":
|
|
9990
|
+
".py": import_tree_sitter_python4.default
|
|
9387
9991
|
};
|
|
9388
9992
|
function parserForExt(ext, cache) {
|
|
9389
9993
|
const grammar = GRAMMAR_BY_EXT2[ext] ?? import_tree_sitter_javascript4.default;
|
|
@@ -9405,7 +10009,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
9405
10009
|
const seen = /* @__PURE__ */ new Set();
|
|
9406
10010
|
for (const file of files) {
|
|
9407
10011
|
if (isTestPath(file.path)) continue;
|
|
9408
|
-
const parser = parserForExt(
|
|
10012
|
+
const parser = parserForExt(import_node_path35.default.extname(file.path), parserCache);
|
|
9409
10013
|
let sites;
|
|
9410
10014
|
try {
|
|
9411
10015
|
sites = callsFromSource(file.content, parser, knownHosts);
|
|
@@ -9414,14 +10018,14 @@ async function addHttpCallEdges(graph, services) {
|
|
|
9414
10018
|
continue;
|
|
9415
10019
|
}
|
|
9416
10020
|
if (sites.length === 0) continue;
|
|
9417
|
-
const relFile = toPosix(
|
|
10021
|
+
const relFile = toPosix(import_node_path35.default.relative(service.dir, file.path));
|
|
9418
10022
|
for (const site of sites) {
|
|
9419
10023
|
const targetId = hostToNodeId.get(site.host);
|
|
9420
10024
|
if (!targetId || targetId === service.node.id) continue;
|
|
9421
10025
|
const dedupKey = `${relFile}|${targetId}`;
|
|
9422
10026
|
if (seen.has(dedupKey)) continue;
|
|
9423
10027
|
seen.add(dedupKey);
|
|
9424
|
-
const confidence = (0,
|
|
10028
|
+
const confidence = (0, import_types24.confidenceForExtracted)("url-literal-service-target");
|
|
9425
10029
|
const ev = {
|
|
9426
10030
|
file: relFile,
|
|
9427
10031
|
line: site.line,
|
|
@@ -9435,25 +10039,25 @@ async function addHttpCallEdges(graph, services) {
|
|
|
9435
10039
|
);
|
|
9436
10040
|
nodesAdded += n;
|
|
9437
10041
|
edgesAdded += e;
|
|
9438
|
-
if (!(0,
|
|
10042
|
+
if (!(0, import_types24.passesExtractedFloor)(confidence)) {
|
|
9439
10043
|
noteExtractedDropped({
|
|
9440
10044
|
source: fileNodeId,
|
|
9441
10045
|
target: targetId,
|
|
9442
|
-
type:
|
|
10046
|
+
type: import_types24.EdgeType.CALLS,
|
|
9443
10047
|
confidence,
|
|
9444
10048
|
confidenceKind: "url-literal-service-target",
|
|
9445
10049
|
evidence: ev
|
|
9446
10050
|
});
|
|
9447
10051
|
continue;
|
|
9448
10052
|
}
|
|
9449
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId,
|
|
10053
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId, import_types24.EdgeType.CALLS);
|
|
9450
10054
|
if (!graph.hasEdge(edgeId)) {
|
|
9451
10055
|
const edge = {
|
|
9452
10056
|
id: edgeId,
|
|
9453
10057
|
source: fileNodeId,
|
|
9454
10058
|
target: targetId,
|
|
9455
|
-
type:
|
|
9456
|
-
provenance:
|
|
10059
|
+
type: import_types24.EdgeType.CALLS,
|
|
10060
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
9457
10061
|
confidence,
|
|
9458
10062
|
evidence: ev
|
|
9459
10063
|
};
|
|
@@ -9468,10 +10072,10 @@ async function addHttpCallEdges(graph, services) {
|
|
|
9468
10072
|
|
|
9469
10073
|
// src/extract/calls/route-match.ts
|
|
9470
10074
|
init_cjs_shims();
|
|
9471
|
-
var
|
|
10075
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
9472
10076
|
var import_tree_sitter7 = __toESM(require("tree-sitter"), 1);
|
|
9473
10077
|
var import_tree_sitter_javascript5 = __toESM(require("tree-sitter-javascript"), 1);
|
|
9474
|
-
var
|
|
10078
|
+
var import_types25 = require("@neat.is/types");
|
|
9475
10079
|
var PARSE_CHUNK5 = 16384;
|
|
9476
10080
|
function parseSource5(parser, source) {
|
|
9477
10081
|
return parser.parse(
|
|
@@ -9636,9 +10240,9 @@ function buildRouteIndex(graph) {
|
|
|
9636
10240
|
const index = /* @__PURE__ */ new Map();
|
|
9637
10241
|
graph.forEachNode((_id, attrs) => {
|
|
9638
10242
|
const node = attrs;
|
|
9639
|
-
if (node.type !==
|
|
10243
|
+
if (node.type !== import_types25.NodeType.RouteNode) return;
|
|
9640
10244
|
const route = attrs;
|
|
9641
|
-
const owner = (0,
|
|
10245
|
+
const owner = (0, import_types25.serviceId)(route.service);
|
|
9642
10246
|
const entry = {
|
|
9643
10247
|
method: route.method.toUpperCase(),
|
|
9644
10248
|
normalizedPath: normalizePathTemplate(route.pathTemplate),
|
|
@@ -9667,7 +10271,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
9667
10271
|
const seen = /* @__PURE__ */ new Set();
|
|
9668
10272
|
for (const file of files) {
|
|
9669
10273
|
if (isTestPath(file.path)) continue;
|
|
9670
|
-
if (!JS_CLIENT_EXTENSIONS.has(
|
|
10274
|
+
if (!JS_CLIENT_EXTENSIONS.has(import_node_path36.default.extname(file.path))) continue;
|
|
9671
10275
|
let sites;
|
|
9672
10276
|
try {
|
|
9673
10277
|
sites = clientCallSitesFromSource(file.content, jsParser, knownHosts);
|
|
@@ -9676,7 +10280,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
9676
10280
|
continue;
|
|
9677
10281
|
}
|
|
9678
10282
|
if (sites.length === 0) continue;
|
|
9679
|
-
const relFile = toPosix(
|
|
10283
|
+
const relFile = toPosix(import_node_path36.default.relative(service.dir, file.path));
|
|
9680
10284
|
for (const site of sites) {
|
|
9681
10285
|
const serverServiceId = hostToNodeId.get(site.host);
|
|
9682
10286
|
if (!serverServiceId || serverServiceId === service.node.id) continue;
|
|
@@ -9696,7 +10300,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
9696
10300
|
);
|
|
9697
10301
|
nodesAdded += n;
|
|
9698
10302
|
edgesAdded += e;
|
|
9699
|
-
const confidence = (0,
|
|
10303
|
+
const confidence = (0, import_types25.confidenceForExtracted)("verified-call-site");
|
|
9700
10304
|
const ev = {
|
|
9701
10305
|
file: relFile,
|
|
9702
10306
|
line: site.line,
|
|
@@ -9704,25 +10308,25 @@ async function addRouteCallEdges(graph, services) {
|
|
|
9704
10308
|
method: site.method ?? match.method,
|
|
9705
10309
|
pathTemplate: site.pathTemplate
|
|
9706
10310
|
};
|
|
9707
|
-
if (!(0,
|
|
10311
|
+
if (!(0, import_types25.passesExtractedFloor)(confidence)) {
|
|
9708
10312
|
noteExtractedDropped({
|
|
9709
10313
|
source: fileNodeId,
|
|
9710
10314
|
target: match.routeNodeId,
|
|
9711
|
-
type:
|
|
10315
|
+
type: import_types25.EdgeType.CALLS,
|
|
9712
10316
|
confidence,
|
|
9713
10317
|
confidenceKind: "verified-call-site",
|
|
9714
10318
|
evidence: ev
|
|
9715
10319
|
});
|
|
9716
10320
|
continue;
|
|
9717
10321
|
}
|
|
9718
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId,
|
|
10322
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId, import_types25.EdgeType.CALLS);
|
|
9719
10323
|
if (!graph.hasEdge(edgeId)) {
|
|
9720
10324
|
const edge = {
|
|
9721
10325
|
id: edgeId,
|
|
9722
10326
|
source: fileNodeId,
|
|
9723
10327
|
target: match.routeNodeId,
|
|
9724
|
-
type:
|
|
9725
|
-
provenance:
|
|
10328
|
+
type: import_types25.EdgeType.CALLS,
|
|
10329
|
+
provenance: import_types25.Provenance.EXTRACTED,
|
|
9726
10330
|
confidence,
|
|
9727
10331
|
evidence: ev
|
|
9728
10332
|
};
|
|
@@ -9737,8 +10341,8 @@ async function addRouteCallEdges(graph, services) {
|
|
|
9737
10341
|
|
|
9738
10342
|
// src/extract/calls/kafka.ts
|
|
9739
10343
|
init_cjs_shims();
|
|
9740
|
-
var
|
|
9741
|
-
var
|
|
10344
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
10345
|
+
var import_types26 = require("@neat.is/types");
|
|
9742
10346
|
var PRODUCER_TOPIC_RE = /(?:producer|kafkaProducer)[\s\S]{0,40}?\.send\s*\(\s*\{[\s\S]{0,200}?topic\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
9743
10347
|
var CONSUMER_TOPIC_RE = /(?:consumer|kafkaConsumer)[\s\S]{0,40}?\.(?:subscribe|run)\s*\(\s*\{[\s\S]{0,200}?topic[s]?\s*:\s*(?:\[\s*)?['"`]([^'"`]+)['"`]/g;
|
|
9744
10348
|
function findAll(re, text) {
|
|
@@ -9759,7 +10363,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
9759
10363
|
seen.add(key);
|
|
9760
10364
|
const line = lineOf(file.content, topic);
|
|
9761
10365
|
out.push({
|
|
9762
|
-
infraId: (0,
|
|
10366
|
+
infraId: (0, import_types26.infraId)("kafka-topic", topic),
|
|
9763
10367
|
name: topic,
|
|
9764
10368
|
kind: "kafka-topic",
|
|
9765
10369
|
edgeType,
|
|
@@ -9768,7 +10372,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
9768
10372
|
// tier (ADR-066).
|
|
9769
10373
|
confidenceKind: "verified-call-site",
|
|
9770
10374
|
evidence: {
|
|
9771
|
-
file:
|
|
10375
|
+
file: import_node_path37.default.relative(serviceDir, file.path),
|
|
9772
10376
|
line,
|
|
9773
10377
|
snippet: snippet(file.content, line)
|
|
9774
10378
|
}
|
|
@@ -9781,8 +10385,8 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
9781
10385
|
|
|
9782
10386
|
// src/extract/calls/redis.ts
|
|
9783
10387
|
init_cjs_shims();
|
|
9784
|
-
var
|
|
9785
|
-
var
|
|
10388
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
10389
|
+
var import_types27 = require("@neat.is/types");
|
|
9786
10390
|
var REDIS_URL_RE = /redis(?:s)?:\/\/(?:[^@'"`\s]+@)?([^:/'"`\s]+)(?::(\d+))?/g;
|
|
9787
10391
|
function redisEndpointsFromFile(file, serviceDir) {
|
|
9788
10392
|
const out = [];
|
|
@@ -9795,7 +10399,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
9795
10399
|
seen.add(host);
|
|
9796
10400
|
const line = lineOf(file.content, host);
|
|
9797
10401
|
out.push({
|
|
9798
|
-
infraId: (0,
|
|
10402
|
+
infraId: (0, import_types27.infraId)("redis", host),
|
|
9799
10403
|
name: host,
|
|
9800
10404
|
kind: "redis",
|
|
9801
10405
|
edgeType: "CALLS",
|
|
@@ -9804,7 +10408,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
9804
10408
|
// support tier (ADR-066).
|
|
9805
10409
|
confidenceKind: "url-with-structural-support",
|
|
9806
10410
|
evidence: {
|
|
9807
|
-
file:
|
|
10411
|
+
file: import_node_path38.default.relative(serviceDir, file.path),
|
|
9808
10412
|
line,
|
|
9809
10413
|
snippet: snippet(file.content, line)
|
|
9810
10414
|
}
|
|
@@ -9815,8 +10419,8 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
9815
10419
|
|
|
9816
10420
|
// src/extract/calls/aws.ts
|
|
9817
10421
|
init_cjs_shims();
|
|
9818
|
-
var
|
|
9819
|
-
var
|
|
10422
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
10423
|
+
var import_types28 = require("@neat.is/types");
|
|
9820
10424
|
var S3_BUCKET_RE = /Bucket\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
9821
10425
|
var DYNAMO_TABLE_RE = /TableName\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
9822
10426
|
function hasMarker(text, markers) {
|
|
@@ -9840,7 +10444,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
9840
10444
|
seen.add(key);
|
|
9841
10445
|
const line = lineOf(file.content, name);
|
|
9842
10446
|
out.push({
|
|
9843
|
-
infraId: (0,
|
|
10447
|
+
infraId: (0, import_types28.infraId)(kind, name),
|
|
9844
10448
|
name,
|
|
9845
10449
|
kind,
|
|
9846
10450
|
edgeType: "CALLS",
|
|
@@ -9849,7 +10453,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
9849
10453
|
// (ADR-066).
|
|
9850
10454
|
confidenceKind: "verified-call-site",
|
|
9851
10455
|
evidence: {
|
|
9852
|
-
file:
|
|
10456
|
+
file: import_node_path39.default.relative(serviceDir, file.path),
|
|
9853
10457
|
line,
|
|
9854
10458
|
snippet: snippet(file.content, line)
|
|
9855
10459
|
}
|
|
@@ -9874,8 +10478,8 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
9874
10478
|
|
|
9875
10479
|
// src/extract/calls/grpc.ts
|
|
9876
10480
|
init_cjs_shims();
|
|
9877
|
-
var
|
|
9878
|
-
var
|
|
10481
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
10482
|
+
var import_types29 = require("@neat.is/types");
|
|
9879
10483
|
var GRPC_CLIENT_RE = /new\s+([A-Z][A-Za-z0-9_]*)Client\s*\(\s*['"`]?([^,'"`)]+)?/g;
|
|
9880
10484
|
var AWS_SDK_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@aws-sdk\/client-([a-z0-9-]+)['"`]/g;
|
|
9881
10485
|
var GRPC_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@grpc\/grpc-js['"`]|_grpc_pb['"`]/;
|
|
@@ -9924,7 +10528,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
9924
10528
|
const { kind } = classified;
|
|
9925
10529
|
const line = lineOf(file.content, m[0]);
|
|
9926
10530
|
out.push({
|
|
9927
|
-
infraId: (0,
|
|
10531
|
+
infraId: (0, import_types29.infraId)(kind, name),
|
|
9928
10532
|
name,
|
|
9929
10533
|
kind,
|
|
9930
10534
|
edgeType: "CALLS",
|
|
@@ -9933,7 +10537,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
9933
10537
|
// tier (ADR-066).
|
|
9934
10538
|
confidenceKind: "verified-call-site",
|
|
9935
10539
|
evidence: {
|
|
9936
|
-
file:
|
|
10540
|
+
file: import_node_path40.default.relative(serviceDir, file.path),
|
|
9937
10541
|
line,
|
|
9938
10542
|
snippet: snippet(file.content, line)
|
|
9939
10543
|
}
|
|
@@ -9944,8 +10548,8 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
9944
10548
|
|
|
9945
10549
|
// src/extract/calls/supabase.ts
|
|
9946
10550
|
init_cjs_shims();
|
|
9947
|
-
var
|
|
9948
|
-
var
|
|
10551
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
10552
|
+
var import_types30 = require("@neat.is/types");
|
|
9949
10553
|
var SUPABASE_JS_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/supabase-js['"`]/;
|
|
9950
10554
|
var SUPABASE_SSR_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/ssr['"`]/;
|
|
9951
10555
|
var SUPABASE_CLIENT_RE = /\b(createClient|createServerClient|createBrowserClient)\s*\(\s*(?:['"`]([^'"`]*)['"`])?/g;
|
|
@@ -9993,7 +10597,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
9993
10597
|
seen.add(name);
|
|
9994
10598
|
const line = lineOf(file.content, m[0]);
|
|
9995
10599
|
out.push({
|
|
9996
|
-
infraId: (0,
|
|
10600
|
+
infraId: (0, import_types30.infraId)("supabase", name),
|
|
9997
10601
|
name,
|
|
9998
10602
|
kind: "supabase",
|
|
9999
10603
|
edgeType: "CALLS",
|
|
@@ -10003,7 +10607,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
10003
10607
|
// tier (ADR-066), the same grade aws.ts / grpc.ts emit at.
|
|
10004
10608
|
confidenceKind: "verified-call-site",
|
|
10005
10609
|
evidence: {
|
|
10006
|
-
file:
|
|
10610
|
+
file: import_node_path41.default.relative(serviceDir, file.path),
|
|
10007
10611
|
line,
|
|
10008
10612
|
snippet: snippet(file.content, line)
|
|
10009
10613
|
}
|
|
@@ -10024,13 +10628,13 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
10024
10628
|
seen.add(key);
|
|
10025
10629
|
const line = lineOf(file.content, am[0]);
|
|
10026
10630
|
out.push({
|
|
10027
|
-
infraId: (0,
|
|
10631
|
+
infraId: (0, import_types30.infraId)(kind, resource),
|
|
10028
10632
|
name: resource,
|
|
10029
10633
|
kind,
|
|
10030
10634
|
edgeType: "CALLS",
|
|
10031
10635
|
confidenceKind: "verified-call-site",
|
|
10032
10636
|
evidence: {
|
|
10033
|
-
file:
|
|
10637
|
+
file: import_node_path41.default.relative(serviceDir, file.path),
|
|
10034
10638
|
line,
|
|
10035
10639
|
snippet: snippet(file.content, line)
|
|
10036
10640
|
}
|
|
@@ -10042,10 +10646,10 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
10042
10646
|
|
|
10043
10647
|
// src/extract/calls/firestore.ts
|
|
10044
10648
|
init_cjs_shims();
|
|
10045
|
-
var
|
|
10649
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
10046
10650
|
var import_tree_sitter8 = __toESM(require("tree-sitter"), 1);
|
|
10047
10651
|
var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"), 1);
|
|
10048
|
-
var
|
|
10652
|
+
var import_types31 = require("@neat.is/types");
|
|
10049
10653
|
var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
|
|
10050
10654
|
var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
|
|
10051
10655
|
function parserForExt2(ext) {
|
|
@@ -10213,7 +10817,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
10213
10817
|
const hasAdmin = FIRESTORE_ADMIN_IMPORT_RE.test(file.content);
|
|
10214
10818
|
if (!hasClient && !hasAdmin) return [];
|
|
10215
10819
|
const fileSdk = hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
|
|
10216
|
-
const tree = parseSource3(parserForExt2(
|
|
10820
|
+
const tree = parseSource3(parserForExt2(import_node_path42.default.extname(file.path)), file.content);
|
|
10217
10821
|
const clientVars = firestoreClientVars(tree.rootNode);
|
|
10218
10822
|
const collLine = /* @__PURE__ */ new Map();
|
|
10219
10823
|
const writes = /* @__PURE__ */ new Map();
|
|
@@ -10306,7 +10910,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
10306
10910
|
}
|
|
10307
10911
|
}
|
|
10308
10912
|
out.push({
|
|
10309
|
-
infraId: (0,
|
|
10913
|
+
infraId: (0, import_types31.infraId)("firestore-collection", collPath),
|
|
10310
10914
|
name: collPath,
|
|
10311
10915
|
kind: "firestore-collection",
|
|
10312
10916
|
edgeType: "CALLS",
|
|
@@ -10317,7 +10921,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
10317
10921
|
...columnSet.size > 0 ? { columns: [...columnSet] } : {},
|
|
10318
10922
|
...sdkWrites ? { sdkWrites } : {},
|
|
10319
10923
|
evidence: {
|
|
10320
|
-
file:
|
|
10924
|
+
file: import_node_path42.default.relative(serviceDir, file.path),
|
|
10321
10925
|
line,
|
|
10322
10926
|
snippet: snippet(file.content, line)
|
|
10323
10927
|
}
|
|
@@ -10328,8 +10932,8 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
10328
10932
|
|
|
10329
10933
|
// src/extract/calls/mongoose.ts
|
|
10330
10934
|
init_cjs_shims();
|
|
10331
|
-
var
|
|
10332
|
-
var
|
|
10935
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
10936
|
+
var import_types32 = require("@neat.is/types");
|
|
10333
10937
|
var MONGOOSE_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongoose['"`]/;
|
|
10334
10938
|
var MONGODB_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongodb['"`]/;
|
|
10335
10939
|
var PLURALIZE_DISABLED_RE = /\bpluralize\s*\(\s*(?:null|false)\s*\)/;
|
|
@@ -10474,12 +11078,12 @@ function collectModelDefs(content, pluralizeOn) {
|
|
|
10474
11078
|
function endpoint(r, file, serviceDir, matchText) {
|
|
10475
11079
|
const line = lineOf(file.content, matchText);
|
|
10476
11080
|
return {
|
|
10477
|
-
infraId: (0,
|
|
11081
|
+
infraId: (0, import_types32.infraId)(r.kind, r.name),
|
|
10478
11082
|
name: r.name,
|
|
10479
11083
|
kind: r.kind,
|
|
10480
11084
|
edgeType: "CALLS",
|
|
10481
11085
|
confidenceKind: "verified-call-site",
|
|
10482
|
-
evidence: { file:
|
|
11086
|
+
evidence: { file: import_node_path43.default.relative(serviceDir, file.path), line, snippet: snippet(file.content, line) }
|
|
10483
11087
|
};
|
|
10484
11088
|
}
|
|
10485
11089
|
function mongooseEndpointsFromFile(file, serviceDir) {
|
|
@@ -10569,7 +11173,7 @@ async function mongooseCrossFileEndpoints(files, serviceDir) {
|
|
|
10569
11173
|
const registry = /* @__PURE__ */ new Map();
|
|
10570
11174
|
for (const f of mongooseFiles) {
|
|
10571
11175
|
const fx = fileExportsOf(f.content, pluralizeOn);
|
|
10572
|
-
if (fx) registry.set(toPosix(
|
|
11176
|
+
if (fx) registry.set(toPosix(import_node_path43.default.relative(serviceDir, f.path)), fx);
|
|
10573
11177
|
}
|
|
10574
11178
|
if (registry.size === 0) return [];
|
|
10575
11179
|
const out = [];
|
|
@@ -10580,7 +11184,7 @@ async function mongooseCrossFileEndpoints(files, serviceDir) {
|
|
|
10580
11184
|
const directColl = /* @__PURE__ */ new Map();
|
|
10581
11185
|
const nsExports = /* @__PURE__ */ new Map();
|
|
10582
11186
|
for (const b of bindings) {
|
|
10583
|
-
const resolvedRel = await resolveJsImport(b.specifier,
|
|
11187
|
+
const resolvedRel = await resolveJsImport(b.specifier, import_node_path43.default.dirname(f.path), serviceDir, null);
|
|
10584
11188
|
if (!resolvedRel) continue;
|
|
10585
11189
|
const fx = registry.get(resolvedRel);
|
|
10586
11190
|
if (!fx) continue;
|
|
@@ -10624,15 +11228,15 @@ async function mongooseCrossFileEndpoints(files, serviceDir) {
|
|
|
10624
11228
|
|
|
10625
11229
|
// src/extract/calls/sqlalchemy.ts
|
|
10626
11230
|
init_cjs_shims();
|
|
10627
|
-
var
|
|
11231
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
10628
11232
|
var import_tree_sitter9 = __toESM(require("tree-sitter"), 1);
|
|
10629
|
-
var
|
|
10630
|
-
var
|
|
11233
|
+
var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
11234
|
+
var import_types33 = require("@neat.is/types");
|
|
10631
11235
|
var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
|
|
10632
11236
|
var PARSE_CHUNK6 = 16384;
|
|
10633
11237
|
function makePyParser3() {
|
|
10634
11238
|
const p = new import_tree_sitter9.default();
|
|
10635
|
-
p.setLanguage(
|
|
11239
|
+
p.setLanguage(import_tree_sitter_python5.default);
|
|
10636
11240
|
return p;
|
|
10637
11241
|
}
|
|
10638
11242
|
function parseSource6(parser, source) {
|
|
@@ -10763,7 +11367,7 @@ function sqlalchemyForeignKeys(file, serviceDir) {
|
|
|
10763
11367
|
childTable,
|
|
10764
11368
|
parentTable,
|
|
10765
11369
|
evidence: {
|
|
10766
|
-
file:
|
|
11370
|
+
file: import_node_path44.default.relative(serviceDir, file.path),
|
|
10767
11371
|
line,
|
|
10768
11372
|
snippet: snippet(file.content, line)
|
|
10769
11373
|
}
|
|
@@ -10781,14 +11385,14 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
10781
11385
|
if (seen.has(name)) return;
|
|
10782
11386
|
seen.add(name);
|
|
10783
11387
|
out.push({
|
|
10784
|
-
infraId: (0,
|
|
11388
|
+
infraId: (0, import_types33.infraId)("sql-table", name),
|
|
10785
11389
|
name,
|
|
10786
11390
|
kind: "sql-table",
|
|
10787
11391
|
edgeType: "CALLS",
|
|
10788
11392
|
confidenceKind: "verified-call-site",
|
|
10789
11393
|
...columns && columns.length > 0 ? { columns } : {},
|
|
10790
11394
|
evidence: {
|
|
10791
|
-
file:
|
|
11395
|
+
file: import_node_path44.default.relative(serviceDir, file.path),
|
|
10792
11396
|
line,
|
|
10793
11397
|
snippet: snippet(file.content, line)
|
|
10794
11398
|
}
|
|
@@ -10889,13 +11493,13 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
10889
11493
|
if (seen.has(key)) continue;
|
|
10890
11494
|
seen.add(key);
|
|
10891
11495
|
out.push({
|
|
10892
|
-
infraId: (0,
|
|
11496
|
+
infraId: (0, import_types33.infraId)("sql-table", t),
|
|
10893
11497
|
name: t,
|
|
10894
11498
|
kind: "sql-table",
|
|
10895
11499
|
edgeType: "CALLS",
|
|
10896
11500
|
confidenceKind: "verified-call-site",
|
|
10897
11501
|
evidence: {
|
|
10898
|
-
file:
|
|
11502
|
+
file: import_node_path44.default.relative(serviceDir, file.path),
|
|
10899
11503
|
line,
|
|
10900
11504
|
snippet: snippet(file.content, line)
|
|
10901
11505
|
}
|
|
@@ -10907,15 +11511,15 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
10907
11511
|
|
|
10908
11512
|
// src/extract/calls/django-orm.ts
|
|
10909
11513
|
init_cjs_shims();
|
|
10910
|
-
var
|
|
11514
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
10911
11515
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
10912
|
-
var
|
|
10913
|
-
var
|
|
11516
|
+
var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
|
|
11517
|
+
var import_types34 = require("@neat.is/types");
|
|
10914
11518
|
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
10915
11519
|
var PARSE_CHUNK7 = 16384;
|
|
10916
11520
|
function makePyParser4() {
|
|
10917
11521
|
const p = new import_tree_sitter10.default();
|
|
10918
|
-
p.setLanguage(
|
|
11522
|
+
p.setLanguage(import_tree_sitter_python6.default);
|
|
10919
11523
|
return p;
|
|
10920
11524
|
}
|
|
10921
11525
|
function parseSource7(parser, source) {
|
|
@@ -10977,7 +11581,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
10977
11581
|
const tree = parseSource7(makePyParser4(), file.content);
|
|
10978
11582
|
const out = [];
|
|
10979
11583
|
const seen = /* @__PURE__ */ new Set();
|
|
10980
|
-
const defaultAppLabel =
|
|
11584
|
+
const defaultAppLabel = import_node_path45.default.basename(import_node_path45.default.dirname(file.path));
|
|
10981
11585
|
walk4(tree.rootNode, (node) => {
|
|
10982
11586
|
if (node.type !== "class_definition") return;
|
|
10983
11587
|
if (!extendsDjangoModel(node)) return;
|
|
@@ -10990,12 +11594,12 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
10990
11594
|
seen.add(table);
|
|
10991
11595
|
const line = node.startPosition.row + 1;
|
|
10992
11596
|
out.push({
|
|
10993
|
-
infraId: (0,
|
|
11597
|
+
infraId: (0, import_types34.infraId)("sql-table", table),
|
|
10994
11598
|
name: table,
|
|
10995
11599
|
kind: "sql-table",
|
|
10996
11600
|
edgeType: "CALLS",
|
|
10997
11601
|
confidenceKind: "verified-call-site",
|
|
10998
|
-
evidence: { file:
|
|
11602
|
+
evidence: { file: import_node_path45.default.relative(serviceDir, file.path), line, snippet: snippet(file.content, line) }
|
|
10999
11603
|
});
|
|
11000
11604
|
});
|
|
11001
11605
|
return out;
|
|
@@ -11003,10 +11607,10 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
11003
11607
|
|
|
11004
11608
|
// src/extract/calls/drizzle.ts
|
|
11005
11609
|
init_cjs_shims();
|
|
11006
|
-
var
|
|
11610
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
11007
11611
|
var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
|
|
11008
11612
|
var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11009
|
-
var
|
|
11613
|
+
var import_types35 = require("@neat.is/types");
|
|
11010
11614
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
11011
11615
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
11012
11616
|
function parserForExt3(ext) {
|
|
@@ -11081,7 +11685,7 @@ function columnsFromObject(obj) {
|
|
|
11081
11685
|
}
|
|
11082
11686
|
function drizzleEndpointsFromFile(file, serviceDir) {
|
|
11083
11687
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
11084
|
-
const tree = parseSource3(parserForExt3(
|
|
11688
|
+
const tree = parseSource3(parserForExt3(import_node_path46.default.extname(file.path)), file.content);
|
|
11085
11689
|
const out = [];
|
|
11086
11690
|
const seen = /* @__PURE__ */ new Set();
|
|
11087
11691
|
const walk9 = (node) => {
|
|
@@ -11097,14 +11701,14 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
11097
11701
|
const columns = columnsFromObject(obj);
|
|
11098
11702
|
const line = node.startPosition.row + 1;
|
|
11099
11703
|
out.push({
|
|
11100
|
-
infraId: (0,
|
|
11704
|
+
infraId: (0, import_types35.infraId)("sql-table", tableName),
|
|
11101
11705
|
name: tableName,
|
|
11102
11706
|
kind: "sql-table",
|
|
11103
11707
|
edgeType: "CALLS",
|
|
11104
11708
|
confidenceKind: "structural",
|
|
11105
11709
|
columns,
|
|
11106
11710
|
evidence: {
|
|
11107
|
-
file:
|
|
11711
|
+
file: import_node_path46.default.relative(serviceDir, file.path),
|
|
11108
11712
|
line,
|
|
11109
11713
|
snippet: snippet(file.content, line)
|
|
11110
11714
|
}
|
|
@@ -11170,7 +11774,7 @@ function referencesTargetVar(call) {
|
|
|
11170
11774
|
}
|
|
11171
11775
|
function drizzleForeignKeys(file, serviceDir) {
|
|
11172
11776
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
11173
|
-
const tree = parseSource3(parserForExt3(
|
|
11777
|
+
const tree = parseSource3(parserForExt3(import_node_path46.default.extname(file.path)), file.content);
|
|
11174
11778
|
const { tables, varToTable } = collectDrizzleTables(tree.rootNode);
|
|
11175
11779
|
const out = [];
|
|
11176
11780
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -11189,7 +11793,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
11189
11793
|
childTable: table.tableName,
|
|
11190
11794
|
parentTable,
|
|
11191
11795
|
evidence: {
|
|
11192
|
-
file:
|
|
11796
|
+
file: import_node_path46.default.relative(serviceDir, file.path),
|
|
11193
11797
|
line,
|
|
11194
11798
|
snippet: snippet(file.content, line)
|
|
11195
11799
|
}
|
|
@@ -11206,8 +11810,8 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
11206
11810
|
|
|
11207
11811
|
// src/extract/calls/prisma.ts
|
|
11208
11812
|
init_cjs_shims();
|
|
11209
|
-
var
|
|
11210
|
-
var
|
|
11813
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
11814
|
+
var import_types36 = require("@neat.is/types");
|
|
11211
11815
|
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
11212
11816
|
"Int",
|
|
11213
11817
|
"String",
|
|
@@ -11255,14 +11859,14 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
11255
11859
|
if (seenTable.has(b.tableName)) return;
|
|
11256
11860
|
seenTable.add(b.tableName);
|
|
11257
11861
|
out.push({
|
|
11258
|
-
infraId: (0,
|
|
11862
|
+
infraId: (0, import_types36.infraId)("sql-table", b.tableName),
|
|
11259
11863
|
name: b.tableName,
|
|
11260
11864
|
kind: "sql-table",
|
|
11261
11865
|
edgeType: "CALLS",
|
|
11262
11866
|
confidenceKind: "structural",
|
|
11263
11867
|
columns: b.columns,
|
|
11264
11868
|
evidence: {
|
|
11265
|
-
file:
|
|
11869
|
+
file: import_node_path47.default.relative(serviceDir, file.path),
|
|
11266
11870
|
line: b.startLine,
|
|
11267
11871
|
snippet: snippet(content, b.startLine)
|
|
11268
11872
|
}
|
|
@@ -11323,7 +11927,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
11323
11927
|
}
|
|
11324
11928
|
async function prismaColumnEndpoints(serviceDir) {
|
|
11325
11929
|
const schemaPath = await findFirst(serviceDir, [
|
|
11326
|
-
|
|
11930
|
+
import_node_path47.default.join("prisma", "schema.prisma"),
|
|
11327
11931
|
"schema.prisma"
|
|
11328
11932
|
]);
|
|
11329
11933
|
if (!schemaPath) return [];
|
|
@@ -11398,7 +12002,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
|
|
|
11398
12002
|
childTable: current.table,
|
|
11399
12003
|
parentTable,
|
|
11400
12004
|
evidence: {
|
|
11401
|
-
file:
|
|
12005
|
+
file: import_node_path47.default.relative(serviceDir, file.path),
|
|
11402
12006
|
line: lineNo,
|
|
11403
12007
|
snippet: snippet(content, lineNo)
|
|
11404
12008
|
}
|
|
@@ -11413,7 +12017,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
|
|
|
11413
12017
|
}
|
|
11414
12018
|
async function prismaForeignKeys(serviceDir) {
|
|
11415
12019
|
const schemaPath = await findFirst(serviceDir, [
|
|
11416
|
-
|
|
12020
|
+
import_node_path47.default.join("prisma", "schema.prisma"),
|
|
11417
12021
|
"schema.prisma"
|
|
11418
12022
|
]);
|
|
11419
12023
|
if (!schemaPath) return [];
|
|
@@ -11424,15 +12028,15 @@ async function prismaForeignKeys(serviceDir) {
|
|
|
11424
12028
|
|
|
11425
12029
|
// src/extract/calls/activerecord.ts
|
|
11426
12030
|
init_cjs_shims();
|
|
11427
|
-
var
|
|
12031
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
11428
12032
|
var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
|
|
11429
|
-
var
|
|
11430
|
-
var
|
|
12033
|
+
var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
|
|
12034
|
+
var import_types37 = require("@neat.is/types");
|
|
11431
12035
|
var AR_SCHEMA_RE = /ActiveRecord::Schema/;
|
|
11432
12036
|
var PARSE_CHUNK8 = 16384;
|
|
11433
12037
|
function makeRubyParser2() {
|
|
11434
12038
|
const p = new import_tree_sitter12.default();
|
|
11435
|
-
p.setLanguage(
|
|
12039
|
+
p.setLanguage(import_tree_sitter_ruby3.default);
|
|
11436
12040
|
return p;
|
|
11437
12041
|
}
|
|
11438
12042
|
function parseSource8(parser, source) {
|
|
@@ -11625,14 +12229,14 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
|
11625
12229
|
if (!table || seen.has(table.name)) return;
|
|
11626
12230
|
seen.add(table.name);
|
|
11627
12231
|
out.push({
|
|
11628
|
-
infraId: (0,
|
|
12232
|
+
infraId: (0, import_types37.infraId)("sql-table", table.name),
|
|
11629
12233
|
name: table.name,
|
|
11630
12234
|
kind: "sql-table",
|
|
11631
12235
|
edgeType: "CALLS",
|
|
11632
12236
|
confidenceKind: "structural",
|
|
11633
12237
|
...table.columns.length > 0 ? { columns: table.columns } : {},
|
|
11634
12238
|
evidence: {
|
|
11635
|
-
file:
|
|
12239
|
+
file: import_node_path48.default.relative(serviceDir, file.path),
|
|
11636
12240
|
line: table.line,
|
|
11637
12241
|
snippet: snippet(file.content, table.line)
|
|
11638
12242
|
}
|
|
@@ -11654,7 +12258,7 @@ function railsSchemaForeignKeys(file, serviceDir) {
|
|
|
11654
12258
|
childTable,
|
|
11655
12259
|
parentTable,
|
|
11656
12260
|
evidence: {
|
|
11657
|
-
file:
|
|
12261
|
+
file: import_node_path48.default.relative(serviceDir, file.path),
|
|
11658
12262
|
line,
|
|
11659
12263
|
snippet: snippet(file.content, line)
|
|
11660
12264
|
}
|
|
@@ -11731,13 +12335,13 @@ function railsModelEndpointsFromFile(file, serviceDir) {
|
|
|
11731
12335
|
seen.add(table);
|
|
11732
12336
|
const line = node.startPosition.row + 1;
|
|
11733
12337
|
out.push({
|
|
11734
|
-
infraId: (0,
|
|
12338
|
+
infraId: (0, import_types37.infraId)("sql-table", table),
|
|
11735
12339
|
name: table,
|
|
11736
12340
|
kind: "sql-table",
|
|
11737
12341
|
edgeType: "CALLS",
|
|
11738
12342
|
confidenceKind: "verified-call-site",
|
|
11739
12343
|
evidence: {
|
|
11740
|
-
file:
|
|
12344
|
+
file: import_node_path48.default.relative(serviceDir, file.path),
|
|
11741
12345
|
line,
|
|
11742
12346
|
snippet: snippet(file.content, line)
|
|
11743
12347
|
}
|
|
@@ -11774,7 +12378,7 @@ function railsModelForeignKeys(file, serviceDir) {
|
|
|
11774
12378
|
childTable,
|
|
11775
12379
|
parentTable,
|
|
11776
12380
|
evidence: {
|
|
11777
|
-
file:
|
|
12381
|
+
file: import_node_path48.default.relative(serviceDir, file.path),
|
|
11778
12382
|
line,
|
|
11779
12383
|
snippet: snippet(file.content, line)
|
|
11780
12384
|
}
|
|
@@ -11786,15 +12390,15 @@ function railsModelForeignKeys(file, serviceDir) {
|
|
|
11786
12390
|
|
|
11787
12391
|
// src/extract/calls/eloquent.ts
|
|
11788
12392
|
init_cjs_shims();
|
|
11789
|
-
var
|
|
12393
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
11790
12394
|
var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
|
|
11791
|
-
var
|
|
11792
|
-
var
|
|
12395
|
+
var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
|
|
12396
|
+
var import_types38 = require("@neat.is/types");
|
|
11793
12397
|
var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
|
|
11794
12398
|
var PARSE_CHUNK9 = 16384;
|
|
11795
12399
|
function makePhpParser2() {
|
|
11796
12400
|
const p = new import_tree_sitter13.default();
|
|
11797
|
-
p.setLanguage(
|
|
12401
|
+
p.setLanguage(import_tree_sitter_php3.default.php_only);
|
|
11798
12402
|
return p;
|
|
11799
12403
|
}
|
|
11800
12404
|
function parseSource9(parser, source) {
|
|
@@ -12036,14 +12640,14 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
12036
12640
|
}
|
|
12037
12641
|
}
|
|
12038
12642
|
out.push({
|
|
12039
|
-
infraId: (0,
|
|
12643
|
+
infraId: (0, import_types38.infraId)("sql-table", bp.table),
|
|
12040
12644
|
name: bp.table,
|
|
12041
12645
|
kind: "sql-table",
|
|
12042
12646
|
edgeType: "CALLS",
|
|
12043
12647
|
confidenceKind: "structural",
|
|
12044
12648
|
...columns.length > 0 ? { columns } : {},
|
|
12045
12649
|
evidence: {
|
|
12046
|
-
file:
|
|
12650
|
+
file: import_node_path49.default.relative(serviceDir, file.path),
|
|
12047
12651
|
line: bp.line,
|
|
12048
12652
|
snippet: snippet(file.content, bp.line)
|
|
12049
12653
|
}
|
|
@@ -12065,7 +12669,7 @@ function laravelMigrationForeignKeys(file, serviceDir) {
|
|
|
12065
12669
|
childTable,
|
|
12066
12670
|
parentTable,
|
|
12067
12671
|
evidence: {
|
|
12068
|
-
file:
|
|
12672
|
+
file: import_node_path49.default.relative(serviceDir, file.path),
|
|
12069
12673
|
line,
|
|
12070
12674
|
snippet: snippet(file.content, line)
|
|
12071
12675
|
}
|
|
@@ -12179,13 +12783,13 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
|
12179
12783
|
seen.add(table);
|
|
12180
12784
|
const line = node.startPosition.row + 1;
|
|
12181
12785
|
out.push({
|
|
12182
|
-
infraId: (0,
|
|
12786
|
+
infraId: (0, import_types38.infraId)("sql-table", table),
|
|
12183
12787
|
name: table,
|
|
12184
12788
|
kind: "sql-table",
|
|
12185
12789
|
edgeType: "CALLS",
|
|
12186
12790
|
confidenceKind: "verified-call-site",
|
|
12187
12791
|
evidence: {
|
|
12188
|
-
file:
|
|
12792
|
+
file: import_node_path49.default.relative(serviceDir, file.path),
|
|
12189
12793
|
line,
|
|
12190
12794
|
snippet: snippet(file.content, line)
|
|
12191
12795
|
}
|
|
@@ -12221,7 +12825,7 @@ function laravelModelForeignKeys(file, serviceDir) {
|
|
|
12221
12825
|
childTable,
|
|
12222
12826
|
parentTable,
|
|
12223
12827
|
evidence: {
|
|
12224
|
-
file:
|
|
12828
|
+
file: import_node_path49.default.relative(serviceDir, file.path),
|
|
12225
12829
|
line,
|
|
12226
12830
|
snippet: snippet(file.content, line)
|
|
12227
12831
|
}
|
|
@@ -12233,10 +12837,10 @@ function laravelModelForeignKeys(file, serviceDir) {
|
|
|
12233
12837
|
|
|
12234
12838
|
// src/extract/calls/go.ts
|
|
12235
12839
|
init_cjs_shims();
|
|
12236
|
-
var
|
|
12840
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
12237
12841
|
var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
|
|
12238
|
-
var
|
|
12239
|
-
var
|
|
12842
|
+
var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
|
|
12843
|
+
var import_types39 = require("@neat.is/types");
|
|
12240
12844
|
init_otel();
|
|
12241
12845
|
var PARSE_CHUNK10 = 16384;
|
|
12242
12846
|
var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
|
|
@@ -12265,7 +12869,7 @@ var DATABASE_SQL_IMPORT = "database/sql";
|
|
|
12265
12869
|
var SQLX_IMPORT = "github.com/jmoiron/sqlx";
|
|
12266
12870
|
function makeGoParser3() {
|
|
12267
12871
|
const p = new import_tree_sitter14.default();
|
|
12268
|
-
p.setLanguage(
|
|
12872
|
+
p.setLanguage(import_tree_sitter_go4.default);
|
|
12269
12873
|
return p;
|
|
12270
12874
|
}
|
|
12271
12875
|
function parseSource10(parser, source) {
|
|
@@ -12308,7 +12912,7 @@ function firstStringLiteralArg(argsNode) {
|
|
|
12308
12912
|
return null;
|
|
12309
12913
|
}
|
|
12310
12914
|
function goSqlEndpointsFromFile(file, serviceDir) {
|
|
12311
|
-
if (
|
|
12915
|
+
if (import_node_path52.default.extname(file.path) !== ".go") return [];
|
|
12312
12916
|
if (!file.content.includes(DATABASE_SQL_IMPORT) && !file.content.includes(SQLX_IMPORT)) return [];
|
|
12313
12917
|
const tree = parseSource10(makeGoParser3(), file.content);
|
|
12314
12918
|
const importsDatabaseSql = goImportsAny(tree.rootNode, /* @__PURE__ */ new Set([DATABASE_SQL_IMPORT]));
|
|
@@ -12330,14 +12934,14 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
12330
12934
|
const columns = columnsFromSqlStatement(sql);
|
|
12331
12935
|
const line = node.startPosition.row + 1;
|
|
12332
12936
|
out.push({
|
|
12333
|
-
infraId: (0,
|
|
12937
|
+
infraId: (0, import_types39.infraId)("sql-table", table),
|
|
12334
12938
|
name: table,
|
|
12335
12939
|
kind: "sql-table",
|
|
12336
12940
|
edgeType: "CALLS",
|
|
12337
12941
|
confidenceKind: "verified-call-site",
|
|
12338
12942
|
...columns.length > 0 ? { columns } : {},
|
|
12339
12943
|
evidence: {
|
|
12340
|
-
file: toPosix(
|
|
12944
|
+
file: toPosix(import_node_path52.default.relative(serviceDir, file.path)),
|
|
12341
12945
|
line,
|
|
12342
12946
|
snippet: snippet(file.content, line)
|
|
12343
12947
|
}
|
|
@@ -12348,15 +12952,15 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
12348
12952
|
|
|
12349
12953
|
// src/extract/calls/gorm.ts
|
|
12350
12954
|
init_cjs_shims();
|
|
12351
|
-
var
|
|
12955
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
12352
12956
|
var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
|
|
12353
|
-
var
|
|
12354
|
-
var
|
|
12957
|
+
var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
|
|
12958
|
+
var import_types40 = require("@neat.is/types");
|
|
12355
12959
|
var GORM_IMPORT_RE = /gorm\.io\/gorm/;
|
|
12356
12960
|
var PARSE_CHUNK11 = 16384;
|
|
12357
12961
|
function makeGoParser4() {
|
|
12358
12962
|
const p = new import_tree_sitter15.default();
|
|
12359
|
-
p.setLanguage(
|
|
12963
|
+
p.setLanguage(import_tree_sitter_go5.default);
|
|
12360
12964
|
return p;
|
|
12361
12965
|
}
|
|
12362
12966
|
function parseSource11(parser, source) {
|
|
@@ -12781,7 +13385,7 @@ function collectColumns(struct, structs, seen, prefix, out, emitted) {
|
|
|
12781
13385
|
seen.delete(struct.name);
|
|
12782
13386
|
}
|
|
12783
13387
|
function gormEndpointsFromFile(file, serviceDir) {
|
|
12784
|
-
if (
|
|
13388
|
+
if (import_node_path53.default.extname(file.path) !== ".go") return [];
|
|
12785
13389
|
if (!GORM_IMPORT_RE.test(file.content)) return [];
|
|
12786
13390
|
const tree = parseSource11(makeGoParser4(), file.content);
|
|
12787
13391
|
const { structs, models, tableFor } = analyze(tree);
|
|
@@ -12796,14 +13400,14 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
12796
13400
|
const columns = [];
|
|
12797
13401
|
collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
|
|
12798
13402
|
out.push({
|
|
12799
|
-
infraId: (0,
|
|
13403
|
+
infraId: (0, import_types40.infraId)("sql-table", table),
|
|
12800
13404
|
name: table,
|
|
12801
13405
|
kind: "sql-table",
|
|
12802
13406
|
edgeType: "CALLS",
|
|
12803
13407
|
confidenceKind: "structural",
|
|
12804
13408
|
...columns.length > 0 ? { columns } : {},
|
|
12805
13409
|
evidence: {
|
|
12806
|
-
file: toPosix(
|
|
13410
|
+
file: toPosix(import_node_path53.default.relative(serviceDir, file.path)),
|
|
12807
13411
|
line: struct.line,
|
|
12808
13412
|
snippet: snippet(file.content, struct.line)
|
|
12809
13413
|
}
|
|
@@ -12812,7 +13416,7 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
12812
13416
|
return out;
|
|
12813
13417
|
}
|
|
12814
13418
|
function gormForeignKeys(file, serviceDir) {
|
|
12815
|
-
if (
|
|
13419
|
+
if (import_node_path53.default.extname(file.path) !== ".go") return [];
|
|
12816
13420
|
if (!GORM_IMPORT_RE.test(file.content)) return [];
|
|
12817
13421
|
const tree = parseSource11(makeGoParser4(), file.content);
|
|
12818
13422
|
const { structs, models, tableFor } = analyze(tree);
|
|
@@ -12827,7 +13431,7 @@ function gormForeignKeys(file, serviceDir) {
|
|
|
12827
13431
|
childTable,
|
|
12828
13432
|
parentTable,
|
|
12829
13433
|
evidence: {
|
|
12830
|
-
file: toPosix(
|
|
13434
|
+
file: toPosix(import_node_path53.default.relative(serviceDir, file.path)),
|
|
12831
13435
|
line,
|
|
12832
13436
|
snippet: snippet(file.content, line)
|
|
12833
13437
|
}
|
|
@@ -12866,11 +13470,11 @@ function gormForeignKeys(file, serviceDir) {
|
|
|
12866
13470
|
function edgeTypeFromEndpoint(ep) {
|
|
12867
13471
|
switch (ep.edgeType) {
|
|
12868
13472
|
case "PUBLISHES_TO":
|
|
12869
|
-
return
|
|
13473
|
+
return import_types41.EdgeType.PUBLISHES_TO;
|
|
12870
13474
|
case "CONSUMES_FROM":
|
|
12871
|
-
return
|
|
13475
|
+
return import_types41.EdgeType.CONSUMES_FROM;
|
|
12872
13476
|
default:
|
|
12873
|
-
return
|
|
13477
|
+
return import_types41.EdgeType.CALLS;
|
|
12874
13478
|
}
|
|
12875
13479
|
}
|
|
12876
13480
|
function isAwsKind(kind) {
|
|
@@ -12930,7 +13534,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
12930
13534
|
if (!graph.hasNode(ep.infraId)) {
|
|
12931
13535
|
const node = {
|
|
12932
13536
|
id: ep.infraId,
|
|
12933
|
-
type:
|
|
13537
|
+
type: import_types41.NodeType.InfraNode,
|
|
12934
13538
|
name: ep.name,
|
|
12935
13539
|
// #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
|
|
12936
13540
|
// aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
|
|
@@ -12943,21 +13547,21 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
12943
13547
|
}
|
|
12944
13548
|
if (ep.columns && ep.columns.length > 0) {
|
|
12945
13549
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
12946
|
-
if (node.type ===
|
|
13550
|
+
if (node.type === import_types41.NodeType.InfraNode) {
|
|
12947
13551
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
12948
13552
|
...node,
|
|
12949
13553
|
columns: foldColumns(
|
|
12950
13554
|
node.columns,
|
|
12951
13555
|
ep.columns,
|
|
12952
|
-
|
|
12953
|
-
(0,
|
|
13556
|
+
import_types41.Provenance.EXTRACTED,
|
|
13557
|
+
(0, import_types41.confidenceForExtracted)(ep.confidenceKind)
|
|
12954
13558
|
)
|
|
12955
13559
|
});
|
|
12956
13560
|
}
|
|
12957
13561
|
}
|
|
12958
13562
|
if (ep.sdkWrites && Object.keys(ep.sdkWrites).length > 0) {
|
|
12959
13563
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
12960
|
-
if (node.type ===
|
|
13564
|
+
if (node.type === import_types41.NodeType.InfraNode) {
|
|
12961
13565
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
12962
13566
|
...node,
|
|
12963
13567
|
columns: foldSdkWrites(node.columns, ep.sdkWrites)
|
|
@@ -12965,7 +13569,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
12965
13569
|
}
|
|
12966
13570
|
}
|
|
12967
13571
|
const edgeType = edgeTypeFromEndpoint(ep);
|
|
12968
|
-
const confidence = (0,
|
|
13572
|
+
const confidence = (0, import_types41.confidenceForExtracted)(ep.confidenceKind);
|
|
12969
13573
|
const relFile = toPosix(ep.evidence.file);
|
|
12970
13574
|
const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
12971
13575
|
graph,
|
|
@@ -12975,7 +13579,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
12975
13579
|
);
|
|
12976
13580
|
nodesAdded += n;
|
|
12977
13581
|
edgesAdded += e;
|
|
12978
|
-
if (!(0,
|
|
13582
|
+
if (!(0, import_types41.passesExtractedFloor)(confidence)) {
|
|
12979
13583
|
noteExtractedDropped({
|
|
12980
13584
|
source: fileNodeId,
|
|
12981
13585
|
target: ep.infraId,
|
|
@@ -12995,7 +13599,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
12995
13599
|
source: fileNodeId,
|
|
12996
13600
|
target: ep.infraId,
|
|
12997
13601
|
type: edgeType,
|
|
12998
|
-
provenance:
|
|
13602
|
+
provenance: import_types41.Provenance.EXTRACTED,
|
|
12999
13603
|
confidence,
|
|
13000
13604
|
evidence: ep.evidence
|
|
13001
13605
|
};
|
|
@@ -13018,7 +13622,7 @@ async function addCallEdges(graph, services) {
|
|
|
13018
13622
|
|
|
13019
13623
|
// src/extract/table-edges.ts
|
|
13020
13624
|
init_cjs_shims();
|
|
13021
|
-
var
|
|
13625
|
+
var import_types42 = require("@neat.is/types");
|
|
13022
13626
|
async function addTableEdges(graph, services) {
|
|
13023
13627
|
let nodesAdded = 0;
|
|
13024
13628
|
let edgesAdded = 0;
|
|
@@ -13046,20 +13650,20 @@ async function addTableEdges(graph, services) {
|
|
|
13046
13650
|
}
|
|
13047
13651
|
refs.push(...modelRefs);
|
|
13048
13652
|
for (const ref of refs) {
|
|
13049
|
-
const childId = (0,
|
|
13050
|
-
const parentId = (0,
|
|
13653
|
+
const childId = (0, import_types42.infraId)("sql-table", ref.childTable);
|
|
13654
|
+
const parentId = (0, import_types42.infraId)("sql-table", ref.parentTable);
|
|
13051
13655
|
if (childId === parentId) continue;
|
|
13052
13656
|
nodesAdded += ensureTableNode(graph, childId, ref.childTable);
|
|
13053
13657
|
nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
|
|
13054
|
-
const edgeId = (0,
|
|
13658
|
+
const edgeId = (0, import_types42.extractedEdgeId)(childId, parentId, import_types42.EdgeType.REFERENCES);
|
|
13055
13659
|
if (graph.hasEdge(edgeId)) continue;
|
|
13056
13660
|
const edge = {
|
|
13057
13661
|
id: edgeId,
|
|
13058
13662
|
source: childId,
|
|
13059
13663
|
target: parentId,
|
|
13060
|
-
type:
|
|
13061
|
-
provenance:
|
|
13062
|
-
confidence: (0,
|
|
13664
|
+
type: import_types42.EdgeType.REFERENCES,
|
|
13665
|
+
provenance: import_types42.Provenance.EXTRACTED,
|
|
13666
|
+
confidence: (0, import_types42.confidenceForExtracted)("structural"),
|
|
13063
13667
|
evidence: ref.evidence
|
|
13064
13668
|
};
|
|
13065
13669
|
graph.addEdgeWithKey(edgeId, childId, parentId, edge);
|
|
@@ -13072,7 +13676,7 @@ function ensureTableNode(graph, id, name) {
|
|
|
13072
13676
|
if (graph.hasNode(id)) return 0;
|
|
13073
13677
|
const node = {
|
|
13074
13678
|
id,
|
|
13075
|
-
type:
|
|
13679
|
+
type: import_types42.NodeType.InfraNode,
|
|
13076
13680
|
name,
|
|
13077
13681
|
provider: "self",
|
|
13078
13682
|
kind: "sql-table"
|
|
@@ -13086,16 +13690,16 @@ init_cjs_shims();
|
|
|
13086
13690
|
|
|
13087
13691
|
// src/extract/infra/docker-compose.ts
|
|
13088
13692
|
init_cjs_shims();
|
|
13089
|
-
var
|
|
13090
|
-
var
|
|
13693
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
13694
|
+
var import_types44 = require("@neat.is/types");
|
|
13091
13695
|
|
|
13092
13696
|
// src/extract/infra/shared.ts
|
|
13093
13697
|
init_cjs_shims();
|
|
13094
|
-
var
|
|
13698
|
+
var import_types43 = require("@neat.is/types");
|
|
13095
13699
|
function makeInfraNode(kind, name, provider = "self", extras) {
|
|
13096
13700
|
return {
|
|
13097
|
-
id: (0,
|
|
13098
|
-
type:
|
|
13701
|
+
id: (0, import_types43.infraId)(kind, name),
|
|
13702
|
+
type: import_types43.NodeType.InfraNode,
|
|
13099
13703
|
name,
|
|
13100
13704
|
provider,
|
|
13101
13705
|
kind,
|
|
@@ -13139,8 +13743,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
|
|
|
13139
13743
|
source: anchorId,
|
|
13140
13744
|
target: node.id,
|
|
13141
13745
|
type: edgeType,
|
|
13142
|
-
provenance:
|
|
13143
|
-
confidence: (0,
|
|
13746
|
+
provenance: import_types43.Provenance.EXTRACTED,
|
|
13747
|
+
confidence: (0, import_types43.confidenceForExtracted)("structural"),
|
|
13144
13748
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
13145
13749
|
};
|
|
13146
13750
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -13157,7 +13761,7 @@ function dependsOnList(value) {
|
|
|
13157
13761
|
}
|
|
13158
13762
|
function serviceNameToServiceNode(name, services) {
|
|
13159
13763
|
for (const s of services) {
|
|
13160
|
-
if (s.node.name === name ||
|
|
13764
|
+
if (s.node.name === name || import_node_path54.default.basename(s.dir) === name) return s.node.id;
|
|
13161
13765
|
}
|
|
13162
13766
|
return null;
|
|
13163
13767
|
}
|
|
@@ -13166,7 +13770,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
13166
13770
|
let edgesAdded = 0;
|
|
13167
13771
|
let composePath = null;
|
|
13168
13772
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
13169
|
-
const abs =
|
|
13773
|
+
const abs = import_node_path54.default.join(scanPath, name);
|
|
13170
13774
|
if (await exists2(abs)) {
|
|
13171
13775
|
composePath = abs;
|
|
13172
13776
|
break;
|
|
@@ -13179,13 +13783,13 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
13179
13783
|
} catch (err) {
|
|
13180
13784
|
recordExtractionError(
|
|
13181
13785
|
"infra docker-compose",
|
|
13182
|
-
|
|
13786
|
+
import_node_path54.default.relative(scanPath, composePath),
|
|
13183
13787
|
err
|
|
13184
13788
|
);
|
|
13185
13789
|
return { nodesAdded, edgesAdded };
|
|
13186
13790
|
}
|
|
13187
13791
|
if (!compose?.services) return { nodesAdded, edgesAdded };
|
|
13188
|
-
const evidenceFile =
|
|
13792
|
+
const evidenceFile = import_node_path54.default.relative(scanPath, composePath).split(import_node_path54.default.sep).join("/");
|
|
13189
13793
|
const composeNameToNodeId = /* @__PURE__ */ new Map();
|
|
13190
13794
|
for (const [composeName, svc] of Object.entries(compose.services)) {
|
|
13191
13795
|
const matchedServiceId = serviceNameToServiceNode(composeName, services);
|
|
@@ -13207,15 +13811,15 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
13207
13811
|
for (const dep of dependsOnList(svc.depends_on)) {
|
|
13208
13812
|
const targetId = composeNameToNodeId.get(dep);
|
|
13209
13813
|
if (!targetId) continue;
|
|
13210
|
-
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId,
|
|
13814
|
+
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types44.EdgeType.DEPENDS_ON);
|
|
13211
13815
|
if (graph.hasEdge(edgeId)) continue;
|
|
13212
13816
|
const edge = {
|
|
13213
13817
|
id: edgeId,
|
|
13214
13818
|
source: sourceId,
|
|
13215
13819
|
target: targetId,
|
|
13216
|
-
type:
|
|
13217
|
-
provenance:
|
|
13218
|
-
confidence: (0,
|
|
13820
|
+
type: import_types44.EdgeType.DEPENDS_ON,
|
|
13821
|
+
provenance: import_types44.Provenance.EXTRACTED,
|
|
13822
|
+
confidence: (0, import_types44.confidenceForExtracted)("structural"),
|
|
13219
13823
|
evidence: { file: evidenceFile }
|
|
13220
13824
|
};
|
|
13221
13825
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -13227,9 +13831,9 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
13227
13831
|
|
|
13228
13832
|
// src/extract/infra/dockerfile.ts
|
|
13229
13833
|
init_cjs_shims();
|
|
13230
|
-
var
|
|
13231
|
-
var
|
|
13232
|
-
var
|
|
13834
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
13835
|
+
var import_node_fs23 = require("fs");
|
|
13836
|
+
var import_types45 = require("@neat.is/types");
|
|
13233
13837
|
function readDockerfile(content) {
|
|
13234
13838
|
let image = null;
|
|
13235
13839
|
const ports = [];
|
|
@@ -13258,15 +13862,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
13258
13862
|
let nodesAdded = 0;
|
|
13259
13863
|
let edgesAdded = 0;
|
|
13260
13864
|
for (const service of services) {
|
|
13261
|
-
const dockerfilePath =
|
|
13865
|
+
const dockerfilePath = import_node_path55.default.join(service.dir, "Dockerfile");
|
|
13262
13866
|
if (!await exists2(dockerfilePath)) continue;
|
|
13263
13867
|
let content;
|
|
13264
13868
|
try {
|
|
13265
|
-
content = await
|
|
13869
|
+
content = await import_node_fs23.promises.readFile(dockerfilePath, "utf8");
|
|
13266
13870
|
} catch (err) {
|
|
13267
13871
|
recordExtractionError(
|
|
13268
13872
|
"infra dockerfile",
|
|
13269
|
-
|
|
13873
|
+
import_node_path55.default.relative(scanPath, dockerfilePath),
|
|
13270
13874
|
err
|
|
13271
13875
|
);
|
|
13272
13876
|
continue;
|
|
@@ -13278,8 +13882,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
13278
13882
|
graph.addNode(node.id, node);
|
|
13279
13883
|
nodesAdded++;
|
|
13280
13884
|
}
|
|
13281
|
-
const relDockerfile = toPosix(
|
|
13282
|
-
const evidenceFile = toPosix(
|
|
13885
|
+
const relDockerfile = toPosix(import_node_path55.default.relative(service.dir, dockerfilePath));
|
|
13886
|
+
const evidenceFile = toPosix(import_node_path55.default.relative(scanPath, dockerfilePath));
|
|
13283
13887
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
13284
13888
|
graph,
|
|
13285
13889
|
service.pkg.name,
|
|
@@ -13288,15 +13892,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
13288
13892
|
);
|
|
13289
13893
|
nodesAdded += fn;
|
|
13290
13894
|
edgesAdded += fe;
|
|
13291
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
13895
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types45.EdgeType.RUNS_ON);
|
|
13292
13896
|
if (!graph.hasEdge(edgeId)) {
|
|
13293
13897
|
const edge = {
|
|
13294
13898
|
id: edgeId,
|
|
13295
13899
|
source: fileNodeId,
|
|
13296
13900
|
target: node.id,
|
|
13297
|
-
type:
|
|
13298
|
-
provenance:
|
|
13299
|
-
confidence: (0,
|
|
13901
|
+
type: import_types45.EdgeType.RUNS_ON,
|
|
13902
|
+
provenance: import_types45.Provenance.EXTRACTED,
|
|
13903
|
+
confidence: (0, import_types45.confidenceForExtracted)("structural"),
|
|
13300
13904
|
evidence: {
|
|
13301
13905
|
file: evidenceFile,
|
|
13302
13906
|
...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
|
|
@@ -13311,15 +13915,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
13311
13915
|
graph.addNode(portNode.id, portNode);
|
|
13312
13916
|
nodesAdded++;
|
|
13313
13917
|
}
|
|
13314
|
-
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id,
|
|
13918
|
+
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types45.EdgeType.CONNECTS_TO);
|
|
13315
13919
|
if (graph.hasEdge(portEdgeId)) continue;
|
|
13316
13920
|
const portEdge = {
|
|
13317
13921
|
id: portEdgeId,
|
|
13318
13922
|
source: fileNodeId,
|
|
13319
13923
|
target: portNode.id,
|
|
13320
|
-
type:
|
|
13321
|
-
provenance:
|
|
13322
|
-
confidence: (0,
|
|
13924
|
+
type: import_types45.EdgeType.CONNECTS_TO,
|
|
13925
|
+
provenance: import_types45.Provenance.EXTRACTED,
|
|
13926
|
+
confidence: (0, import_types45.confidenceForExtracted)("structural"),
|
|
13323
13927
|
evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
|
|
13324
13928
|
};
|
|
13325
13929
|
graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
|
|
@@ -13331,23 +13935,23 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
13331
13935
|
|
|
13332
13936
|
// src/extract/infra/terraform.ts
|
|
13333
13937
|
init_cjs_shims();
|
|
13334
|
-
var
|
|
13335
|
-
var
|
|
13336
|
-
var
|
|
13938
|
+
var import_node_fs24 = require("fs");
|
|
13939
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
13940
|
+
var import_types46 = require("@neat.is/types");
|
|
13337
13941
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
13338
13942
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
13339
13943
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
13340
13944
|
if (depth > max) return [];
|
|
13341
13945
|
const out = [];
|
|
13342
|
-
const entries = await
|
|
13946
|
+
const entries = await import_node_fs24.promises.readdir(start, { withFileTypes: true }).catch(() => []);
|
|
13343
13947
|
for (const entry of entries) {
|
|
13344
13948
|
if (entry.isDirectory()) {
|
|
13345
13949
|
if (IGNORED_DIRS.has(entry.name) || entry.name === ".terraform") continue;
|
|
13346
|
-
const child =
|
|
13950
|
+
const child = import_node_path56.default.join(start, entry.name);
|
|
13347
13951
|
if (await isPythonVenvDir(child)) continue;
|
|
13348
13952
|
out.push(...await walkTfFiles(child, depth + 1, max));
|
|
13349
13953
|
} else if (entry.isFile() && entry.name.endsWith(".tf")) {
|
|
13350
|
-
out.push(
|
|
13954
|
+
out.push(import_node_path56.default.join(start, entry.name));
|
|
13351
13955
|
}
|
|
13352
13956
|
}
|
|
13353
13957
|
return out;
|
|
@@ -13378,8 +13982,8 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
13378
13982
|
let edgesAdded = 0;
|
|
13379
13983
|
const files = await walkTfFiles(scanPath);
|
|
13380
13984
|
for (const file of files) {
|
|
13381
|
-
const content = await
|
|
13382
|
-
const evidenceFile = toPosix(
|
|
13985
|
+
const content = await import_node_fs24.promises.readFile(file, "utf8");
|
|
13986
|
+
const evidenceFile = toPosix(import_node_path56.default.relative(scanPath, file));
|
|
13383
13987
|
const resources = [];
|
|
13384
13988
|
const byKey = /* @__PURE__ */ new Map();
|
|
13385
13989
|
RESOURCE_RE.lastIndex = 0;
|
|
@@ -13414,16 +14018,16 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
13414
14018
|
if (!target) continue;
|
|
13415
14019
|
if (seen.has(target.nodeId)) continue;
|
|
13416
14020
|
seen.add(target.nodeId);
|
|
13417
|
-
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId,
|
|
14021
|
+
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types46.EdgeType.DEPENDS_ON);
|
|
13418
14022
|
if (graph.hasEdge(edgeId)) continue;
|
|
13419
14023
|
const line = lineAt2(content, resource.bodyOffset + ref.index);
|
|
13420
14024
|
const edge = {
|
|
13421
14025
|
id: edgeId,
|
|
13422
14026
|
source: resource.nodeId,
|
|
13423
14027
|
target: target.nodeId,
|
|
13424
|
-
type:
|
|
13425
|
-
provenance:
|
|
13426
|
-
confidence: (0,
|
|
14028
|
+
type: import_types46.EdgeType.DEPENDS_ON,
|
|
14029
|
+
provenance: import_types46.Provenance.EXTRACTED,
|
|
14030
|
+
confidence: (0, import_types46.confidenceForExtracted)("structural"),
|
|
13427
14031
|
evidence: { file: evidenceFile, line, snippet: key }
|
|
13428
14032
|
};
|
|
13429
14033
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -13436,8 +14040,8 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
13436
14040
|
|
|
13437
14041
|
// src/extract/infra/k8s.ts
|
|
13438
14042
|
init_cjs_shims();
|
|
13439
|
-
var
|
|
13440
|
-
var
|
|
14043
|
+
var import_node_fs25 = require("fs");
|
|
14044
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
13441
14045
|
var import_yaml3 = require("yaml");
|
|
13442
14046
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
13443
14047
|
Service: "k8s-service",
|
|
@@ -13451,15 +14055,15 @@ var K8S_KIND_TO_INFRA_KIND = {
|
|
|
13451
14055
|
async function walkYamlFiles2(start, depth = 0, max = 5) {
|
|
13452
14056
|
if (depth > max) return [];
|
|
13453
14057
|
const out = [];
|
|
13454
|
-
const entries = await
|
|
14058
|
+
const entries = await import_node_fs25.promises.readdir(start, { withFileTypes: true }).catch(() => []);
|
|
13455
14059
|
for (const entry of entries) {
|
|
13456
14060
|
if (entry.isDirectory()) {
|
|
13457
14061
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
13458
|
-
const child =
|
|
14062
|
+
const child = import_node_path57.default.join(start, entry.name);
|
|
13459
14063
|
if (await isPythonVenvDir(child)) continue;
|
|
13460
14064
|
out.push(...await walkYamlFiles2(child, depth + 1, max));
|
|
13461
|
-
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(
|
|
13462
|
-
out.push(
|
|
14065
|
+
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path57.default.extname(entry.name))) {
|
|
14066
|
+
out.push(import_node_path57.default.join(start, entry.name));
|
|
13463
14067
|
}
|
|
13464
14068
|
}
|
|
13465
14069
|
return out;
|
|
@@ -13468,7 +14072,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
13468
14072
|
let nodesAdded = 0;
|
|
13469
14073
|
const files = await walkYamlFiles2(scanPath);
|
|
13470
14074
|
for (const file of files) {
|
|
13471
|
-
const content = await
|
|
14075
|
+
const content = await import_node_fs25.promises.readFile(file, "utf8");
|
|
13472
14076
|
let docs;
|
|
13473
14077
|
try {
|
|
13474
14078
|
docs = (0, import_yaml3.parseAllDocuments)(content).map((d) => d.toJSON());
|
|
@@ -13492,16 +14096,16 @@ async function addK8sResources(graph, scanPath) {
|
|
|
13492
14096
|
|
|
13493
14097
|
// src/extract/infra/cloudflare.ts
|
|
13494
14098
|
init_cjs_shims();
|
|
13495
|
-
var
|
|
13496
|
-
var
|
|
14099
|
+
var import_node_fs26 = require("fs");
|
|
14100
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
13497
14101
|
var import_smol_toml2 = require("smol-toml");
|
|
13498
|
-
var
|
|
14102
|
+
var import_types47 = require("@neat.is/types");
|
|
13499
14103
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
13500
14104
|
async function readWranglerConfig(dir) {
|
|
13501
14105
|
for (const filename of WRANGLER_FILENAMES) {
|
|
13502
|
-
const abs =
|
|
14106
|
+
const abs = import_node_path58.default.join(dir, filename);
|
|
13503
14107
|
if (!await exists2(abs)) continue;
|
|
13504
|
-
const raw = await
|
|
14108
|
+
const raw = await import_node_fs26.promises.readFile(abs, "utf8");
|
|
13505
14109
|
const config = filename === "wrangler.toml" ? (0, import_smol_toml2.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
13506
14110
|
return { config, relFile: filename, raw };
|
|
13507
14111
|
}
|
|
@@ -13543,8 +14147,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
|
|
|
13543
14147
|
source: anchorId,
|
|
13544
14148
|
target: node.id,
|
|
13545
14149
|
type: edgeType,
|
|
13546
|
-
provenance:
|
|
13547
|
-
confidence: (0,
|
|
14150
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
14151
|
+
confidence: (0, import_types47.confidenceForExtracted)("structural"),
|
|
13548
14152
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
13549
14153
|
};
|
|
13550
14154
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -13562,11 +14166,11 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13562
14166
|
try {
|
|
13563
14167
|
read = await readWranglerConfig(service.dir);
|
|
13564
14168
|
} catch (err) {
|
|
13565
|
-
recordExtractionError("infra cloudflare",
|
|
14169
|
+
recordExtractionError("infra cloudflare", import_node_path58.default.relative(scanPath, service.dir), err);
|
|
13566
14170
|
continue;
|
|
13567
14171
|
}
|
|
13568
14172
|
if (!read || !read.config.name) continue;
|
|
13569
|
-
const evidenceFile = toPosix(
|
|
14173
|
+
const evidenceFile = toPosix(import_node_path58.default.relative(scanPath, import_node_path58.default.join(service.dir, read.relFile)));
|
|
13570
14174
|
discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
|
|
13571
14175
|
}
|
|
13572
14176
|
for (const worker of discovered) {
|
|
@@ -13578,7 +14182,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13578
14182
|
}
|
|
13579
14183
|
let anchorId = service.node.id;
|
|
13580
14184
|
if (config.main) {
|
|
13581
|
-
const entryRelPath = toPosix(
|
|
14185
|
+
const entryRelPath = toPosix(import_node_path58.default.normalize(config.main));
|
|
13582
14186
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
13583
14187
|
graph,
|
|
13584
14188
|
service.pkg.name,
|
|
@@ -13605,15 +14209,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13605
14209
|
nodesAdded++;
|
|
13606
14210
|
}
|
|
13607
14211
|
if (runtimeNode.id !== anchorId) {
|
|
13608
|
-
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id,
|
|
14212
|
+
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types47.EdgeType.RUNS_ON);
|
|
13609
14213
|
if (!graph.hasEdge(runsOnId)) {
|
|
13610
14214
|
const edge = {
|
|
13611
14215
|
id: runsOnId,
|
|
13612
14216
|
source: anchorId,
|
|
13613
14217
|
target: runtimeNode.id,
|
|
13614
|
-
type:
|
|
13615
|
-
provenance:
|
|
13616
|
-
confidence: (0,
|
|
14218
|
+
type: import_types47.EdgeType.RUNS_ON,
|
|
14219
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
14220
|
+
confidence: (0, import_types47.confidenceForExtracted)("structural"),
|
|
13617
14221
|
evidence: {
|
|
13618
14222
|
file: evidenceFile,
|
|
13619
14223
|
...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
|
|
@@ -13627,7 +14231,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13627
14231
|
const result = addResourceEdge(
|
|
13628
14232
|
graph,
|
|
13629
14233
|
anchorId,
|
|
13630
|
-
|
|
14234
|
+
import_types47.EdgeType.CONNECTS_TO,
|
|
13631
14235
|
"cloudflare-route",
|
|
13632
14236
|
route,
|
|
13633
14237
|
evidenceFile,
|
|
@@ -13651,7 +14255,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13651
14255
|
const result = addResourceEdge(
|
|
13652
14256
|
graph,
|
|
13653
14257
|
anchorId,
|
|
13654
|
-
|
|
14258
|
+
import_types47.EdgeType.DEPENDS_ON,
|
|
13655
14259
|
group.kind,
|
|
13656
14260
|
name,
|
|
13657
14261
|
evidenceFile,
|
|
@@ -13665,7 +14269,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13665
14269
|
const result = addResourceEdge(
|
|
13666
14270
|
graph,
|
|
13667
14271
|
anchorId,
|
|
13668
|
-
|
|
14272
|
+
import_types47.EdgeType.DEPENDS_ON,
|
|
13669
14273
|
"cloudflare-cron",
|
|
13670
14274
|
cron,
|
|
13671
14275
|
evidenceFile,
|
|
@@ -13678,7 +14282,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13678
14282
|
const result = addResourceEdge(
|
|
13679
14283
|
graph,
|
|
13680
14284
|
anchorId,
|
|
13681
|
-
|
|
14285
|
+
import_types47.EdgeType.DEPENDS_ON,
|
|
13682
14286
|
"cloudflare-env-var",
|
|
13683
14287
|
varName,
|
|
13684
14288
|
evidenceFile,
|
|
@@ -13691,15 +14295,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13691
14295
|
if (!svc.service) continue;
|
|
13692
14296
|
const target = workerIndex.get(svc.service);
|
|
13693
14297
|
if (target && target.anchorId !== anchorId) {
|
|
13694
|
-
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId,
|
|
14298
|
+
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types47.EdgeType.CALLS);
|
|
13695
14299
|
if (!graph.hasEdge(edgeId)) {
|
|
13696
14300
|
const edge = {
|
|
13697
14301
|
id: edgeId,
|
|
13698
14302
|
source: anchorId,
|
|
13699
14303
|
target: target.anchorId,
|
|
13700
|
-
type:
|
|
13701
|
-
provenance:
|
|
13702
|
-
confidence: (0,
|
|
14304
|
+
type: import_types47.EdgeType.CALLS,
|
|
14305
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
14306
|
+
confidence: (0, import_types47.confidenceForExtracted)("structural"),
|
|
13703
14307
|
evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
|
|
13704
14308
|
};
|
|
13705
14309
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -13710,7 +14314,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13710
14314
|
const result = addResourceEdge(
|
|
13711
14315
|
graph,
|
|
13712
14316
|
anchorId,
|
|
13713
|
-
|
|
14317
|
+
import_types47.EdgeType.DEPENDS_ON,
|
|
13714
14318
|
"cloudflare-service-binding",
|
|
13715
14319
|
svc.service,
|
|
13716
14320
|
evidenceFile,
|
|
@@ -13725,24 +14329,24 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
13725
14329
|
|
|
13726
14330
|
// src/extract/infra/vercel.ts
|
|
13727
14331
|
init_cjs_shims();
|
|
13728
|
-
var
|
|
13729
|
-
var
|
|
13730
|
-
var
|
|
14332
|
+
var import_node_fs27 = require("fs");
|
|
14333
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
14334
|
+
var import_types48 = require("@neat.is/types");
|
|
13731
14335
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
13732
14336
|
async function readVercelConfig(dir) {
|
|
13733
14337
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
13734
|
-
const abs =
|
|
14338
|
+
const abs = import_node_path59.default.join(dir, filename);
|
|
13735
14339
|
if (!await exists2(abs)) continue;
|
|
13736
|
-
const raw = await
|
|
14340
|
+
const raw = await import_node_fs27.promises.readFile(abs, "utf8");
|
|
13737
14341
|
const config = JSON.parse(maskCommentsInSource(raw));
|
|
13738
14342
|
return { config, relFile: filename, raw };
|
|
13739
14343
|
}
|
|
13740
14344
|
return null;
|
|
13741
14345
|
}
|
|
13742
14346
|
async function readLinkedProjectName(dir) {
|
|
13743
|
-
const abs =
|
|
14347
|
+
const abs = import_node_path59.default.join(dir, ".vercel", "project.json");
|
|
13744
14348
|
if (!await exists2(abs)) return void 0;
|
|
13745
|
-
const parsed = JSON.parse(await
|
|
14349
|
+
const parsed = JSON.parse(await import_node_fs27.promises.readFile(abs, "utf8"));
|
|
13746
14350
|
return typeof parsed.projectName === "string" ? parsed.projectName : void 0;
|
|
13747
14351
|
}
|
|
13748
14352
|
function routeSource(route) {
|
|
@@ -13758,7 +14362,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
13758
14362
|
read = await readVercelConfig(service.dir);
|
|
13759
14363
|
projectName = await readLinkedProjectName(service.dir);
|
|
13760
14364
|
} catch (err) {
|
|
13761
|
-
recordExtractionError("infra vercel",
|
|
14365
|
+
recordExtractionError("infra vercel", import_node_path59.default.relative(scanPath, service.dir), err);
|
|
13762
14366
|
continue;
|
|
13763
14367
|
}
|
|
13764
14368
|
if (!read && !projectName) continue;
|
|
@@ -13774,7 +14378,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
13774
14378
|
const anchorId = service.node.id;
|
|
13775
14379
|
if (!read) continue;
|
|
13776
14380
|
const { config, relFile, raw } = read;
|
|
13777
|
-
const evidenceFile = toPosix(
|
|
14381
|
+
const evidenceFile = toPosix(import_node_path59.default.relative(scanPath, import_node_path59.default.join(service.dir, relFile)));
|
|
13778
14382
|
const add = (edgeType, kind, name) => {
|
|
13779
14383
|
if (!name) return;
|
|
13780
14384
|
const result = emitPlatformResourceEdge(
|
|
@@ -13790,12 +14394,12 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
13790
14394
|
nodesAdded += result.nodesAdded;
|
|
13791
14395
|
edgesAdded += result.edgesAdded;
|
|
13792
14396
|
};
|
|
13793
|
-
add(
|
|
13794
|
-
for (const cron of config.crons ?? []) add(
|
|
13795
|
-
for (const varName of Object.keys(config.env ?? {})) add(
|
|
13796
|
-
for (const varName of Object.keys(config.build?.env ?? {})) add(
|
|
14397
|
+
add(import_types48.EdgeType.RUNS_ON, "vercel", "vercel");
|
|
14398
|
+
for (const cron of config.crons ?? []) add(import_types48.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
|
|
14399
|
+
for (const varName of Object.keys(config.env ?? {})) add(import_types48.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
14400
|
+
for (const varName of Object.keys(config.build?.env ?? {})) add(import_types48.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
13797
14401
|
for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
|
|
13798
|
-
add(
|
|
14402
|
+
add(import_types48.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
|
|
13799
14403
|
}
|
|
13800
14404
|
}
|
|
13801
14405
|
return { nodesAdded, edgesAdded };
|
|
@@ -13803,16 +14407,16 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
13803
14407
|
|
|
13804
14408
|
// src/extract/infra/railway.ts
|
|
13805
14409
|
init_cjs_shims();
|
|
13806
|
-
var
|
|
13807
|
-
var
|
|
14410
|
+
var import_node_fs28 = require("fs");
|
|
14411
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
13808
14412
|
var import_smol_toml3 = require("smol-toml");
|
|
13809
|
-
var
|
|
14413
|
+
var import_types49 = require("@neat.is/types");
|
|
13810
14414
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
13811
14415
|
async function readRailwayConfig(dir) {
|
|
13812
14416
|
for (const filename of RAILWAY_FILENAMES) {
|
|
13813
|
-
const abs =
|
|
14417
|
+
const abs = import_node_path60.default.join(dir, filename);
|
|
13814
14418
|
if (!await exists2(abs)) continue;
|
|
13815
|
-
const raw = await
|
|
14419
|
+
const raw = await import_node_fs28.promises.readFile(abs, "utf8");
|
|
13816
14420
|
const config = filename === "railway.toml" ? (0, import_smol_toml3.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
13817
14421
|
return { config, relFile: filename, raw };
|
|
13818
14422
|
}
|
|
@@ -13826,7 +14430,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
13826
14430
|
try {
|
|
13827
14431
|
read = await readRailwayConfig(service.dir);
|
|
13828
14432
|
} catch (err) {
|
|
13829
|
-
recordExtractionError("infra railway",
|
|
14433
|
+
recordExtractionError("infra railway", import_node_path60.default.relative(scanPath, service.dir), err);
|
|
13830
14434
|
continue;
|
|
13831
14435
|
}
|
|
13832
14436
|
if (!read) continue;
|
|
@@ -13836,7 +14440,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
13836
14440
|
}
|
|
13837
14441
|
const anchorId = service.node.id;
|
|
13838
14442
|
const { config, relFile, raw } = read;
|
|
13839
|
-
const evidenceFile = toPosix(
|
|
14443
|
+
const evidenceFile = toPosix(import_node_path60.default.relative(scanPath, import_node_path60.default.join(service.dir, relFile)));
|
|
13840
14444
|
const add = (edgeType, kind, name) => {
|
|
13841
14445
|
if (!name) return;
|
|
13842
14446
|
const result = emitPlatformResourceEdge(
|
|
@@ -13852,24 +14456,24 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
13852
14456
|
nodesAdded += result.nodesAdded;
|
|
13853
14457
|
edgesAdded += result.edgesAdded;
|
|
13854
14458
|
};
|
|
13855
|
-
add(
|
|
13856
|
-
add(
|
|
13857
|
-
add(
|
|
14459
|
+
add(import_types49.EdgeType.RUNS_ON, "railway", "railway");
|
|
14460
|
+
add(import_types49.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
|
|
14461
|
+
add(import_types49.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
|
|
13858
14462
|
}
|
|
13859
14463
|
return { nodesAdded, edgesAdded };
|
|
13860
14464
|
}
|
|
13861
14465
|
|
|
13862
14466
|
// src/extract/infra/supabase.ts
|
|
13863
14467
|
init_cjs_shims();
|
|
13864
|
-
var
|
|
13865
|
-
var
|
|
14468
|
+
var import_node_fs29 = require("fs");
|
|
14469
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
13866
14470
|
var import_smol_toml4 = require("smol-toml");
|
|
13867
|
-
var
|
|
14471
|
+
var import_types50 = require("@neat.is/types");
|
|
13868
14472
|
async function readSupabaseConfig(dir) {
|
|
13869
|
-
const relFile =
|
|
13870
|
-
const abs =
|
|
14473
|
+
const relFile = import_node_path61.default.join("supabase", "config.toml");
|
|
14474
|
+
const abs = import_node_path61.default.join(dir, relFile);
|
|
13871
14475
|
if (!await exists2(abs)) return null;
|
|
13872
|
-
const raw = await
|
|
14476
|
+
const raw = await import_node_fs29.promises.readFile(abs, "utf8");
|
|
13873
14477
|
const config = (0, import_smol_toml4.parse)(raw);
|
|
13874
14478
|
return { config, relFile, raw };
|
|
13875
14479
|
}
|
|
@@ -13881,7 +14485,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
13881
14485
|
try {
|
|
13882
14486
|
read = await readSupabaseConfig(service.dir);
|
|
13883
14487
|
} catch (err) {
|
|
13884
|
-
recordExtractionError("infra supabase",
|
|
14488
|
+
recordExtractionError("infra supabase", import_node_path61.default.relative(scanPath, service.dir), err);
|
|
13885
14489
|
continue;
|
|
13886
14490
|
}
|
|
13887
14491
|
if (!read) continue;
|
|
@@ -13896,7 +14500,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
13896
14500
|
});
|
|
13897
14501
|
}
|
|
13898
14502
|
const anchorId = service.node.id;
|
|
13899
|
-
const evidenceFile = toPosix(
|
|
14503
|
+
const evidenceFile = toPosix(import_node_path61.default.relative(scanPath, import_node_path61.default.join(service.dir, relFile)));
|
|
13900
14504
|
const add = (edgeType, kind, name) => {
|
|
13901
14505
|
if (!name) return;
|
|
13902
14506
|
const result = emitPlatformResourceEdge(
|
|
@@ -13912,10 +14516,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
13912
14516
|
nodesAdded += result.nodesAdded;
|
|
13913
14517
|
edgesAdded += result.edgesAdded;
|
|
13914
14518
|
};
|
|
13915
|
-
add(
|
|
13916
|
-
for (const fn of Object.keys(config.functions ?? {})) add(
|
|
13917
|
-
if (config.storage) add(
|
|
13918
|
-
if (config.auth) add(
|
|
14519
|
+
add(import_types50.EdgeType.RUNS_ON, "supabase", "supabase");
|
|
14520
|
+
for (const fn of Object.keys(config.functions ?? {})) add(import_types50.EdgeType.DEPENDS_ON, "supabase-function", fn);
|
|
14521
|
+
if (config.storage) add(import_types50.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
|
|
14522
|
+
if (config.auth) add(import_types50.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
|
|
13919
14523
|
}
|
|
13920
14524
|
return { nodesAdded, edgesAdded };
|
|
13921
14525
|
}
|
|
@@ -13938,10 +14542,10 @@ async function addInfra(graph, scanPath, services) {
|
|
|
13938
14542
|
|
|
13939
14543
|
// src/extract/zod-shapes.ts
|
|
13940
14544
|
init_cjs_shims();
|
|
13941
|
-
var
|
|
14545
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
13942
14546
|
var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
|
|
13943
14547
|
var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
|
|
13944
|
-
var
|
|
14548
|
+
var import_types51 = require("@neat.is/types");
|
|
13945
14549
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
13946
14550
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
13947
14551
|
function parserForExt4(ext) {
|
|
@@ -14033,7 +14637,7 @@ function topLevelSchemas(root) {
|
|
|
14033
14637
|
}
|
|
14034
14638
|
function zodShapesFromFile(file, serviceDir) {
|
|
14035
14639
|
if (!ZOD_IMPORT_RE.test(file.content)) return [];
|
|
14036
|
-
const tree = parseSource3(parserForExt4(
|
|
14640
|
+
const tree = parseSource3(parserForExt4(import_node_path62.default.extname(file.path)), file.content);
|
|
14037
14641
|
const out = [];
|
|
14038
14642
|
const seen = /* @__PURE__ */ new Set();
|
|
14039
14643
|
for (const { name, call } of topLevelSchemas(tree.rootNode)) {
|
|
@@ -14047,11 +14651,11 @@ function zodShapesFromFile(file, serviceDir) {
|
|
|
14047
14651
|
seen.add(name);
|
|
14048
14652
|
const line = call.startPosition.row + 1;
|
|
14049
14653
|
out.push({
|
|
14050
|
-
infraId: (0,
|
|
14654
|
+
infraId: (0, import_types51.infraId)("zod-schema", name),
|
|
14051
14655
|
name,
|
|
14052
14656
|
fields,
|
|
14053
14657
|
evidence: {
|
|
14054
|
-
file:
|
|
14658
|
+
file: import_node_path62.default.relative(serviceDir, file.path),
|
|
14055
14659
|
line,
|
|
14056
14660
|
snippet: snippet(file.content, line)
|
|
14057
14661
|
}
|
|
@@ -14082,7 +14686,7 @@ async function addZodShapes(graph, services) {
|
|
|
14082
14686
|
if (!graph.hasNode(shape.infraId)) {
|
|
14083
14687
|
const node = {
|
|
14084
14688
|
id: shape.infraId,
|
|
14085
|
-
type:
|
|
14689
|
+
type: import_types51.NodeType.InfraNode,
|
|
14086
14690
|
name: shape.name,
|
|
14087
14691
|
provider: "self",
|
|
14088
14692
|
kind: "zod-schema"
|
|
@@ -14092,14 +14696,14 @@ async function addZodShapes(graph, services) {
|
|
|
14092
14696
|
}
|
|
14093
14697
|
if (shape.fields.length > 0) {
|
|
14094
14698
|
const node = graph.getNodeAttributes(shape.infraId);
|
|
14095
|
-
if (node.type ===
|
|
14699
|
+
if (node.type === import_types51.NodeType.InfraNode) {
|
|
14096
14700
|
graph.replaceNodeAttributes(shape.infraId, {
|
|
14097
14701
|
...node,
|
|
14098
14702
|
columns: foldColumns(
|
|
14099
14703
|
node.columns,
|
|
14100
14704
|
shape.fields,
|
|
14101
|
-
|
|
14102
|
-
(0,
|
|
14705
|
+
import_types51.Provenance.EXTRACTED,
|
|
14706
|
+
(0, import_types51.confidenceForExtracted)("structural")
|
|
14103
14707
|
)
|
|
14104
14708
|
});
|
|
14105
14709
|
}
|
|
@@ -14113,15 +14717,15 @@ async function addZodShapes(graph, services) {
|
|
|
14113
14717
|
);
|
|
14114
14718
|
nodesAdded += n;
|
|
14115
14719
|
edgesAdded += e;
|
|
14116
|
-
const edgeId = (0,
|
|
14720
|
+
const edgeId = (0, import_types51.extractedEdgeId)(fileNodeId, shape.infraId, import_types51.EdgeType.CONTAINS);
|
|
14117
14721
|
if (!graph.hasEdge(edgeId)) {
|
|
14118
14722
|
const edge = {
|
|
14119
14723
|
id: edgeId,
|
|
14120
14724
|
source: fileNodeId,
|
|
14121
14725
|
target: shape.infraId,
|
|
14122
|
-
type:
|
|
14123
|
-
provenance:
|
|
14124
|
-
confidence: (0,
|
|
14726
|
+
type: import_types51.EdgeType.CONTAINS,
|
|
14727
|
+
provenance: import_types51.Provenance.EXTRACTED,
|
|
14728
|
+
confidence: (0, import_types51.confidenceForExtracted)("structural"),
|
|
14125
14729
|
evidence: shape.evidence
|
|
14126
14730
|
};
|
|
14127
14731
|
graph.addEdgeWithKey(edgeId, fileNodeId, shape.infraId, edge);
|
|
@@ -14135,7 +14739,7 @@ async function addZodShapes(graph, services) {
|
|
|
14135
14739
|
|
|
14136
14740
|
// src/extract/firestore-rules.ts
|
|
14137
14741
|
init_cjs_shims();
|
|
14138
|
-
var
|
|
14742
|
+
var import_types52 = require("@neat.is/types");
|
|
14139
14743
|
var FIRESTORE_COLLECTION_KIND = "firestore-collection";
|
|
14140
14744
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["write", "create", "update"]);
|
|
14141
14745
|
function stripComments(src) {
|
|
@@ -14275,7 +14879,7 @@ async function addFirestoreRules(graph, services) {
|
|
|
14275
14879
|
if (guards.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
14276
14880
|
graph.forEachNode((id, attrs) => {
|
|
14277
14881
|
const node = attrs;
|
|
14278
|
-
if (node.type !==
|
|
14882
|
+
if (node.type !== import_types52.NodeType.InfraNode) return;
|
|
14279
14883
|
if (node.kind !== FIRESTORE_COLLECTION_KIND) return;
|
|
14280
14884
|
const fields = guards.get(collectionKeyFromName(node.name));
|
|
14281
14885
|
if (!fields || fields.size === 0) return;
|
|
@@ -14288,17 +14892,17 @@ async function addFirestoreRules(graph, services) {
|
|
|
14288
14892
|
}
|
|
14289
14893
|
|
|
14290
14894
|
// src/extract/index.ts
|
|
14291
|
-
var
|
|
14895
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
14292
14896
|
|
|
14293
14897
|
// src/extract/retire.ts
|
|
14294
14898
|
init_cjs_shims();
|
|
14295
|
-
var
|
|
14296
|
-
var
|
|
14297
|
-
var
|
|
14899
|
+
var import_node_fs30 = require("fs");
|
|
14900
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
14901
|
+
var import_types53 = require("@neat.is/types");
|
|
14298
14902
|
function dropOrphanedFileNodes(graph) {
|
|
14299
14903
|
const orphans = [];
|
|
14300
14904
|
graph.forEachNode((id, attrs) => {
|
|
14301
|
-
if (attrs.type !==
|
|
14905
|
+
if (attrs.type !== import_types53.NodeType.FileNode) return;
|
|
14302
14906
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
14303
14907
|
orphans.push(id);
|
|
14304
14908
|
}
|
|
@@ -14311,14 +14915,14 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
|
|
|
14311
14915
|
const bases = [scanPath, ...serviceDirs];
|
|
14312
14916
|
graph.forEachEdge((id, attrs) => {
|
|
14313
14917
|
const edge = attrs;
|
|
14314
|
-
if (edge.provenance !==
|
|
14918
|
+
if (edge.provenance !== import_types53.Provenance.EXTRACTED) return;
|
|
14315
14919
|
const evidenceFile = edge.evidence?.file;
|
|
14316
14920
|
if (!evidenceFile) return;
|
|
14317
|
-
if (
|
|
14318
|
-
if (!(0,
|
|
14921
|
+
if (import_node_path63.default.isAbsolute(evidenceFile)) {
|
|
14922
|
+
if (!(0, import_node_fs30.existsSync)(evidenceFile)) toDrop.push(id);
|
|
14319
14923
|
return;
|
|
14320
14924
|
}
|
|
14321
|
-
const found = bases.some((base) => (0,
|
|
14925
|
+
const found = bases.some((base) => (0, import_node_fs30.existsSync)(import_node_path63.default.join(base, evidenceFile)));
|
|
14322
14926
|
if (!found) toDrop.push(id);
|
|
14323
14927
|
});
|
|
14324
14928
|
for (const id of toDrop) graph.dropEdge(id);
|
|
@@ -14375,7 +14979,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
14375
14979
|
}
|
|
14376
14980
|
const droppedEntries = drainDroppedExtracted();
|
|
14377
14981
|
if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
|
|
14378
|
-
const rejectedPath =
|
|
14982
|
+
const rejectedPath = import_node_path64.default.join(import_node_path64.default.dirname(opts.errorsPath), "rejected.ndjson");
|
|
14379
14983
|
try {
|
|
14380
14984
|
await writeRejectedExtracted(droppedEntries, rejectedPath);
|
|
14381
14985
|
} catch (err) {
|
|
@@ -14409,7 +15013,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
14409
15013
|
|
|
14410
15014
|
// src/diff.ts
|
|
14411
15015
|
init_cjs_shims();
|
|
14412
|
-
var
|
|
15016
|
+
var import_node_fs31 = require("fs");
|
|
14413
15017
|
async function loadSnapshotForDiff(target) {
|
|
14414
15018
|
if (/^https?:\/\//i.test(target)) {
|
|
14415
15019
|
const res = await fetch(target);
|
|
@@ -14418,7 +15022,7 @@ async function loadSnapshotForDiff(target) {
|
|
|
14418
15022
|
}
|
|
14419
15023
|
return await res.json();
|
|
14420
15024
|
}
|
|
14421
|
-
const raw = await
|
|
15025
|
+
const raw = await import_node_fs31.promises.readFile(target, "utf8");
|
|
14422
15026
|
return JSON.parse(raw);
|
|
14423
15027
|
}
|
|
14424
15028
|
function indexEntries(entries) {
|
|
@@ -14486,9 +15090,9 @@ function canonicalJson(value) {
|
|
|
14486
15090
|
|
|
14487
15091
|
// src/persist.ts
|
|
14488
15092
|
init_cjs_shims();
|
|
14489
|
-
var
|
|
14490
|
-
var
|
|
14491
|
-
var
|
|
15093
|
+
var import_node_fs32 = require("fs");
|
|
15094
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
15095
|
+
var import_types54 = require("@neat.is/types");
|
|
14492
15096
|
var SCHEMA_VERSION = 7;
|
|
14493
15097
|
function migrateV1ToV2(payload) {
|
|
14494
15098
|
const nodes = payload.graph.nodes;
|
|
@@ -14512,7 +15116,7 @@ function migrateV5ToV6(payload) {
|
|
|
14512
15116
|
if (Array.isArray(nodes)) {
|
|
14513
15117
|
for (const node of nodes) {
|
|
14514
15118
|
const attrs = node.attributes;
|
|
14515
|
-
if (!attrs || attrs.type !==
|
|
15119
|
+
if (!attrs || attrs.type !== import_types54.NodeType.InfraNode) continue;
|
|
14516
15120
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
14517
15121
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
14518
15122
|
}
|
|
@@ -14528,12 +15132,12 @@ function migrateV2ToV3(payload) {
|
|
|
14528
15132
|
for (const edge of edges) {
|
|
14529
15133
|
const attrs = edge.attributes;
|
|
14530
15134
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
14531
|
-
attrs.provenance =
|
|
15135
|
+
attrs.provenance = import_types54.Provenance.OBSERVED;
|
|
14532
15136
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
14533
15137
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
14534
15138
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
14535
15139
|
if (type && source && target) {
|
|
14536
|
-
const newId = (0,
|
|
15140
|
+
const newId = (0, import_types54.observedEdgeId)(source, target, type);
|
|
14537
15141
|
attrs.id = newId;
|
|
14538
15142
|
if (edge.key) edge.key = newId;
|
|
14539
15143
|
}
|
|
@@ -14542,7 +15146,7 @@ function migrateV2ToV3(payload) {
|
|
|
14542
15146
|
return { ...payload, schemaVersion: 3 };
|
|
14543
15147
|
}
|
|
14544
15148
|
async function ensureDir(filePath) {
|
|
14545
|
-
await
|
|
15149
|
+
await import_node_fs32.promises.mkdir(import_node_path65.default.dirname(filePath), { recursive: true });
|
|
14546
15150
|
}
|
|
14547
15151
|
async function saveGraphToDisk(graph, outPath) {
|
|
14548
15152
|
await ensureDir(outPath);
|
|
@@ -14552,13 +15156,13 @@ async function saveGraphToDisk(graph, outPath) {
|
|
|
14552
15156
|
graph: graph.export()
|
|
14553
15157
|
};
|
|
14554
15158
|
const tmp = `${outPath}.tmp`;
|
|
14555
|
-
await
|
|
14556
|
-
await
|
|
15159
|
+
await import_node_fs32.promises.writeFile(tmp, JSON.stringify(payload), "utf8");
|
|
15160
|
+
await import_node_fs32.promises.rename(tmp, outPath);
|
|
14557
15161
|
}
|
|
14558
15162
|
async function loadGraphFromDisk(graph, outPath) {
|
|
14559
15163
|
let raw;
|
|
14560
15164
|
try {
|
|
14561
|
-
raw = await
|
|
15165
|
+
raw = await import_node_fs32.promises.readFile(outPath, "utf8");
|
|
14562
15166
|
} catch (err) {
|
|
14563
15167
|
if (err.code === "ENOENT") return;
|
|
14564
15168
|
throw err;
|
|
@@ -14632,23 +15236,23 @@ function startPersistLoop(graph, outPath, opts = {}) {
|
|
|
14632
15236
|
|
|
14633
15237
|
// src/projects.ts
|
|
14634
15238
|
init_cjs_shims();
|
|
14635
|
-
var
|
|
15239
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
14636
15240
|
function pathsForProject(project, baseDir) {
|
|
14637
15241
|
if (project === DEFAULT_PROJECT) {
|
|
14638
15242
|
return {
|
|
14639
|
-
snapshotPath:
|
|
14640
|
-
errorsPath:
|
|
14641
|
-
staleEventsPath:
|
|
14642
|
-
embeddingsCachePath:
|
|
14643
|
-
policyViolationsPath:
|
|
15243
|
+
snapshotPath: import_node_path66.default.join(baseDir, "graph.json"),
|
|
15244
|
+
errorsPath: import_node_path66.default.join(baseDir, "errors.ndjson"),
|
|
15245
|
+
staleEventsPath: import_node_path66.default.join(baseDir, "stale-events.ndjson"),
|
|
15246
|
+
embeddingsCachePath: import_node_path66.default.join(baseDir, "embeddings.json"),
|
|
15247
|
+
policyViolationsPath: import_node_path66.default.join(baseDir, "policy-violations.ndjson")
|
|
14644
15248
|
};
|
|
14645
15249
|
}
|
|
14646
15250
|
return {
|
|
14647
|
-
snapshotPath:
|
|
14648
|
-
errorsPath:
|
|
14649
|
-
staleEventsPath:
|
|
14650
|
-
embeddingsCachePath:
|
|
14651
|
-
policyViolationsPath:
|
|
15251
|
+
snapshotPath: import_node_path66.default.join(baseDir, `${project}.json`),
|
|
15252
|
+
errorsPath: import_node_path66.default.join(baseDir, `errors.${project}.ndjson`),
|
|
15253
|
+
staleEventsPath: import_node_path66.default.join(baseDir, `stale-events.${project}.ndjson`),
|
|
15254
|
+
embeddingsCachePath: import_node_path66.default.join(baseDir, `embeddings.${project}.json`),
|
|
15255
|
+
policyViolationsPath: import_node_path66.default.join(baseDir, `policy-violations.${project}.ndjson`)
|
|
14652
15256
|
};
|
|
14653
15257
|
}
|
|
14654
15258
|
var Projects = class {
|
|
@@ -14688,20 +15292,20 @@ function parseExtraProjects(raw) {
|
|
|
14688
15292
|
|
|
14689
15293
|
// src/registry.ts
|
|
14690
15294
|
init_cjs_shims();
|
|
14691
|
-
var
|
|
15295
|
+
var import_node_fs33 = require("fs");
|
|
14692
15296
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
14693
|
-
var
|
|
14694
|
-
var
|
|
15297
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
15298
|
+
var import_types55 = require("@neat.is/types");
|
|
14695
15299
|
function neatHome() {
|
|
14696
15300
|
const override = process.env.NEAT_HOME;
|
|
14697
|
-
if (override && override.length > 0) return
|
|
14698
|
-
return
|
|
15301
|
+
if (override && override.length > 0) return import_node_path67.default.resolve(override);
|
|
15302
|
+
return import_node_path67.default.join(import_node_os3.default.homedir(), ".neat");
|
|
14699
15303
|
}
|
|
14700
15304
|
function registryPath() {
|
|
14701
|
-
return
|
|
15305
|
+
return import_node_path67.default.join(neatHome(), "projects.json");
|
|
14702
15306
|
}
|
|
14703
15307
|
function daemonsDir() {
|
|
14704
|
-
return
|
|
15308
|
+
return import_node_path67.default.join(neatHome(), "daemons");
|
|
14705
15309
|
}
|
|
14706
15310
|
function isFiniteInt(v) {
|
|
14707
15311
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -14734,7 +15338,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
|
|
|
14734
15338
|
const dir = daemonsDir();
|
|
14735
15339
|
let names;
|
|
14736
15340
|
try {
|
|
14737
|
-
names = await
|
|
15341
|
+
names = await import_node_fs33.promises.readdir(dir);
|
|
14738
15342
|
} catch (err) {
|
|
14739
15343
|
if (err.code === "ENOENT") return [];
|
|
14740
15344
|
throw err;
|
|
@@ -14742,10 +15346,10 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
|
|
|
14742
15346
|
const out = [];
|
|
14743
15347
|
for (const name of names) {
|
|
14744
15348
|
if (!name.endsWith(".json")) continue;
|
|
14745
|
-
const file =
|
|
15349
|
+
const file = import_node_path67.default.join(dir, name);
|
|
14746
15350
|
let raw;
|
|
14747
15351
|
try {
|
|
14748
|
-
raw = await
|
|
15352
|
+
raw = await import_node_fs33.promises.readFile(file, "utf8");
|
|
14749
15353
|
} catch {
|
|
14750
15354
|
continue;
|
|
14751
15355
|
}
|
|
@@ -14773,7 +15377,7 @@ async function readRegistry() {
|
|
|
14773
15377
|
const file = registryPath();
|
|
14774
15378
|
let raw;
|
|
14775
15379
|
try {
|
|
14776
|
-
raw = await
|
|
15380
|
+
raw = await import_node_fs33.promises.readFile(file, "utf8");
|
|
14777
15381
|
} catch (err) {
|
|
14778
15382
|
if (err.code === "ENOENT") {
|
|
14779
15383
|
return { version: 1, projects: [] };
|
|
@@ -14781,7 +15385,7 @@ async function readRegistry() {
|
|
|
14781
15385
|
throw err;
|
|
14782
15386
|
}
|
|
14783
15387
|
const parsed = JSON.parse(raw);
|
|
14784
|
-
return
|
|
15388
|
+
return import_types55.RegistryFileSchema.parse(parsed);
|
|
14785
15389
|
}
|
|
14786
15390
|
async function getProject(name) {
|
|
14787
15391
|
const reg = await readRegistry();
|
|
@@ -14856,8 +15460,8 @@ init_auth();
|
|
|
14856
15460
|
// src/connectors-config.ts
|
|
14857
15461
|
init_cjs_shims();
|
|
14858
15462
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
14859
|
-
var
|
|
14860
|
-
var
|
|
15463
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
15464
|
+
var import_node_fs34 = require("fs");
|
|
14861
15465
|
var CONNECTORS_CONFIG_VERSION = 1;
|
|
14862
15466
|
var EnvRefUnsetError = class extends Error {
|
|
14863
15467
|
ref;
|
|
@@ -14871,17 +15475,17 @@ var EnvRefUnsetError = class extends Error {
|
|
|
14871
15475
|
};
|
|
14872
15476
|
function neatHome2() {
|
|
14873
15477
|
const override = process.env.NEAT_HOME;
|
|
14874
|
-
if (override && override.length > 0) return
|
|
14875
|
-
return
|
|
15478
|
+
if (override && override.length > 0) return import_node_path68.default.resolve(override);
|
|
15479
|
+
return import_node_path68.default.join(import_node_os4.default.homedir(), ".neat");
|
|
14876
15480
|
}
|
|
14877
15481
|
function connectorsConfigPath(home = neatHome2()) {
|
|
14878
|
-
return
|
|
15482
|
+
return import_node_path68.default.join(home, "connectors.json");
|
|
14879
15483
|
}
|
|
14880
15484
|
var MODE_MASK_LOOSER_THAN_0600 = 63;
|
|
14881
15485
|
async function warnIfModeLooserThan0600(file) {
|
|
14882
15486
|
if (process.platform === "win32") return;
|
|
14883
15487
|
try {
|
|
14884
|
-
const stat = await
|
|
15488
|
+
const stat = await import_node_fs34.promises.stat(file);
|
|
14885
15489
|
if ((stat.mode & MODE_MASK_LOOSER_THAN_0600) !== 0) {
|
|
14886
15490
|
const mode = (stat.mode & 511).toString(8).padStart(3, "0");
|
|
14887
15491
|
console.warn(
|
|
@@ -14895,7 +15499,7 @@ async function readConnectorsConfig(home = neatHome2()) {
|
|
|
14895
15499
|
const file = connectorsConfigPath(home);
|
|
14896
15500
|
let raw;
|
|
14897
15501
|
try {
|
|
14898
|
-
raw = await
|
|
15502
|
+
raw = await import_node_fs34.promises.readFile(file, "utf8");
|
|
14899
15503
|
} catch (err) {
|
|
14900
15504
|
if (err.code === "ENOENT") {
|
|
14901
15505
|
return { version: CONNECTORS_CONFIG_VERSION, connectors: [] };
|
|
@@ -15062,15 +15666,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
15062
15666
|
|
|
15063
15667
|
// src/connectors/index.ts
|
|
15064
15668
|
init_cjs_shims();
|
|
15065
|
-
var
|
|
15669
|
+
var import_types56 = require("@neat.is/types");
|
|
15066
15670
|
var NO_ENV = "unknown";
|
|
15067
15671
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
15068
15672
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
15069
15673
|
const sites = [];
|
|
15070
15674
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
15071
15675
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
15072
|
-
if (edge.provenance !==
|
|
15073
|
-
const parsed = (0,
|
|
15676
|
+
if (edge.provenance !== import_types56.Provenance.EXTRACTED) continue;
|
|
15677
|
+
const parsed = (0, import_types56.parseFileId)(edge.source);
|
|
15074
15678
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
15075
15679
|
const site = { relPath: edge.evidence.file };
|
|
15076
15680
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -15081,7 +15685,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
15081
15685
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
15082
15686
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
15083
15687
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
15084
|
-
if (attrs.type !==
|
|
15688
|
+
if (attrs.type !== import_types56.NodeType.RouteNode || !attrs.path) return void 0;
|
|
15085
15689
|
const site = { relPath: attrs.path };
|
|
15086
15690
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
15087
15691
|
return site;
|
|
@@ -15538,10 +16142,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
|
|
|
15538
16142
|
// src/connectors/supabase/map.ts
|
|
15539
16143
|
var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
|
|
15540
16144
|
var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
|
|
15541
|
-
function targetFromRestPath(
|
|
15542
|
-
const rpcMatch = REST_RPC_PATH_RE.exec(
|
|
16145
|
+
function targetFromRestPath(path71) {
|
|
16146
|
+
const rpcMatch = REST_RPC_PATH_RE.exec(path71);
|
|
15543
16147
|
if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
|
|
15544
|
-
const tableMatch = REST_TABLE_PATH_RE.exec(
|
|
16148
|
+
const tableMatch = REST_TABLE_PATH_RE.exec(path71);
|
|
15545
16149
|
if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
|
|
15546
16150
|
return null;
|
|
15547
16151
|
}
|
|
@@ -15652,23 +16256,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
15652
16256
|
|
|
15653
16257
|
// src/connectors/supabase/resolve.ts
|
|
15654
16258
|
init_cjs_shims();
|
|
15655
|
-
var
|
|
16259
|
+
var import_types58 = require("@neat.is/types");
|
|
15656
16260
|
function createSupabaseResolveTarget(graph, config) {
|
|
15657
16261
|
return (signal, _ctx) => {
|
|
15658
16262
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
15659
16263
|
return null;
|
|
15660
16264
|
}
|
|
15661
|
-
const subResourceId = (0,
|
|
16265
|
+
const subResourceId = (0, import_types58.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
15662
16266
|
if (graph.hasNode(subResourceId)) {
|
|
15663
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
16267
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types58.EdgeType.CALLS };
|
|
15664
16268
|
}
|
|
15665
|
-
const bareResourceId = (0,
|
|
16269
|
+
const bareResourceId = (0, import_types58.infraId)(signal.targetKind, signal.targetName);
|
|
15666
16270
|
if (graph.hasNode(bareResourceId)) {
|
|
15667
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
16271
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types58.EdgeType.CALLS };
|
|
15668
16272
|
}
|
|
15669
|
-
const projectLevelId = (0,
|
|
16273
|
+
const projectLevelId = (0, import_types58.infraId)("supabase", config.nodeRef);
|
|
15670
16274
|
if (graph.hasNode(projectLevelId)) {
|
|
15671
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
16275
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types58.EdgeType.CALLS };
|
|
15672
16276
|
}
|
|
15673
16277
|
return null;
|
|
15674
16278
|
};
|
|
@@ -15761,7 +16365,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
15761
16365
|
|
|
15762
16366
|
// src/connectors/railway/index.ts
|
|
15763
16367
|
init_cjs_shims();
|
|
15764
|
-
var
|
|
16368
|
+
var import_types62 = require("@neat.is/types");
|
|
15765
16369
|
|
|
15766
16370
|
// src/connectors/railway/client.ts
|
|
15767
16371
|
init_cjs_shims();
|
|
@@ -15912,7 +16516,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
15912
16516
|
const out = [];
|
|
15913
16517
|
graph.forEachNode((_id, attrs) => {
|
|
15914
16518
|
const node = attrs;
|
|
15915
|
-
if (node.type !==
|
|
16519
|
+
if (node.type !== import_types62.NodeType.RouteNode) return;
|
|
15916
16520
|
const route = attrs;
|
|
15917
16521
|
if (route.service !== serviceName) return;
|
|
15918
16522
|
out.push({
|
|
@@ -16016,12 +16620,12 @@ function createRailwayResolveTarget(config) {
|
|
|
16016
16620
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
16017
16621
|
if (!serviceName) return null;
|
|
16018
16622
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
16019
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
16623
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types62.EdgeType.CALLS };
|
|
16020
16624
|
}
|
|
16021
16625
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
16022
16626
|
const peerName = config.serviceNameById[signal.targetName];
|
|
16023
16627
|
if (!peerName) return null;
|
|
16024
|
-
return { targetNodeId: (0,
|
|
16628
|
+
return { targetNodeId: (0, import_types62.serviceId)(peerName), serviceName, edgeType: import_types62.EdgeType.CONNECTS_TO };
|
|
16025
16629
|
}
|
|
16026
16630
|
return null;
|
|
16027
16631
|
};
|
|
@@ -16145,9 +16749,9 @@ function parseFirebaseTargetName(targetName) {
|
|
|
16145
16749
|
const secondSep = rest.indexOf(FIELD_SEP);
|
|
16146
16750
|
if (secondSep === -1) return null;
|
|
16147
16751
|
const method = rest.slice(0, secondSep);
|
|
16148
|
-
const
|
|
16149
|
-
if (!resourceName || !method || !
|
|
16150
|
-
return { resourceName, method, path:
|
|
16752
|
+
const path71 = rest.slice(secondSep + 1);
|
|
16753
|
+
if (!resourceName || !method || !path71) return null;
|
|
16754
|
+
return { resourceName, method, path: path71 };
|
|
16151
16755
|
}
|
|
16152
16756
|
function resourceNameFor(type, labels) {
|
|
16153
16757
|
if (!labels) return null;
|
|
@@ -16185,14 +16789,14 @@ function mapLogEntryToSignal(entry) {
|
|
|
16185
16789
|
if (!req) return null;
|
|
16186
16790
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
16187
16791
|
const method = req.requestMethod.toUpperCase();
|
|
16188
|
-
const
|
|
16189
|
-
if (
|
|
16792
|
+
const path71 = pathFromRequestUrl(req.requestUrl);
|
|
16793
|
+
if (path71 === null) return null;
|
|
16190
16794
|
const timestamp = entry.timestamp;
|
|
16191
16795
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
16192
16796
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
|
|
16193
16797
|
return {
|
|
16194
16798
|
targetKind: resourceType,
|
|
16195
|
-
targetName: packFirebaseTargetName({ resourceName, method, path:
|
|
16799
|
+
targetName: packFirebaseTargetName({ resourceName, method, path: path71 }),
|
|
16196
16800
|
callCount: 1,
|
|
16197
16801
|
errorCount: isError ? 1 : 0,
|
|
16198
16802
|
lastObservedIso: timestamp
|
|
@@ -16209,7 +16813,7 @@ function mapLogEntriesToSignals(entries) {
|
|
|
16209
16813
|
|
|
16210
16814
|
// src/connectors/firebase/resolve.ts
|
|
16211
16815
|
init_cjs_shims();
|
|
16212
|
-
var
|
|
16816
|
+
var import_types63 = require("@neat.is/types");
|
|
16213
16817
|
function neatServiceNameFor(resourceType, resourceName, serviceMap) {
|
|
16214
16818
|
switch (resourceType) {
|
|
16215
16819
|
case "cloud_function":
|
|
@@ -16224,7 +16828,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
16224
16828
|
const entries = [];
|
|
16225
16829
|
graph.forEachNode((_id, attrs) => {
|
|
16226
16830
|
const node = attrs;
|
|
16227
|
-
if (node.type !==
|
|
16831
|
+
if (node.type !== import_types63.NodeType.RouteNode) return;
|
|
16228
16832
|
const route = attrs;
|
|
16229
16833
|
if (route.service !== serviceName) return;
|
|
16230
16834
|
entries.push({
|
|
@@ -16256,7 +16860,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
16256
16860
|
return {
|
|
16257
16861
|
targetNodeId: match.routeNodeId,
|
|
16258
16862
|
serviceName,
|
|
16259
|
-
edgeType:
|
|
16863
|
+
edgeType: import_types63.EdgeType.CALLS
|
|
16260
16864
|
};
|
|
16261
16865
|
};
|
|
16262
16866
|
}
|
|
@@ -16283,7 +16887,7 @@ init_cjs_shims();
|
|
|
16283
16887
|
|
|
16284
16888
|
// src/connectors/cloudflare/connector.ts
|
|
16285
16889
|
init_cjs_shims();
|
|
16286
|
-
var
|
|
16890
|
+
var import_types65 = require("@neat.is/types");
|
|
16287
16891
|
|
|
16288
16892
|
// src/connectors/cloudflare/client.ts
|
|
16289
16893
|
init_cjs_shims();
|
|
@@ -16399,7 +17003,7 @@ function mapEventToSignal(event) {
|
|
|
16399
17003
|
if (Number.isNaN(observedAt.getTime())) return null;
|
|
16400
17004
|
const statusCode = metadata?.statusCode;
|
|
16401
17005
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
16402
|
-
const
|
|
17006
|
+
const path71 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
16403
17007
|
return {
|
|
16404
17008
|
targetKind: CLOUDFLARE_TARGET_KIND,
|
|
16405
17009
|
targetName: scriptName,
|
|
@@ -16407,7 +17011,7 @@ function mapEventToSignal(event) {
|
|
|
16407
17011
|
errorCount: isError ? 1 : 0,
|
|
16408
17012
|
lastObservedIso: observedAt.toISOString(),
|
|
16409
17013
|
method,
|
|
16410
|
-
...
|
|
17014
|
+
...path71 ? { path: path71 } : {},
|
|
16411
17015
|
...typeof statusCode === "number" ? { statusCode } : {},
|
|
16412
17016
|
...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
|
|
16413
17017
|
};
|
|
@@ -16447,19 +17051,19 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
16447
17051
|
graph.forEachNode((id, attrs) => {
|
|
16448
17052
|
if (found) return;
|
|
16449
17053
|
const a = attrs;
|
|
16450
|
-
if (a.type ===
|
|
17054
|
+
if (a.type === import_types65.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
16451
17055
|
found = id;
|
|
16452
17056
|
}
|
|
16453
17057
|
});
|
|
16454
17058
|
return found;
|
|
16455
17059
|
}
|
|
16456
|
-
function findMatchingRouteNode(graph, serviceName, method,
|
|
16457
|
-
const normalizedPath = normalizePathTemplate(
|
|
17060
|
+
function findMatchingRouteNode(graph, serviceName, method, path71) {
|
|
17061
|
+
const normalizedPath = normalizePathTemplate(path71);
|
|
16458
17062
|
let found = null;
|
|
16459
17063
|
graph.forEachNode((id, attrs) => {
|
|
16460
17064
|
if (found) return;
|
|
16461
17065
|
const a = attrs;
|
|
16462
|
-
if (a.type !==
|
|
17066
|
+
if (a.type !== import_types65.NodeType.RouteNode || a.service !== serviceName) return;
|
|
16463
17067
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
16464
17068
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
16465
17069
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -16471,18 +17075,18 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
16471
17075
|
return (signal) => {
|
|
16472
17076
|
if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
|
|
16473
17077
|
const scriptName = signal.targetName;
|
|
16474
|
-
const { method, path:
|
|
17078
|
+
const { method, path: path71 } = signal;
|
|
16475
17079
|
const resolveRouteGrain = (serviceName, wholeFileId) => {
|
|
16476
|
-
if (!method || !
|
|
16477
|
-
return findMatchingRouteNode(graph, serviceName, method,
|
|
17080
|
+
if (!method || !path71) return wholeFileId;
|
|
17081
|
+
return findMatchingRouteNode(graph, serviceName, method, path71) ?? wholeFileId;
|
|
16478
17082
|
};
|
|
16479
17083
|
const mapping = config.workers?.[scriptName];
|
|
16480
17084
|
if (mapping) {
|
|
16481
|
-
const wholeFileId = (0,
|
|
17085
|
+
const wholeFileId = (0, import_types65.fileId)(mapping.service, mapping.entryFile);
|
|
16482
17086
|
return {
|
|
16483
17087
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
16484
17088
|
serviceName: mapping.service,
|
|
16485
|
-
edgeType:
|
|
17089
|
+
edgeType: import_types65.EdgeType.CALLS
|
|
16486
17090
|
};
|
|
16487
17091
|
}
|
|
16488
17092
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -16491,13 +17095,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
16491
17095
|
return {
|
|
16492
17096
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
16493
17097
|
serviceName: fileNode.service,
|
|
16494
|
-
edgeType:
|
|
17098
|
+
edgeType: import_types65.EdgeType.CALLS
|
|
16495
17099
|
};
|
|
16496
17100
|
}
|
|
16497
17101
|
return {
|
|
16498
|
-
targetNodeId: (0,
|
|
17102
|
+
targetNodeId: (0, import_types65.infraId)("cloudflare-worker", scriptName),
|
|
16499
17103
|
serviceName: scriptName,
|
|
16500
|
-
edgeType:
|
|
17104
|
+
edgeType: import_types65.EdgeType.CALLS,
|
|
16501
17105
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
16502
17106
|
};
|
|
16503
17107
|
};
|
|
@@ -16693,14 +17297,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
16693
17297
|
|
|
16694
17298
|
// src/connectors/neon/resolve.ts
|
|
16695
17299
|
init_cjs_shims();
|
|
16696
|
-
var
|
|
17300
|
+
var import_types69 = require("@neat.is/types");
|
|
16697
17301
|
function createNeonResolveTarget(config) {
|
|
16698
17302
|
return (signal) => {
|
|
16699
17303
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
16700
17304
|
return {
|
|
16701
|
-
targetNodeId: (0,
|
|
17305
|
+
targetNodeId: (0, import_types69.infraId)("sql-table", signal.targetName),
|
|
16702
17306
|
serviceName: config.serviceName,
|
|
16703
|
-
edgeType:
|
|
17307
|
+
edgeType: import_types69.EdgeType.CALLS,
|
|
16704
17308
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
16705
17309
|
};
|
|
16706
17310
|
};
|
|
@@ -16826,9 +17430,9 @@ function parseCloudRunTargetName(targetName) {
|
|
|
16826
17430
|
const secondSep = rest.indexOf(FIELD_SEP2);
|
|
16827
17431
|
if (secondSep === -1) return null;
|
|
16828
17432
|
const method = rest.slice(0, secondSep);
|
|
16829
|
-
const
|
|
16830
|
-
if (!serviceName || !method || !
|
|
16831
|
-
return { serviceName, method, path:
|
|
17433
|
+
const path71 = rest.slice(secondSep + 1);
|
|
17434
|
+
if (!serviceName || !method || !path71) return null;
|
|
17435
|
+
return { serviceName, method, path: path71 };
|
|
16832
17436
|
}
|
|
16833
17437
|
|
|
16834
17438
|
// src/connectors/cloud-run/map.ts
|
|
@@ -16857,14 +17461,14 @@ function mapLogEntryToSignal2(entry) {
|
|
|
16857
17461
|
if (!req) return null;
|
|
16858
17462
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
16859
17463
|
const method = req.requestMethod.toUpperCase();
|
|
16860
|
-
const
|
|
16861
|
-
if (
|
|
17464
|
+
const path71 = pathFromRequestUrl2(req.requestUrl);
|
|
17465
|
+
if (path71 === null) return null;
|
|
16862
17466
|
const timestamp = entry.timestamp;
|
|
16863
17467
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
16864
17468
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD4;
|
|
16865
17469
|
return {
|
|
16866
17470
|
targetKind: CLOUD_RUN_TARGET_KIND,
|
|
16867
|
-
targetName: packCloudRunTargetName({ serviceName, method, path:
|
|
17471
|
+
targetName: packCloudRunTargetName({ serviceName, method, path: path71 }),
|
|
16868
17472
|
callCount: 1,
|
|
16869
17473
|
errorCount: isError ? 1 : 0,
|
|
16870
17474
|
lastObservedIso: timestamp
|
|
@@ -16881,14 +17485,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
16881
17485
|
|
|
16882
17486
|
// src/connectors/cloud-run/resolve.ts
|
|
16883
17487
|
init_cjs_shims();
|
|
16884
|
-
var
|
|
17488
|
+
var import_types73 = require("@neat.is/types");
|
|
16885
17489
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
16886
17490
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
16887
17491
|
let found = null;
|
|
16888
17492
|
graph.forEachNode((_id, attrs) => {
|
|
16889
17493
|
if (found) return;
|
|
16890
17494
|
const node = attrs;
|
|
16891
|
-
if (node.type !==
|
|
17495
|
+
if (node.type !== import_types73.NodeType.RouteNode) return;
|
|
16892
17496
|
const route = attrs;
|
|
16893
17497
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
16894
17498
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -16903,23 +17507,23 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
16903
17507
|
if (signal.targetKind !== CLOUD_RUN_TARGET_KIND) return null;
|
|
16904
17508
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
16905
17509
|
if (!identity) return null;
|
|
16906
|
-
const { serviceName: gcpServiceName, method, path:
|
|
17510
|
+
const { serviceName: gcpServiceName, method, path: path71 } = identity;
|
|
16907
17511
|
const mappedService = config.serviceMap?.[gcpServiceName];
|
|
16908
17512
|
if (mappedService) {
|
|
16909
17513
|
const routeNodeId = findMatchingRouteNode2(
|
|
16910
17514
|
graph,
|
|
16911
17515
|
mappedService,
|
|
16912
17516
|
method,
|
|
16913
|
-
normalizePathTemplate(
|
|
17517
|
+
normalizePathTemplate(path71)
|
|
16914
17518
|
);
|
|
16915
17519
|
if (routeNodeId) {
|
|
16916
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
17520
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types73.EdgeType.CALLS };
|
|
16917
17521
|
}
|
|
16918
17522
|
}
|
|
16919
17523
|
return {
|
|
16920
|
-
targetNodeId: (0,
|
|
17524
|
+
targetNodeId: (0, import_types73.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
16921
17525
|
serviceName: mappedService ?? gcpServiceName,
|
|
16922
|
-
edgeType:
|
|
17526
|
+
edgeType: import_types73.EdgeType.CALLS,
|
|
16923
17527
|
ensureInfraNode: {
|
|
16924
17528
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
16925
17529
|
name: gcpServiceName,
|
|
@@ -16960,7 +17564,7 @@ function createCloudRunConnector(graph, config = {}) {
|
|
|
16960
17564
|
|
|
16961
17565
|
// src/connectors/render/index.ts
|
|
16962
17566
|
init_cjs_shims();
|
|
16963
|
-
var
|
|
17567
|
+
var import_types76 = require("@neat.is/types");
|
|
16964
17568
|
|
|
16965
17569
|
// src/connectors/render/types.ts
|
|
16966
17570
|
init_cjs_shims();
|
|
@@ -17038,7 +17642,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
17038
17642
|
const out = [];
|
|
17039
17643
|
graph.forEachNode((_id, attrs) => {
|
|
17040
17644
|
const node = attrs;
|
|
17041
|
-
if (node.type !==
|
|
17645
|
+
if (node.type !== import_types76.NodeType.RouteNode) return;
|
|
17042
17646
|
const route = attrs;
|
|
17043
17647
|
if (route.service !== serviceName) return;
|
|
17044
17648
|
out.push({
|
|
@@ -17123,7 +17727,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
17123
17727
|
function createRenderResolveTarget(config) {
|
|
17124
17728
|
return (signal) => {
|
|
17125
17729
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
17126
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
17730
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types76.EdgeType.CALLS };
|
|
17127
17731
|
}
|
|
17128
17732
|
return null;
|
|
17129
17733
|
};
|
|
@@ -17261,21 +17865,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
17261
17865
|
|
|
17262
17866
|
// src/connectors/planetscale/resolve.ts
|
|
17263
17867
|
init_cjs_shims();
|
|
17264
|
-
var
|
|
17868
|
+
var import_types80 = require("@neat.is/types");
|
|
17265
17869
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
17266
17870
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
17267
17871
|
const databaseName = `${config.organization}/${config.database}`;
|
|
17268
17872
|
return (signal, _ctx) => {
|
|
17269
17873
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
17270
|
-
const tableId = (0,
|
|
17874
|
+
const tableId = (0, import_types80.infraId)("sql-table", signal.targetName);
|
|
17271
17875
|
if (graph.hasNode(tableId)) {
|
|
17272
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
17876
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types80.EdgeType.CALLS };
|
|
17273
17877
|
}
|
|
17274
|
-
const providerId = (0,
|
|
17878
|
+
const providerId = (0, import_types80.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
17275
17879
|
return {
|
|
17276
17880
|
targetNodeId: providerId,
|
|
17277
17881
|
serviceName: config.serviceName,
|
|
17278
|
-
edgeType:
|
|
17882
|
+
edgeType: import_types80.EdgeType.CALLS,
|
|
17279
17883
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
17280
17884
|
};
|
|
17281
17885
|
};
|
|
@@ -17540,7 +18144,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
17540
18144
|
|
|
17541
18145
|
// src/connectors/eas/resolve.ts
|
|
17542
18146
|
init_cjs_shims();
|
|
17543
|
-
var
|
|
18147
|
+
var import_types85 = require("@neat.is/types");
|
|
17544
18148
|
var NO_ENV2 = "unknown";
|
|
17545
18149
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
17546
18150
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -17556,8 +18160,8 @@ function configBasenamesForPhase(phase) {
|
|
|
17556
18160
|
function configNodeService(graph, configNodeId) {
|
|
17557
18161
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
17558
18162
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17559
|
-
if (edge.type !==
|
|
17560
|
-
const parsed = (0,
|
|
18163
|
+
if (edge.type !== import_types85.EdgeType.CONFIGURED_BY) continue;
|
|
18164
|
+
const parsed = (0, import_types85.parseFileId)(edge.source);
|
|
17561
18165
|
if (parsed) return parsed.service;
|
|
17562
18166
|
}
|
|
17563
18167
|
return null;
|
|
@@ -17568,7 +18172,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
17568
18172
|
graph.forEachNode((id, attrs) => {
|
|
17569
18173
|
if (scoped) return;
|
|
17570
18174
|
const node = attrs;
|
|
17571
|
-
if (node.type !==
|
|
18175
|
+
if (node.type !== import_types85.NodeType.ConfigNode) return;
|
|
17572
18176
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
17573
18177
|
if (anyMatch === null) anyMatch = id;
|
|
17574
18178
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -17585,13 +18189,13 @@ function createEasResolveTarget(graph) {
|
|
|
17585
18189
|
if (basenames.length > 0) {
|
|
17586
18190
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
17587
18191
|
if (configNodeId) {
|
|
17588
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
18192
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types85.EdgeType.CALLS };
|
|
17589
18193
|
}
|
|
17590
18194
|
}
|
|
17591
18195
|
return {
|
|
17592
18196
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
17593
18197
|
serviceName,
|
|
17594
|
-
edgeType:
|
|
18198
|
+
edgeType: import_types85.EdgeType.CALLS
|
|
17595
18199
|
};
|
|
17596
18200
|
};
|
|
17597
18201
|
}
|
|
@@ -18270,11 +18874,11 @@ function registerRoutes(scope, ctx) {
|
|
|
18270
18874
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
18271
18875
|
const parsed = [];
|
|
18272
18876
|
for (const c of candidates) {
|
|
18273
|
-
const r =
|
|
18877
|
+
const r = import_types88.DivergenceTypeSchema.safeParse(c);
|
|
18274
18878
|
if (!r.success) {
|
|
18275
18879
|
return reply.code(400).send({
|
|
18276
18880
|
error: `unknown divergence type "${c}"`,
|
|
18277
|
-
allowed:
|
|
18881
|
+
allowed: import_types88.DivergenceTypeSchema.options
|
|
18278
18882
|
});
|
|
18279
18883
|
}
|
|
18280
18884
|
parsed.push(r.data);
|
|
@@ -18616,7 +19220,7 @@ function registerRoutes(scope, ctx) {
|
|
|
18616
19220
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
18617
19221
|
let violations = await log.readAll();
|
|
18618
19222
|
if (req.query.severity) {
|
|
18619
|
-
const sev =
|
|
19223
|
+
const sev = import_types88.PolicySeveritySchema.safeParse(req.query.severity);
|
|
18620
19224
|
if (!sev.success) {
|
|
18621
19225
|
return reply.code(400).send({
|
|
18622
19226
|
error: "invalid severity",
|
|
@@ -18655,7 +19259,7 @@ function registerRoutes(scope, ctx) {
|
|
|
18655
19259
|
scope.post("/policies/check", async (req, reply) => {
|
|
18656
19260
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
18657
19261
|
if (!proj) return;
|
|
18658
|
-
const parsed =
|
|
19262
|
+
const parsed = import_types88.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
18659
19263
|
if (!parsed.success) {
|
|
18660
19264
|
return reply.code(400).send({
|
|
18661
19265
|
error: "invalid /policies/check body",
|
|
@@ -18976,8 +19580,8 @@ init_otel_grpc();
|
|
|
18976
19580
|
|
|
18977
19581
|
// src/search.ts
|
|
18978
19582
|
init_cjs_shims();
|
|
18979
|
-
var
|
|
18980
|
-
var
|
|
19583
|
+
var import_node_fs35 = require("fs");
|
|
19584
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
18981
19585
|
var import_node_crypto4 = require("crypto");
|
|
18982
19586
|
var DEFAULT_LIMIT = 10;
|
|
18983
19587
|
var NOMIC_DIM = 768;
|
|
@@ -19131,7 +19735,7 @@ async function pickEmbedder() {
|
|
|
19131
19735
|
}
|
|
19132
19736
|
async function readCache(cachePath) {
|
|
19133
19737
|
try {
|
|
19134
|
-
const raw = await
|
|
19738
|
+
const raw = await import_node_fs35.promises.readFile(cachePath, "utf8");
|
|
19135
19739
|
const parsed = JSON.parse(raw);
|
|
19136
19740
|
if (parsed.version !== 1) return null;
|
|
19137
19741
|
return parsed;
|
|
@@ -19140,8 +19744,8 @@ async function readCache(cachePath) {
|
|
|
19140
19744
|
}
|
|
19141
19745
|
}
|
|
19142
19746
|
async function writeCache(cachePath, cache) {
|
|
19143
|
-
await
|
|
19144
|
-
await
|
|
19747
|
+
await import_node_fs35.promises.mkdir(import_node_path69.default.dirname(cachePath), { recursive: true });
|
|
19748
|
+
await import_node_fs35.promises.writeFile(cachePath, JSON.stringify(cache));
|
|
19145
19749
|
}
|
|
19146
19750
|
var VectorIndex = class {
|
|
19147
19751
|
constructor(embedder, cachePath) {
|
|
@@ -19355,14 +19959,14 @@ async function bootProject(registry, name, scanPath, baseDir) {
|
|
|
19355
19959
|
async function main() {
|
|
19356
19960
|
const baseDirEnv = process.env.NEAT_OUT_DIR;
|
|
19357
19961
|
const legacyOutPath = process.env.NEAT_OUT_PATH;
|
|
19358
|
-
const baseDir = baseDirEnv ?
|
|
19359
|
-
const defaultScanPath =
|
|
19962
|
+
const baseDir = baseDirEnv ? import_node_path70.default.resolve(baseDirEnv) : legacyOutPath ? import_node_path70.default.resolve(import_node_path70.default.dirname(legacyOutPath)) : import_node_path70.default.resolve("./neat-out");
|
|
19963
|
+
const defaultScanPath = import_node_path70.default.resolve(process.env.NEAT_SCAN_PATH ?? "./demo");
|
|
19360
19964
|
const registry = new Projects();
|
|
19361
19965
|
await bootProject(registry, DEFAULT_PROJECT, defaultScanPath, baseDir);
|
|
19362
19966
|
for (const name of parseExtraProjects(process.env.NEAT_PROJECTS)) {
|
|
19363
19967
|
const envKey = `NEAT_PROJECT_SCAN_PATH_${name.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
|
|
19364
19968
|
const projectScan = process.env[envKey];
|
|
19365
|
-
await bootProject(registry, name, projectScan ?
|
|
19969
|
+
await bootProject(registry, name, projectScan ? import_node_path70.default.resolve(projectScan) : void 0, baseDir);
|
|
19366
19970
|
}
|
|
19367
19971
|
const host = process.env.HOST ?? "0.0.0.0";
|
|
19368
19972
|
const port = Number(process.env.PORT ?? 8080);
|