@neat.is/core 0.10.1 → 0.10.3-dev.20260930
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-AWIK6T3G.js → chunk-DLQNMU3R.js} +2 -2
- package/dist/{chunk-E3YFFIHE.js → chunk-LNIVRE4L.js} +801 -569
- package/dist/chunk-LNIVRE4L.js.map +1 -0
- package/dist/cli.cjs +1544 -1081
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +5 -2
- package/dist/cli.d.ts +5 -2
- package/dist/cli.js +457 -224
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +843 -628
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +854 -639
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +712 -525
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-E3YFFIHE.js.map +0 -1
- /package/dist/{chunk-AWIK6T3G.js.map → chunk-DLQNMU3R.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -60,8 +60,8 @@ function mountBearerAuth(app, opts) {
|
|
|
60
60
|
]);
|
|
61
61
|
const publicRead = opts.publicRead === true;
|
|
62
62
|
app.addHook("preHandler", (req, reply, done) => {
|
|
63
|
-
const
|
|
64
|
-
if (exactUnauthPaths.has(
|
|
63
|
+
const path80 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
64
|
+
if (exactUnauthPaths.has(path80) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path80)) {
|
|
65
65
|
done();
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
@@ -193,8 +193,8 @@ function reshapeGrpcRequest(req) {
|
|
|
193
193
|
};
|
|
194
194
|
}
|
|
195
195
|
function resolveProtoRoot() {
|
|
196
|
-
const here =
|
|
197
|
-
return
|
|
196
|
+
const here = import_node_path54.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
197
|
+
return import_node_path54.default.resolve(here, "..", "proto");
|
|
198
198
|
}
|
|
199
199
|
function loadTraceService() {
|
|
200
200
|
const protoRoot = resolveProtoRoot();
|
|
@@ -262,13 +262,13 @@ async function startOtelGrpcReceiver(opts) {
|
|
|
262
262
|
})
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
|
-
var import_node_url,
|
|
265
|
+
var import_node_url, import_node_path54, import_node_crypto2, grpc, protoLoader;
|
|
266
266
|
var init_otel_grpc = __esm({
|
|
267
267
|
"src/otel-grpc.ts"() {
|
|
268
268
|
"use strict";
|
|
269
269
|
init_cjs_shims();
|
|
270
270
|
import_node_url = require("url");
|
|
271
|
-
|
|
271
|
+
import_node_path54 = __toESM(require("path"), 1);
|
|
272
272
|
import_node_crypto2 = require("crypto");
|
|
273
273
|
grpc = __toESM(require("@grpc/grpc-js"), 1);
|
|
274
274
|
protoLoader = __toESM(require("@grpc/proto-loader"), 1);
|
|
@@ -414,8 +414,8 @@ function websocketChannelPathOf(attrs) {
|
|
|
414
414
|
const v = attrs[key];
|
|
415
415
|
if (typeof v === "string" && v.length > 0) {
|
|
416
416
|
const q = v.indexOf("?");
|
|
417
|
-
const
|
|
418
|
-
if (
|
|
417
|
+
const path80 = q === -1 ? v : v.slice(0, q);
|
|
418
|
+
if (path80.length > 0) return path80;
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
421
|
return void 0;
|
|
@@ -477,10 +477,10 @@ function parseOtlpRequest(body) {
|
|
|
477
477
|
return out;
|
|
478
478
|
}
|
|
479
479
|
function loadProtoRoot() {
|
|
480
|
-
const here =
|
|
481
|
-
const protoRoot =
|
|
480
|
+
const here = import_node_path55.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
|
|
481
|
+
const protoRoot = import_node_path55.default.resolve(here, "..", "proto");
|
|
482
482
|
const root = new import_protobufjs.default.Root();
|
|
483
|
-
root.resolvePath = (_origin, target) =>
|
|
483
|
+
root.resolvePath = (_origin, target) => import_node_path55.default.resolve(protoRoot, target);
|
|
484
484
|
root.loadSync(
|
|
485
485
|
"opentelemetry/proto/collector/trace/v1/trace_service.proto",
|
|
486
486
|
{ keepCase: true }
|
|
@@ -766,12 +766,12 @@ function logSpanHandler(span) {
|
|
|
766
766
|
`otel: ${span.service} ${span.name} parent=${parent} status=${status2}${db}`
|
|
767
767
|
);
|
|
768
768
|
}
|
|
769
|
-
var
|
|
769
|
+
var import_node_path55, import_node_url2, import_node_zlib, import_fastify, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody, OTLP_STEP_ATTEMPTS, OTLP_STEP_STRIDE;
|
|
770
770
|
var init_otel = __esm({
|
|
771
771
|
"src/otel.ts"() {
|
|
772
772
|
"use strict";
|
|
773
773
|
init_cjs_shims();
|
|
774
|
-
|
|
774
|
+
import_node_path55 = __toESM(require("path"), 1);
|
|
775
775
|
import_node_url2 = require("url");
|
|
776
776
|
import_node_zlib = __toESM(require("zlib"), 1);
|
|
777
777
|
import_fastify = __toESM(require("fastify"), 1);
|
|
@@ -868,8 +868,8 @@ init_cjs_shims();
|
|
|
868
868
|
|
|
869
869
|
// src/ingest.ts
|
|
870
870
|
init_cjs_shims();
|
|
871
|
-
var
|
|
872
|
-
var
|
|
871
|
+
var import_node_fs8 = require("fs");
|
|
872
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
873
873
|
var sourceMapJs = __toESM(require("source-map-js"), 1);
|
|
874
874
|
|
|
875
875
|
// src/policy.ts
|
|
@@ -1374,19 +1374,19 @@ function confidenceFromMix(edges, now = Date.now()) {
|
|
|
1374
1374
|
function longestIncomingWalk(graph, start, maxDepth) {
|
|
1375
1375
|
let best = { path: [start], edges: [] };
|
|
1376
1376
|
const visited = /* @__PURE__ */ new Set([start]);
|
|
1377
|
-
function step(node,
|
|
1378
|
-
if (
|
|
1379
|
-
best = { path: [...
|
|
1377
|
+
function step(node, path80, edges) {
|
|
1378
|
+
if (path80.length > best.path.length) {
|
|
1379
|
+
best = { path: [...path80], edges: [...edges] };
|
|
1380
1380
|
}
|
|
1381
|
-
if (
|
|
1381
|
+
if (path80.length - 1 >= maxDepth) return;
|
|
1382
1382
|
const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
|
|
1383
1383
|
for (const [srcId, edge] of incoming) {
|
|
1384
1384
|
if (visited.has(srcId)) continue;
|
|
1385
1385
|
visited.add(srcId);
|
|
1386
|
-
|
|
1386
|
+
path80.push(srcId);
|
|
1387
1387
|
edges.push(edge);
|
|
1388
|
-
step(srcId,
|
|
1389
|
-
|
|
1388
|
+
step(srcId, path80, edges);
|
|
1389
|
+
path80.pop();
|
|
1390
1390
|
edges.pop();
|
|
1391
1391
|
visited.delete(srcId);
|
|
1392
1392
|
}
|
|
@@ -1601,20 +1601,20 @@ function dominantFailingCall(graph, serviceId17, visited) {
|
|
|
1601
1601
|
return best;
|
|
1602
1602
|
}
|
|
1603
1603
|
function followFailingCallChain(graph, originServiceId, maxDepth) {
|
|
1604
|
-
const
|
|
1604
|
+
const path80 = [originServiceId];
|
|
1605
1605
|
const edges = [];
|
|
1606
1606
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
1607
1607
|
let current = originServiceId;
|
|
1608
1608
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
1609
1609
|
const hop = dominantFailingCall(graph, current, visited);
|
|
1610
1610
|
if (!hop) break;
|
|
1611
|
-
|
|
1611
|
+
path80.push(hop.nextService);
|
|
1612
1612
|
edges.push(hop.edge);
|
|
1613
1613
|
visited.add(hop.nextService);
|
|
1614
1614
|
current = hop.nextService;
|
|
1615
1615
|
}
|
|
1616
1616
|
if (edges.length === 0) return null;
|
|
1617
|
-
return { path:
|
|
1617
|
+
return { path: path80, edges, culprit: current };
|
|
1618
1618
|
}
|
|
1619
1619
|
function isStaleCallEdge(e) {
|
|
1620
1620
|
return e.type === import_types.EdgeType.CALLS && e.provenance === import_types.Provenance.STALE;
|
|
@@ -1650,26 +1650,26 @@ function dominantStaleCall(graph, serviceId17, visited) {
|
|
|
1650
1650
|
return best;
|
|
1651
1651
|
}
|
|
1652
1652
|
function followStaleCallChain(graph, originServiceId, maxDepth) {
|
|
1653
|
-
const
|
|
1653
|
+
const path80 = [originServiceId];
|
|
1654
1654
|
const edges = [];
|
|
1655
1655
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
1656
1656
|
let current = originServiceId;
|
|
1657
1657
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
1658
1658
|
const hop = dominantStaleCall(graph, current, visited);
|
|
1659
1659
|
if (!hop) break;
|
|
1660
|
-
|
|
1660
|
+
path80.push(hop.nextService);
|
|
1661
1661
|
edges.push(hop.edge);
|
|
1662
1662
|
visited.add(hop.nextService);
|
|
1663
1663
|
current = hop.nextService;
|
|
1664
1664
|
}
|
|
1665
1665
|
if (edges.length === 0) return null;
|
|
1666
|
-
return { path:
|
|
1666
|
+
return { path: path80, edges, culprit: current };
|
|
1667
1667
|
}
|
|
1668
1668
|
function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
1669
1669
|
const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
|
|
1670
1670
|
if (!chain) return null;
|
|
1671
1671
|
const culprit = chain.culprit;
|
|
1672
|
-
const
|
|
1672
|
+
const path80 = [...chain.path];
|
|
1673
1673
|
const edgeProvenances = chain.edges.map((e) => e.provenance);
|
|
1674
1674
|
const baseConfidence = confidenceFromMix(chain.edges);
|
|
1675
1675
|
const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
|
|
@@ -1677,14 +1677,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
1677
1677
|
if (loc) {
|
|
1678
1678
|
let rootCauseNode = culprit;
|
|
1679
1679
|
if (loc.fileNode) {
|
|
1680
|
-
|
|
1680
|
+
path80.push(loc.fileNode);
|
|
1681
1681
|
edgeProvenances.push(import_types.Provenance.OBSERVED);
|
|
1682
1682
|
rootCauseNode = loc.fileNode;
|
|
1683
1683
|
}
|
|
1684
1684
|
return import_types.RootCauseResultSchema.parse({
|
|
1685
1685
|
rootCauseNode,
|
|
1686
1686
|
rootCauseReason: loc.rootCauseReason,
|
|
1687
|
-
traversalPath:
|
|
1687
|
+
traversalPath: path80,
|
|
1688
1688
|
edgeProvenances,
|
|
1689
1689
|
confidence,
|
|
1690
1690
|
...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
|
|
@@ -1696,7 +1696,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
1696
1696
|
return import_types.RootCauseResultSchema.parse({
|
|
1697
1697
|
rootCauseNode: culprit,
|
|
1698
1698
|
rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
|
|
1699
|
-
traversalPath:
|
|
1699
|
+
traversalPath: path80,
|
|
1700
1700
|
edgeProvenances,
|
|
1701
1701
|
confidence,
|
|
1702
1702
|
fixRecommendation: `Inspect ${culpritName}'s failing handler`
|
|
@@ -2349,10 +2349,10 @@ function enrichWithNavigation(graph, errorNodeId, tagged, incidents, now) {
|
|
|
2349
2349
|
traversalPath = staleChain.path;
|
|
2350
2350
|
edgeProvenances = staleChain.edges.map((e) => e.provenance);
|
|
2351
2351
|
} else if (top.node !== seedNode) {
|
|
2352
|
-
const
|
|
2353
|
-
if (
|
|
2354
|
-
traversalPath =
|
|
2355
|
-
edgeProvenances =
|
|
2352
|
+
const path80 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
|
|
2353
|
+
if (path80) {
|
|
2354
|
+
traversalPath = path80.nodes;
|
|
2355
|
+
edgeProvenances = path80.edges.map((e) => e.provenance);
|
|
2356
2356
|
} else {
|
|
2357
2357
|
traversalPath = [errorNodeId, top.node];
|
|
2358
2358
|
edgeProvenances = [top.provenance ?? import_types.Provenance.OBSERVED];
|
|
@@ -2891,7 +2891,7 @@ var import_types8 = require("@neat.is/types");
|
|
|
2891
2891
|
|
|
2892
2892
|
// src/extract/routes.ts
|
|
2893
2893
|
init_cjs_shims();
|
|
2894
|
-
var
|
|
2894
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
2895
2895
|
var import_tree_sitter2 = __toESM(require("tree-sitter"), 1);
|
|
2896
2896
|
var import_tree_sitter_javascript2 = __toESM(require("tree-sitter-javascript"), 1);
|
|
2897
2897
|
var import_tree_sitter_python2 = __toESM(require("tree-sitter-python"), 1);
|
|
@@ -2917,6 +2917,17 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
|
2917
2917
|
"dist",
|
|
2918
2918
|
"build",
|
|
2919
2919
|
".next",
|
|
2920
|
+
// `_next` is the *emitted* half of the pair above — `next build`'s output as
|
|
2921
|
+
// it is served or exported. `.next` was listed and `_next` wasn't, so an
|
|
2922
|
+
// exported bundle walked in as first-party source: minified chunks, one file
|
|
2923
|
+
// per line, hundreds of KB each (#1254).
|
|
2924
|
+
"_next",
|
|
2925
|
+
// Agent scratch space. `.claude/worktrees/` holds a full checkout per agent
|
|
2926
|
+
// session, so walking it re-extracts the whole repo once per worktree — and
|
|
2927
|
+
// pulls in whatever build output those checkouts happen to carry. It is
|
|
2928
|
+
// gitignored in practice, but the file walk doesn't read .gitignore, so the
|
|
2929
|
+
// name has to be listed here.
|
|
2930
|
+
".claude",
|
|
2920
2931
|
// Python virtualenv shapes (issue #344). Walking into a venv pulls in the
|
|
2921
2932
|
// entire CPython stdlib + every installed package as if it were first-party
|
|
2922
2933
|
// service code — 20k+ files, none of which the user wrote. The shape names
|
|
@@ -3148,6 +3159,15 @@ function noteExtractedDropped(edge) {
|
|
|
3148
3159
|
function drainDroppedExtracted() {
|
|
3149
3160
|
return droppedSink.splice(0, droppedSink.length);
|
|
3150
3161
|
}
|
|
3162
|
+
var skippedSink = /* @__PURE__ */ new Map();
|
|
3163
|
+
function noteSkippedFile(file) {
|
|
3164
|
+
if (!skippedSink.has(file.path)) skippedSink.set(file.path, file);
|
|
3165
|
+
}
|
|
3166
|
+
function drainSkippedFiles() {
|
|
3167
|
+
const out = [...skippedSink.values()];
|
|
3168
|
+
skippedSink.clear();
|
|
3169
|
+
return out;
|
|
3170
|
+
}
|
|
3151
3171
|
function isRejectedLogEnabled() {
|
|
3152
3172
|
const raw = process.env.NEAT_EXTRACTED_REJECTED_LOG;
|
|
3153
3173
|
return raw === "1" || raw === "true";
|
|
@@ -3161,14 +3181,91 @@ async function writeRejectedExtracted(drops, rejectedPath) {
|
|
|
3161
3181
|
|
|
3162
3182
|
// src/extract/calls/shared.ts
|
|
3163
3183
|
init_cjs_shims();
|
|
3184
|
+
var import_node_fs6 = require("fs");
|
|
3185
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
3186
|
+
var import_types4 = require("@neat.is/types");
|
|
3187
|
+
|
|
3188
|
+
// src/extract/gitignore.ts
|
|
3189
|
+
init_cjs_shims();
|
|
3164
3190
|
var import_node_fs5 = require("fs");
|
|
3165
3191
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
3166
|
-
var
|
|
3192
|
+
var import_ignore = __toESM(require("ignore"), 1);
|
|
3193
|
+
var LAYER_CACHE = /* @__PURE__ */ new Map();
|
|
3194
|
+
async function layerFor(dir) {
|
|
3195
|
+
const cached = LAYER_CACHE.get(dir);
|
|
3196
|
+
if (cached !== void 0) return cached;
|
|
3197
|
+
let layer = null;
|
|
3198
|
+
try {
|
|
3199
|
+
const raw = await import_node_fs5.promises.readFile(import_node_path5.default.join(dir, ".gitignore"), "utf8");
|
|
3200
|
+
layer = { dir, ig: (0, import_ignore.default)().add(raw) };
|
|
3201
|
+
} catch {
|
|
3202
|
+
layer = null;
|
|
3203
|
+
}
|
|
3204
|
+
LAYER_CACHE.set(dir, layer);
|
|
3205
|
+
return layer;
|
|
3206
|
+
}
|
|
3207
|
+
async function isRepoRoot(dir) {
|
|
3208
|
+
try {
|
|
3209
|
+
await import_node_fs5.promises.stat(import_node_path5.default.join(dir, ".git"));
|
|
3210
|
+
return true;
|
|
3211
|
+
} catch {
|
|
3212
|
+
return false;
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
async function loadIgnoreChain(startDir) {
|
|
3216
|
+
const dirs = [];
|
|
3217
|
+
let current = import_node_path5.default.resolve(startDir);
|
|
3218
|
+
for (; ; ) {
|
|
3219
|
+
dirs.push(current);
|
|
3220
|
+
if (await isRepoRoot(current)) break;
|
|
3221
|
+
const parent = import_node_path5.default.dirname(current);
|
|
3222
|
+
if (parent === current) break;
|
|
3223
|
+
current = parent;
|
|
3224
|
+
}
|
|
3225
|
+
dirs.reverse();
|
|
3226
|
+
const layers = [];
|
|
3227
|
+
for (const dir of dirs) {
|
|
3228
|
+
const layer = await layerFor(dir);
|
|
3229
|
+
if (layer) layers.push(layer);
|
|
3230
|
+
}
|
|
3231
|
+
return layers;
|
|
3232
|
+
}
|
|
3233
|
+
async function extendIgnoreChain(chain, dir) {
|
|
3234
|
+
const layer = await layerFor(import_node_path5.default.resolve(dir));
|
|
3235
|
+
return layer ? [...chain, layer] : chain;
|
|
3236
|
+
}
|
|
3237
|
+
function isIgnored(chain, fullPath, isDir) {
|
|
3238
|
+
return decide(chain, fullPath, isDir).ignored;
|
|
3239
|
+
}
|
|
3240
|
+
function decide(chain, fullPath, isDir) {
|
|
3241
|
+
if (chain.length === 0) return { ignored: false, subtree: chain };
|
|
3242
|
+
const abs = import_node_path5.default.resolve(fullPath);
|
|
3243
|
+
let ignored = false;
|
|
3244
|
+
let unignoredAt = -1;
|
|
3245
|
+
for (let i = 0; i < chain.length; i++) {
|
|
3246
|
+
const layer = chain[i];
|
|
3247
|
+
const rel = import_node_path5.default.relative(layer.dir, abs);
|
|
3248
|
+
if (!rel || rel.startsWith("..") || import_node_path5.default.isAbsolute(rel)) continue;
|
|
3249
|
+
const candidate = rel.split(import_node_path5.default.sep).join("/") + (isDir ? "/" : "");
|
|
3250
|
+
const result = layer.ig.test(candidate);
|
|
3251
|
+
if (result.ignored) ignored = true;
|
|
3252
|
+
else if (result.unignored) {
|
|
3253
|
+
ignored = false;
|
|
3254
|
+
unignoredAt = i;
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
return {
|
|
3258
|
+
ignored,
|
|
3259
|
+
subtree: unignoredAt >= 0 ? chain.slice(unignoredAt) : chain
|
|
3260
|
+
};
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
// src/extract/calls/shared.ts
|
|
3167
3264
|
function buildServiceHostIndex(services) {
|
|
3168
3265
|
const knownHosts = /* @__PURE__ */ new Set();
|
|
3169
3266
|
const hostToNodeId = /* @__PURE__ */ new Map();
|
|
3170
3267
|
for (const service of services) {
|
|
3171
|
-
const base =
|
|
3268
|
+
const base = import_node_path6.default.basename(service.dir);
|
|
3172
3269
|
knownHosts.add(base);
|
|
3173
3270
|
knownHosts.add(service.pkg.name);
|
|
3174
3271
|
hostToNodeId.set(base, service.node.id);
|
|
@@ -3177,33 +3274,62 @@ function buildServiceHostIndex(services) {
|
|
|
3177
3274
|
return { knownHosts, hostToNodeId };
|
|
3178
3275
|
}
|
|
3179
3276
|
async function walkSourceFiles(dir, excludeDirs = []) {
|
|
3180
|
-
const excluded = new Set(excludeDirs.map((d) =>
|
|
3277
|
+
const excluded = new Set(excludeDirs.map((d) => import_node_path6.default.resolve(d)));
|
|
3181
3278
|
const out = [];
|
|
3182
|
-
|
|
3183
|
-
|
|
3279
|
+
const rootChain = await loadIgnoreChain(dir);
|
|
3280
|
+
async function walk11(current, inherited) {
|
|
3281
|
+
const entries = await import_node_fs6.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
3282
|
+
const chain = entries.some((e) => e.isFile() && e.name === ".gitignore") ? await extendIgnoreChain(inherited, current) : inherited;
|
|
3184
3283
|
for (const entry of entries) {
|
|
3185
|
-
const full =
|
|
3284
|
+
const full = import_node_path6.default.join(current, entry.name);
|
|
3186
3285
|
if (entry.isDirectory()) {
|
|
3187
3286
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
3188
|
-
if (excluded.has(
|
|
3287
|
+
if (excluded.has(import_node_path6.default.resolve(full))) continue;
|
|
3288
|
+
const verdict = decide(chain, full, true);
|
|
3289
|
+
if (verdict.ignored) continue;
|
|
3189
3290
|
if (await isPythonVenvDir(full)) continue;
|
|
3190
|
-
await walk11(full);
|
|
3191
|
-
} else if (entry.isFile() && SERVICE_FILE_EXTENSIONS.has(
|
|
3291
|
+
await walk11(full, verdict.subtree);
|
|
3292
|
+
} else if (entry.isFile() && SERVICE_FILE_EXTENSIONS.has(import_node_path6.default.extname(entry.name)) && // Skip NEAT's own generated `otel-init.*` bootstrap — extracting it
|
|
3192
3293
|
// would attribute our instrumentation imports to the user's service.
|
|
3193
|
-
!isNeatAuthoredSourceFile(entry.name)) {
|
|
3294
|
+
!isNeatAuthoredSourceFile(entry.name) && !isIgnored(chain, full, false)) {
|
|
3194
3295
|
out.push(full);
|
|
3195
3296
|
}
|
|
3196
3297
|
}
|
|
3197
3298
|
}
|
|
3198
|
-
await walk11(dir);
|
|
3299
|
+
await walk11(dir, rootChain.filter((l) => import_node_path6.default.resolve(l.dir) !== import_node_path6.default.resolve(dir)));
|
|
3199
3300
|
return out;
|
|
3200
3301
|
}
|
|
3302
|
+
var MINIFIED_LINE_CHARS = 5e3;
|
|
3303
|
+
function hasMinifiedName(filePath) {
|
|
3304
|
+
return /\.min\.(js|mjs|cjs|jsx|ts|tsx)$/i.test(filePath);
|
|
3305
|
+
}
|
|
3306
|
+
function isMinifiedSource(filePath, content) {
|
|
3307
|
+
if (hasMinifiedName(filePath)) return { minified: true, detail: "named *.min.js" };
|
|
3308
|
+
let longest = 0;
|
|
3309
|
+
let start = 0;
|
|
3310
|
+
for (; ; ) {
|
|
3311
|
+
const nl = content.indexOf("\n", start);
|
|
3312
|
+
const len = (nl === -1 ? content.length : nl) - start;
|
|
3313
|
+
if (len > longest) longest = len;
|
|
3314
|
+
if (nl === -1) break;
|
|
3315
|
+
start = nl + 1;
|
|
3316
|
+
}
|
|
3317
|
+
if (longest > MINIFIED_LINE_CHARS) {
|
|
3318
|
+
return { minified: true, detail: `longest line ${longest} chars` };
|
|
3319
|
+
}
|
|
3320
|
+
return { minified: false, detail: "" };
|
|
3321
|
+
}
|
|
3201
3322
|
async function loadSourceFiles(dir, excludeDirs = []) {
|
|
3202
3323
|
const paths = await walkSourceFiles(dir, excludeDirs);
|
|
3203
3324
|
const out = [];
|
|
3204
3325
|
for (const p of paths) {
|
|
3205
3326
|
try {
|
|
3206
|
-
const content = await
|
|
3327
|
+
const content = await import_node_fs6.promises.readFile(p, "utf8");
|
|
3328
|
+
const verdict = isMinifiedSource(p, content);
|
|
3329
|
+
if (verdict.minified) {
|
|
3330
|
+
noteSkippedFile({ path: p, reason: "minified", detail: verdict.detail });
|
|
3331
|
+
continue;
|
|
3332
|
+
}
|
|
3207
3333
|
out.push({ path: p, content });
|
|
3208
3334
|
} catch {
|
|
3209
3335
|
}
|
|
@@ -3215,15 +3341,18 @@ function lineOf(text, needle) {
|
|
|
3215
3341
|
if (idx < 0) return 1;
|
|
3216
3342
|
return text.slice(0, idx).split("\n").length;
|
|
3217
3343
|
}
|
|
3344
|
+
var SNIPPET_MAX_CHARS = 120;
|
|
3218
3345
|
function snippet(text, line) {
|
|
3219
3346
|
const lines = text.split("\n");
|
|
3220
|
-
|
|
3347
|
+
const raw = (lines[line - 1] ?? "").trim();
|
|
3348
|
+
if (raw.length <= SNIPPET_MAX_CHARS) return raw;
|
|
3349
|
+
return `${raw.slice(0, SNIPPET_MAX_CHARS)}\u2026 (+${raw.length - SNIPPET_MAX_CHARS} chars)`;
|
|
3221
3350
|
}
|
|
3222
3351
|
function toPosix(p) {
|
|
3223
3352
|
return p.split("\\").join("/");
|
|
3224
3353
|
}
|
|
3225
3354
|
function languageForPath(relPath) {
|
|
3226
|
-
switch (
|
|
3355
|
+
switch (import_node_path6.default.extname(relPath).toLowerCase()) {
|
|
3227
3356
|
case ".py":
|
|
3228
3357
|
return "python";
|
|
3229
3358
|
case ".go":
|
|
@@ -3297,8 +3426,8 @@ function ensureFileNode(graph, serviceName, serviceNodeId, relPath) {
|
|
|
3297
3426
|
|
|
3298
3427
|
// src/extract/imports.ts
|
|
3299
3428
|
init_cjs_shims();
|
|
3300
|
-
var
|
|
3301
|
-
var
|
|
3429
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
3430
|
+
var import_node_fs7 = require("fs");
|
|
3302
3431
|
var import_tree_sitter = __toESM(require("tree-sitter"), 1);
|
|
3303
3432
|
var import_tree_sitter_javascript = __toESM(require("tree-sitter-javascript"), 1);
|
|
3304
3433
|
var import_tree_sitter_python = __toESM(require("tree-sitter-python"), 1);
|
|
@@ -3443,15 +3572,15 @@ function collectPyImports(node, out) {
|
|
|
3443
3572
|
}
|
|
3444
3573
|
async function fileExists(p) {
|
|
3445
3574
|
try {
|
|
3446
|
-
await
|
|
3575
|
+
await import_node_fs7.promises.access(p);
|
|
3447
3576
|
return true;
|
|
3448
3577
|
} catch {
|
|
3449
3578
|
return false;
|
|
3450
3579
|
}
|
|
3451
3580
|
}
|
|
3452
3581
|
function isWithinServiceDir(candidate, serviceDir) {
|
|
3453
|
-
const rel =
|
|
3454
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
3582
|
+
const rel = import_node_path7.default.relative(serviceDir, candidate);
|
|
3583
|
+
return rel !== "" && !rel.startsWith("..") && !import_node_path7.default.isAbsolute(rel);
|
|
3455
3584
|
}
|
|
3456
3585
|
var JS_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
3457
3586
|
var JS_INDEX_FILES = JS_EXTENSIONS.map((ext) => `index${ext}`);
|
|
@@ -3459,22 +3588,22 @@ async function firstExistingCandidate(base, serviceDir) {
|
|
|
3459
3588
|
for (const ext of JS_EXTENSIONS) {
|
|
3460
3589
|
const candidate = base + ext;
|
|
3461
3590
|
if (isWithinServiceDir(candidate, serviceDir) && await fileExists(candidate)) {
|
|
3462
|
-
return toPosix(
|
|
3591
|
+
return toPosix(import_node_path7.default.relative(serviceDir, candidate));
|
|
3463
3592
|
}
|
|
3464
3593
|
}
|
|
3465
3594
|
for (const indexFile of JS_INDEX_FILES) {
|
|
3466
|
-
const candidate =
|
|
3595
|
+
const candidate = import_node_path7.default.join(base, indexFile);
|
|
3467
3596
|
if (isWithinServiceDir(candidate, serviceDir) && await fileExists(candidate)) {
|
|
3468
|
-
return toPosix(
|
|
3597
|
+
return toPosix(import_node_path7.default.relative(serviceDir, candidate));
|
|
3469
3598
|
}
|
|
3470
3599
|
}
|
|
3471
3600
|
return null;
|
|
3472
3601
|
}
|
|
3473
3602
|
async function loadTsPathConfig(serviceDir) {
|
|
3474
|
-
const tsconfigPath =
|
|
3603
|
+
const tsconfigPath = import_node_path7.default.join(serviceDir, "tsconfig.json");
|
|
3475
3604
|
let raw;
|
|
3476
3605
|
try {
|
|
3477
|
-
raw = await
|
|
3606
|
+
raw = await import_node_fs7.promises.readFile(tsconfigPath, "utf8");
|
|
3478
3607
|
} catch {
|
|
3479
3608
|
return null;
|
|
3480
3609
|
}
|
|
@@ -3483,7 +3612,7 @@ async function loadTsPathConfig(serviceDir) {
|
|
|
3483
3612
|
const paths = parsed.compilerOptions?.paths;
|
|
3484
3613
|
if (!paths || Object.keys(paths).length === 0) return null;
|
|
3485
3614
|
const baseUrl = parsed.compilerOptions?.baseUrl;
|
|
3486
|
-
return { paths, baseDir: baseUrl ?
|
|
3615
|
+
return { paths, baseDir: baseUrl ? import_node_path7.default.resolve(serviceDir, baseUrl) : serviceDir };
|
|
3487
3616
|
} catch (err) {
|
|
3488
3617
|
recordExtractionError("import alias resolution", tsconfigPath, err);
|
|
3489
3618
|
return null;
|
|
@@ -3501,11 +3630,11 @@ async function resolveTsAlias(specifier, config, serviceDir) {
|
|
|
3501
3630
|
if (suffix === null) continue;
|
|
3502
3631
|
for (const target of targets) {
|
|
3503
3632
|
const targetBase = target.endsWith("/*") ? target.slice(0, -2) : target.replace(/\*$/, "");
|
|
3504
|
-
const resolvedBase =
|
|
3633
|
+
const resolvedBase = import_node_path7.default.resolve(config.baseDir, targetBase, suffix);
|
|
3505
3634
|
const hit = await firstExistingCandidate(resolvedBase, serviceDir);
|
|
3506
3635
|
if (hit) return hit;
|
|
3507
3636
|
if (isWithinServiceDir(resolvedBase, serviceDir) && await fileExists(resolvedBase)) {
|
|
3508
|
-
return toPosix(
|
|
3637
|
+
return toPosix(import_node_path7.default.relative(serviceDir, resolvedBase));
|
|
3509
3638
|
}
|
|
3510
3639
|
}
|
|
3511
3640
|
}
|
|
@@ -3514,18 +3643,18 @@ async function resolveTsAlias(specifier, config, serviceDir) {
|
|
|
3514
3643
|
async function resolveJsImport(specifier, importerDir, serviceDir, tsPaths) {
|
|
3515
3644
|
if (!specifier) return null;
|
|
3516
3645
|
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
3517
|
-
const base =
|
|
3518
|
-
const ext =
|
|
3646
|
+
const base = import_node_path7.default.resolve(importerDir, specifier);
|
|
3647
|
+
const ext = import_node_path7.default.extname(specifier);
|
|
3519
3648
|
if (ext) {
|
|
3520
3649
|
if (ext === ".js" || ext === ".jsx") {
|
|
3521
3650
|
const tsExt = ext === ".jsx" ? ".tsx" : ".ts";
|
|
3522
3651
|
const tsSibling = base.slice(0, -ext.length) + tsExt;
|
|
3523
3652
|
if (isWithinServiceDir(tsSibling, serviceDir) && await fileExists(tsSibling)) {
|
|
3524
|
-
return toPosix(
|
|
3653
|
+
return toPosix(import_node_path7.default.relative(serviceDir, tsSibling));
|
|
3525
3654
|
}
|
|
3526
3655
|
}
|
|
3527
3656
|
if (isWithinServiceDir(base, serviceDir) && await fileExists(base)) {
|
|
3528
|
-
return toPosix(
|
|
3657
|
+
return toPosix(import_node_path7.default.relative(serviceDir, base));
|
|
3529
3658
|
}
|
|
3530
3659
|
if (!JS_EXTENSIONS.includes(ext)) {
|
|
3531
3660
|
return firstExistingCandidate(base, serviceDir);
|
|
@@ -3540,30 +3669,30 @@ async function resolveJsImport(specifier, importerDir, serviceDir, tsPaths) {
|
|
|
3540
3669
|
async function resolvePyImport(imp, importerPath, serviceDir) {
|
|
3541
3670
|
let baseDir;
|
|
3542
3671
|
if (imp.level > 0) {
|
|
3543
|
-
baseDir =
|
|
3544
|
-
for (let i = 1; i < imp.level; i++) baseDir =
|
|
3672
|
+
baseDir = import_node_path7.default.dirname(importerPath);
|
|
3673
|
+
for (let i = 1; i < imp.level; i++) baseDir = import_node_path7.default.dirname(baseDir);
|
|
3545
3674
|
} else {
|
|
3546
3675
|
baseDir = serviceDir;
|
|
3547
3676
|
}
|
|
3548
|
-
const moduleBase = imp.modulePath ?
|
|
3677
|
+
const moduleBase = imp.modulePath ? import_node_path7.default.join(baseDir, imp.modulePath.split(".").join("/")) : baseDir;
|
|
3549
3678
|
const resolved = /* @__PURE__ */ new Set();
|
|
3550
3679
|
let needModuleFile = imp.names.length === 0;
|
|
3551
3680
|
for (const name of imp.names) {
|
|
3552
|
-
const submoduleFile =
|
|
3553
|
-
const subpackageInit =
|
|
3681
|
+
const submoduleFile = import_node_path7.default.join(moduleBase, `${name}.py`);
|
|
3682
|
+
const subpackageInit = import_node_path7.default.join(moduleBase, name, "__init__.py");
|
|
3554
3683
|
if (isWithinServiceDir(submoduleFile, serviceDir) && await fileExists(submoduleFile)) {
|
|
3555
|
-
resolved.add(toPosix(
|
|
3684
|
+
resolved.add(toPosix(import_node_path7.default.relative(serviceDir, submoduleFile)));
|
|
3556
3685
|
} else if (isWithinServiceDir(subpackageInit, serviceDir) && await fileExists(subpackageInit)) {
|
|
3557
|
-
resolved.add(toPosix(
|
|
3686
|
+
resolved.add(toPosix(import_node_path7.default.relative(serviceDir, subpackageInit)));
|
|
3558
3687
|
} else {
|
|
3559
3688
|
needModuleFile = true;
|
|
3560
3689
|
}
|
|
3561
3690
|
}
|
|
3562
3691
|
if (needModuleFile) {
|
|
3563
|
-
const moduleFileCandidates = imp.modulePath ? [`${moduleBase}.py`,
|
|
3692
|
+
const moduleFileCandidates = imp.modulePath ? [`${moduleBase}.py`, import_node_path7.default.join(moduleBase, "__init__.py")] : [import_node_path7.default.join(moduleBase, "__init__.py")];
|
|
3564
3693
|
for (const candidate of moduleFileCandidates) {
|
|
3565
3694
|
if (isWithinServiceDir(candidate, serviceDir) && await fileExists(candidate)) {
|
|
3566
|
-
resolved.add(toPosix(
|
|
3695
|
+
resolved.add(toPosix(import_node_path7.default.relative(serviceDir, candidate)));
|
|
3567
3696
|
break;
|
|
3568
3697
|
}
|
|
3569
3698
|
}
|
|
@@ -3573,11 +3702,11 @@ async function resolvePyImport(imp, importerPath, serviceDir) {
|
|
|
3573
3702
|
async function resolveGoImport(specifier, modulePath, serviceDir) {
|
|
3574
3703
|
if (specifier !== modulePath && !specifier.startsWith(`${modulePath}/`)) return null;
|
|
3575
3704
|
const suffix = specifier === modulePath ? "" : specifier.slice(modulePath.length + 1);
|
|
3576
|
-
const dir =
|
|
3577
|
-
const entries = await
|
|
3578
|
-
const candidates = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".go") && !entry.name.endsWith("_test.go")).map((entry) =>
|
|
3705
|
+
const dir = import_node_path7.default.join(serviceDir, suffix);
|
|
3706
|
+
const entries = await import_node_fs7.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
3707
|
+
const candidates = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".go") && !entry.name.endsWith("_test.go")).map((entry) => import_node_path7.default.join(dir, entry.name));
|
|
3579
3708
|
if (candidates.length !== 1) return null;
|
|
3580
|
-
return toPosix(
|
|
3709
|
+
return toPosix(import_node_path7.default.relative(serviceDir, candidates[0]));
|
|
3581
3710
|
}
|
|
3582
3711
|
function emitImportEdge(graph, serviceName, importerFileId, importerRelPath, importeeRelPath, line, snippet2) {
|
|
3583
3712
|
const importeeFileId = (0, import_types5.fileId)(serviceName, importeeRelPath);
|
|
@@ -3607,12 +3736,12 @@ async function addImports(graph, services) {
|
|
|
3607
3736
|
const files = await loadSourceFiles(service.dir, service.excludeDirs);
|
|
3608
3737
|
for (const file of files) {
|
|
3609
3738
|
if (isTestPath(file.path)) continue;
|
|
3610
|
-
const relFile = toPosix(
|
|
3739
|
+
const relFile = toPosix(import_node_path7.default.relative(service.dir, file.path));
|
|
3611
3740
|
const importerFileId = (0, import_types5.fileId)(service.pkg.name, relFile);
|
|
3612
|
-
const isPython =
|
|
3613
|
-
const isGo =
|
|
3614
|
-
if (
|
|
3615
|
-
if (
|
|
3741
|
+
const isPython = import_node_path7.default.extname(file.path) === ".py";
|
|
3742
|
+
const isGo = import_node_path7.default.extname(file.path) === ".go";
|
|
3743
|
+
if (import_node_path7.default.extname(file.path) === ".rb") continue;
|
|
3744
|
+
if (import_node_path7.default.extname(file.path) === ".php") continue;
|
|
3616
3745
|
if (isGo) {
|
|
3617
3746
|
let goImports = [];
|
|
3618
3747
|
try {
|
|
@@ -3622,7 +3751,7 @@ async function addImports(graph, services) {
|
|
|
3622
3751
|
recordExtractionError("import extraction", file.path, err);
|
|
3623
3752
|
continue;
|
|
3624
3753
|
}
|
|
3625
|
-
const goMod = await
|
|
3754
|
+
const goMod = await import_node_fs7.promises.readFile(import_node_path7.default.join(service.dir, "go.mod"), "utf8").catch(() => "");
|
|
3626
3755
|
const modulePath = goMod.match(/^\s*module\s+(\S+)\s*$/m)?.[1];
|
|
3627
3756
|
if (!modulePath) continue;
|
|
3628
3757
|
for (const imp of goImports) {
|
|
@@ -3666,7 +3795,7 @@ async function addImports(graph, services) {
|
|
|
3666
3795
|
continue;
|
|
3667
3796
|
}
|
|
3668
3797
|
for (const imp of jsImports) {
|
|
3669
|
-
const resolved = await resolveJsImport(imp.specifier,
|
|
3798
|
+
const resolved = await resolveJsImport(imp.specifier, import_node_path7.default.dirname(file.path), service.dir, tsPaths);
|
|
3670
3799
|
if (!resolved) continue;
|
|
3671
3800
|
edgesAdded += emitImportEdge(
|
|
3672
3801
|
graph,
|
|
@@ -3791,8 +3920,8 @@ function chiRoutesFromSource(source, parser) {
|
|
|
3791
3920
|
chiWalk(tree.rootNode, "", out);
|
|
3792
3921
|
return out;
|
|
3793
3922
|
}
|
|
3794
|
-
function stripChiRegex(
|
|
3795
|
-
return
|
|
3923
|
+
function stripChiRegex(path80) {
|
|
3924
|
+
return path80.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
|
|
3796
3925
|
}
|
|
3797
3926
|
function chiWalk(node, prefix, out) {
|
|
3798
3927
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
@@ -4132,7 +4261,7 @@ function isNextPagesApiFile(relFile) {
|
|
|
4132
4261
|
if (pagesIdx === -1 || segs[pagesIdx + 1] !== "api") return false;
|
|
4133
4262
|
const base = segs[segs.length - 1] ?? "";
|
|
4134
4263
|
if (/^_(app|document|middleware)\./.test(base)) return false;
|
|
4135
|
-
return JS_ROUTE_EXTENSIONS.has(
|
|
4264
|
+
return JS_ROUTE_EXTENSIONS.has(import_node_path8.default.extname(base));
|
|
4136
4265
|
}
|
|
4137
4266
|
function nextSegment(seg) {
|
|
4138
4267
|
if (seg.startsWith("(") && seg.endsWith(")")) return null;
|
|
@@ -4464,9 +4593,9 @@ function rubyRocketRoute(args) {
|
|
|
4464
4593
|
if (!pair || pair.type !== "pair") continue;
|
|
4465
4594
|
const k = pair.childForFieldName("key");
|
|
4466
4595
|
if (k?.type !== "string") continue;
|
|
4467
|
-
const
|
|
4468
|
-
if (
|
|
4469
|
-
return { path:
|
|
4596
|
+
const path80 = rubyLiteral(k);
|
|
4597
|
+
if (path80 === null) continue;
|
|
4598
|
+
return { path: path80, target: rubyLiteral(pair.childForFieldName("value")) };
|
|
4470
4599
|
}
|
|
4471
4600
|
return null;
|
|
4472
4601
|
}
|
|
@@ -5314,12 +5443,12 @@ async function expressMountPrefixes(files, serviceDir, tsPaths) {
|
|
|
5314
5443
|
const jsParser = makeJsParser2();
|
|
5315
5444
|
const fileInfo = /* @__PURE__ */ new Map();
|
|
5316
5445
|
for (const f of files) {
|
|
5317
|
-
if (!JS_ROUTE_EXTENSIONS.has(
|
|
5446
|
+
if (!JS_ROUTE_EXTENSIONS.has(import_node_path8.default.extname(f.path))) continue;
|
|
5318
5447
|
if (isTestPath(f.path)) continue;
|
|
5319
|
-
const rel = toPosix(
|
|
5448
|
+
const rel = toPosix(import_node_path8.default.relative(serviceDir, f.path));
|
|
5320
5449
|
try {
|
|
5321
5450
|
const tree = parseSource2(jsParser, f.content);
|
|
5322
|
-
fileInfo.set(rel, analyzeExpressFile(tree.rootNode,
|
|
5451
|
+
fileInfo.set(rel, analyzeExpressFile(tree.rootNode, import_node_path8.default.dirname(f.path)));
|
|
5323
5452
|
} catch {
|
|
5324
5453
|
}
|
|
5325
5454
|
}
|
|
@@ -5418,14 +5547,14 @@ async function addRoutes(graph, services) {
|
|
|
5418
5547
|
const mountPrefixes = hasExpress ? await expressMountPrefixes(files, service.dir, await loadTsPathConfig(service.dir)) : /* @__PURE__ */ new Map();
|
|
5419
5548
|
for (const file of files) {
|
|
5420
5549
|
if (isTestPath(file.path)) continue;
|
|
5421
|
-
const ext =
|
|
5550
|
+
const ext = import_node_path8.default.extname(file.path);
|
|
5422
5551
|
const isPy = ext === ".py";
|
|
5423
5552
|
const isGo = ext === ".go";
|
|
5424
5553
|
const isRb = ext === ".rb";
|
|
5425
5554
|
const isPhp = ext === ".php";
|
|
5426
5555
|
const isRs = ext === ".rs";
|
|
5427
5556
|
if (!JS_ROUTE_EXTENSIONS.has(ext) && !isPy && !isGo && !isRb && !isPhp && !isRs) continue;
|
|
5428
|
-
const relFile = toPosix(
|
|
5557
|
+
const relFile = toPosix(import_node_path8.default.relative(service.dir, file.path));
|
|
5429
5558
|
let routes;
|
|
5430
5559
|
try {
|
|
5431
5560
|
if (isPhp) {
|
|
@@ -5933,7 +6062,7 @@ function languageForExt(relPath) {
|
|
|
5933
6062
|
function relPathForRuntimeFile(filepath, serviceNode, scanPath) {
|
|
5934
6063
|
let p = toPosix2(filepath).replace(/^file:\/\//, "");
|
|
5935
6064
|
if (scanPath && scanPath.length > 0) {
|
|
5936
|
-
const absRoot = toPosix2(
|
|
6065
|
+
const absRoot = toPosix2(import_node_path9.default.resolve(scanPath, serviceNode?.repoPath ?? ""));
|
|
5937
6066
|
const anchor = absRoot.endsWith("/") ? absRoot : `${absRoot}/`;
|
|
5938
6067
|
if (p.startsWith(anchor)) return p.slice(anchor.length);
|
|
5939
6068
|
}
|
|
@@ -5961,10 +6090,10 @@ function resolveDistToSrc(absFilepath, line) {
|
|
|
5961
6090
|
entry = null;
|
|
5962
6091
|
const mapPath = `${absFilepath}.map`;
|
|
5963
6092
|
try {
|
|
5964
|
-
if ((0,
|
|
5965
|
-
const raw = JSON.parse((0,
|
|
6093
|
+
if ((0, import_node_fs8.existsSync)(mapPath)) {
|
|
6094
|
+
const raw = JSON.parse((0, import_node_fs8.readFileSync)(mapPath, "utf8"));
|
|
5966
6095
|
const consumer = new sourceMapJs.SourceMapConsumer(raw);
|
|
5967
|
-
entry = { consumer, dir:
|
|
6096
|
+
entry = { consumer, dir: import_node_path9.default.dirname(mapPath) };
|
|
5968
6097
|
}
|
|
5969
6098
|
} catch {
|
|
5970
6099
|
entry = null;
|
|
@@ -5984,7 +6113,7 @@ function resolveDistToSrc(absFilepath, line) {
|
|
|
5984
6113
|
}
|
|
5985
6114
|
if (!pos || !pos.source) return null;
|
|
5986
6115
|
const root = entry.consumer.sourceRoot ?? "";
|
|
5987
|
-
const resolved =
|
|
6116
|
+
const resolved = import_node_path9.default.resolve(entry.dir, root, pos.source);
|
|
5988
6117
|
return { filepath: resolved, ...pos.line ? { line: pos.line } : {} };
|
|
5989
6118
|
} catch {
|
|
5990
6119
|
return null;
|
|
@@ -6528,8 +6657,8 @@ function emitIncidentEvent(project, ev) {
|
|
|
6528
6657
|
});
|
|
6529
6658
|
}
|
|
6530
6659
|
async function appendErrorEvent(ctx, ev) {
|
|
6531
|
-
await
|
|
6532
|
-
await
|
|
6660
|
+
await import_node_fs8.promises.mkdir(import_node_path9.default.dirname(ctx.errorsPath), { recursive: true });
|
|
6661
|
+
await import_node_fs8.promises.appendFile(ctx.errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
6533
6662
|
emitIncidentEvent(ctx.project ?? DEFAULT_PROJECT, ev);
|
|
6534
6663
|
}
|
|
6535
6664
|
async function appendConnectorIncident(errorsPath, input, project) {
|
|
@@ -6544,8 +6673,8 @@ async function appendConnectorIncident(errorsPath, input, project) {
|
|
|
6544
6673
|
...input.attributes && Object.keys(input.attributes).length > 0 ? { attributes: input.attributes } : {},
|
|
6545
6674
|
affectedNode: input.affectedNode
|
|
6546
6675
|
};
|
|
6547
|
-
await
|
|
6548
|
-
await
|
|
6676
|
+
await import_node_fs8.promises.mkdir(import_node_path9.default.dirname(errorsPath), { recursive: true });
|
|
6677
|
+
await import_node_fs8.promises.appendFile(errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
6549
6678
|
if (project) emitIncidentEvent(project, ev);
|
|
6550
6679
|
}
|
|
6551
6680
|
function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
@@ -6667,8 +6796,8 @@ function makeErrorSpanWriter(errorsPath, graph, scanPath, project = DEFAULT_PROJ
|
|
|
6667
6796
|
return async (span) => {
|
|
6668
6797
|
const ev = buildErrorEventForReceiver(span, graph, scanPath);
|
|
6669
6798
|
if (!ev) return;
|
|
6670
|
-
await
|
|
6671
|
-
await
|
|
6799
|
+
await import_node_fs8.promises.mkdir(import_node_path9.default.dirname(errorsPath), { recursive: true });
|
|
6800
|
+
await import_node_fs8.promises.appendFile(errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
6672
6801
|
emitIncidentEvent(project, ev);
|
|
6673
6802
|
};
|
|
6674
6803
|
}
|
|
@@ -7171,13 +7300,13 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7171
7300
|
return { count: events.length, events };
|
|
7172
7301
|
}
|
|
7173
7302
|
async function appendStaleEvents(staleEventsPath, events) {
|
|
7174
|
-
await
|
|
7303
|
+
await import_node_fs8.promises.mkdir(import_node_path9.default.dirname(staleEventsPath), { recursive: true });
|
|
7175
7304
|
const lines = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
7176
|
-
await
|
|
7305
|
+
await import_node_fs8.promises.appendFile(staleEventsPath, lines, "utf8");
|
|
7177
7306
|
}
|
|
7178
7307
|
async function readStaleEvents(staleEventsPath) {
|
|
7179
7308
|
try {
|
|
7180
|
-
const raw = await
|
|
7309
|
+
const raw = await import_node_fs8.promises.readFile(staleEventsPath, "utf8");
|
|
7181
7310
|
return raw.split("\n").filter((line) => line.length > 0).map((line) => JSON.parse(line));
|
|
7182
7311
|
} catch (err) {
|
|
7183
7312
|
if (err.code === "ENOENT") return [];
|
|
@@ -7213,7 +7342,7 @@ function startStalenessLoop(graph, options = {}) {
|
|
|
7213
7342
|
var INCIDENT_READ_MAX_BYTES = 32 * 1024 * 1024;
|
|
7214
7343
|
var INCIDENT_READ_MAX_EVENTS = 5e3;
|
|
7215
7344
|
async function readErrorFileTail(errorsPath, maxBytes) {
|
|
7216
|
-
const handle = await
|
|
7345
|
+
const handle = await import_node_fs8.promises.open(errorsPath, "r");
|
|
7217
7346
|
try {
|
|
7218
7347
|
const { size } = await handle.stat();
|
|
7219
7348
|
if (size <= maxBytes) {
|
|
@@ -7338,16 +7467,16 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7338
7467
|
|
|
7339
7468
|
// src/extract/services.ts
|
|
7340
7469
|
init_cjs_shims();
|
|
7341
|
-
var
|
|
7342
|
-
var
|
|
7343
|
-
var
|
|
7470
|
+
var import_node_fs19 = require("fs");
|
|
7471
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
7472
|
+
var import_ignore2 = __toESM(require("ignore"), 1);
|
|
7344
7473
|
var import_minimatch2 = require("minimatch");
|
|
7345
7474
|
var import_types18 = require("@neat.is/types");
|
|
7346
7475
|
|
|
7347
7476
|
// src/extract/python.ts
|
|
7348
7477
|
init_cjs_shims();
|
|
7349
|
-
var
|
|
7350
|
-
var
|
|
7478
|
+
var import_node_fs9 = require("fs");
|
|
7479
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
7351
7480
|
var import_smol_toml = require("smol-toml");
|
|
7352
7481
|
var REQUIREMENT_LINE = /^\s*([A-Za-z0-9_.-]+)(?:\[[^\]]*\])?\s*(?:(==)\s*([A-Za-z0-9_.+-]+))?/;
|
|
7353
7482
|
function parseRequirementsTxt(content) {
|
|
@@ -7380,25 +7509,25 @@ function depsFromPyProject(pyproject) {
|
|
|
7380
7509
|
return out;
|
|
7381
7510
|
}
|
|
7382
7511
|
async function discoverPythonService(serviceDir) {
|
|
7383
|
-
const pyprojectPath =
|
|
7384
|
-
const requirementsPath =
|
|
7385
|
-
const setupPath =
|
|
7512
|
+
const pyprojectPath = import_node_path10.default.join(serviceDir, "pyproject.toml");
|
|
7513
|
+
const requirementsPath = import_node_path10.default.join(serviceDir, "requirements.txt");
|
|
7514
|
+
const setupPath = import_node_path10.default.join(serviceDir, "setup.py");
|
|
7386
7515
|
const hasPyproject = await exists(pyprojectPath);
|
|
7387
7516
|
const hasRequirements = await exists(requirementsPath);
|
|
7388
7517
|
const hasSetup = await exists(setupPath);
|
|
7389
7518
|
if (!hasPyproject && !hasRequirements && !hasSetup) return null;
|
|
7390
|
-
let name =
|
|
7519
|
+
let name = import_node_path10.default.basename(serviceDir);
|
|
7391
7520
|
let version;
|
|
7392
7521
|
const dependencies = {};
|
|
7393
7522
|
if (hasPyproject) {
|
|
7394
|
-
const raw = await
|
|
7523
|
+
const raw = await import_node_fs9.promises.readFile(pyprojectPath, "utf8");
|
|
7395
7524
|
const pyproject = (0, import_smol_toml.parse)(raw);
|
|
7396
7525
|
name = pyproject.project?.name ?? pyproject.tool?.poetry?.name ?? name;
|
|
7397
7526
|
version = pyproject.project?.version ?? pyproject.tool?.poetry?.version ?? void 0;
|
|
7398
7527
|
Object.assign(dependencies, depsFromPyProject(pyproject));
|
|
7399
7528
|
}
|
|
7400
7529
|
if (hasRequirements) {
|
|
7401
|
-
const raw = await
|
|
7530
|
+
const raw = await import_node_fs9.promises.readFile(requirementsPath, "utf8");
|
|
7402
7531
|
Object.assign(dependencies, parseRequirementsTxt(raw));
|
|
7403
7532
|
}
|
|
7404
7533
|
return { name, version, dependencies };
|
|
@@ -7413,8 +7542,8 @@ function pythonToPackage(service) {
|
|
|
7413
7542
|
|
|
7414
7543
|
// src/extract/go.ts
|
|
7415
7544
|
init_cjs_shims();
|
|
7416
|
-
var
|
|
7417
|
-
var
|
|
7545
|
+
var import_node_fs10 = require("fs");
|
|
7546
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
7418
7547
|
var import_types9 = require("@neat.is/types");
|
|
7419
7548
|
function parseGoMod(source) {
|
|
7420
7549
|
const module2 = source.match(/^\s*module\s+(\S+)\s*$/m)?.[1];
|
|
@@ -7441,7 +7570,7 @@ function goFramework(deps) {
|
|
|
7441
7570
|
async function discoverGoService(scanPath, dir) {
|
|
7442
7571
|
let raw;
|
|
7443
7572
|
try {
|
|
7444
|
-
raw = await
|
|
7573
|
+
raw = await import_node_fs10.promises.readFile(import_node_path11.default.join(dir, "go.mod"), "utf8");
|
|
7445
7574
|
} catch {
|
|
7446
7575
|
return null;
|
|
7447
7576
|
}
|
|
@@ -7456,7 +7585,7 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7456
7585
|
name,
|
|
7457
7586
|
language: "go",
|
|
7458
7587
|
dependencies: mod.dependencies,
|
|
7459
|
-
repoPath:
|
|
7588
|
+
repoPath: import_node_path11.default.relative(scanPath, dir),
|
|
7460
7589
|
...framework ? { framework } : {}
|
|
7461
7590
|
};
|
|
7462
7591
|
return { pkg, dir, node };
|
|
@@ -7464,8 +7593,8 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7464
7593
|
|
|
7465
7594
|
// src/extract/ruby.ts
|
|
7466
7595
|
init_cjs_shims();
|
|
7467
|
-
var
|
|
7468
|
-
var
|
|
7596
|
+
var import_node_fs11 = require("fs");
|
|
7597
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
7469
7598
|
var import_types10 = require("@neat.is/types");
|
|
7470
7599
|
function parseGemfile(source) {
|
|
7471
7600
|
const dependencies = {};
|
|
@@ -7482,12 +7611,12 @@ function parseGemfile(source) {
|
|
|
7482
7611
|
async function discoverRubyService(scanPath, dir) {
|
|
7483
7612
|
let raw;
|
|
7484
7613
|
try {
|
|
7485
|
-
raw = await
|
|
7614
|
+
raw = await import_node_fs11.promises.readFile(import_node_path12.default.join(dir, "Gemfile"), "utf8");
|
|
7486
7615
|
} catch {
|
|
7487
7616
|
return null;
|
|
7488
7617
|
}
|
|
7489
7618
|
const gemfile = parseGemfile(raw);
|
|
7490
|
-
const name =
|
|
7619
|
+
const name = import_node_path12.default.basename(dir);
|
|
7491
7620
|
const pkg = { name, dependencies: gemfile.dependencies };
|
|
7492
7621
|
const node = {
|
|
7493
7622
|
id: (0, import_types10.serviceId)(name),
|
|
@@ -7495,7 +7624,7 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7495
7624
|
name,
|
|
7496
7625
|
language: "ruby",
|
|
7497
7626
|
dependencies: gemfile.dependencies,
|
|
7498
|
-
repoPath:
|
|
7627
|
+
repoPath: import_node_path12.default.relative(scanPath, dir),
|
|
7499
7628
|
...gemfile.dependencies["rails"] !== void 0 ? { framework: "rails" } : {}
|
|
7500
7629
|
};
|
|
7501
7630
|
return { pkg, dir, node };
|
|
@@ -7503,7 +7632,7 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7503
7632
|
|
|
7504
7633
|
// src/extract/php.ts
|
|
7505
7634
|
init_cjs_shims();
|
|
7506
|
-
var
|
|
7635
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
7507
7636
|
var import_types11 = require("@neat.is/types");
|
|
7508
7637
|
function parseComposerJson(composer) {
|
|
7509
7638
|
return {
|
|
@@ -7516,12 +7645,12 @@ function parseComposerJson(composer) {
|
|
|
7516
7645
|
async function discoverPhpService(scanPath, dir) {
|
|
7517
7646
|
let composer;
|
|
7518
7647
|
try {
|
|
7519
|
-
composer = await readJson(
|
|
7648
|
+
composer = await readJson(import_node_path13.default.join(dir, "composer.json"));
|
|
7520
7649
|
} catch {
|
|
7521
7650
|
return null;
|
|
7522
7651
|
}
|
|
7523
7652
|
const { dependencies } = parseComposerJson(composer);
|
|
7524
|
-
const name =
|
|
7653
|
+
const name = import_node_path13.default.basename(dir);
|
|
7525
7654
|
const pkg = { name, dependencies };
|
|
7526
7655
|
const node = {
|
|
7527
7656
|
id: (0, import_types11.serviceId)(name),
|
|
@@ -7529,7 +7658,7 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7529
7658
|
name,
|
|
7530
7659
|
language: "php",
|
|
7531
7660
|
dependencies,
|
|
7532
|
-
repoPath:
|
|
7661
|
+
repoPath: import_node_path13.default.relative(scanPath, dir),
|
|
7533
7662
|
...dependencies["laravel/framework"] !== void 0 ? { framework: "laravel" } : {}
|
|
7534
7663
|
};
|
|
7535
7664
|
return { pkg, dir, node };
|
|
@@ -7537,23 +7666,23 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7537
7666
|
|
|
7538
7667
|
// src/extract/csharp.ts
|
|
7539
7668
|
init_cjs_shims();
|
|
7540
|
-
var
|
|
7541
|
-
var
|
|
7669
|
+
var import_node_fs12 = require("fs");
|
|
7670
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
7542
7671
|
var import_types12 = require("@neat.is/types");
|
|
7543
7672
|
var CSHARP_PROJECT_EXTS = /* @__PURE__ */ new Set([".csproj", ".sln"]);
|
|
7544
7673
|
async function projectFiles(dir) {
|
|
7545
|
-
const entries = await
|
|
7674
|
+
const entries = await import_node_fs12.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
7546
7675
|
const out = [];
|
|
7547
7676
|
for (const entry of entries) {
|
|
7548
7677
|
if (!entry.isFile()) continue;
|
|
7549
|
-
if (CSHARP_PROJECT_EXTS.has(
|
|
7678
|
+
if (CSHARP_PROJECT_EXTS.has(import_node_path14.default.extname(entry.name).toLowerCase())) out.push(entry.name);
|
|
7550
7679
|
}
|
|
7551
7680
|
return out.sort();
|
|
7552
7681
|
}
|
|
7553
7682
|
var NESTED_PROJECT_DIR = "src";
|
|
7554
7683
|
async function resolveProjectDir(dir) {
|
|
7555
7684
|
if ((await projectFiles(dir)).length > 0) return dir;
|
|
7556
|
-
const nested =
|
|
7685
|
+
const nested = import_node_path14.default.join(dir, NESTED_PROJECT_DIR);
|
|
7557
7686
|
if ((await projectFiles(nested)).length > 0) return nested;
|
|
7558
7687
|
return null;
|
|
7559
7688
|
}
|
|
@@ -7578,10 +7707,10 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7578
7707
|
if (projectDir === null) return null;
|
|
7579
7708
|
const projects = await projectFiles(projectDir);
|
|
7580
7709
|
const csproj = projects.find((p) => p.toLowerCase().endsWith(".csproj"));
|
|
7581
|
-
const name = csproj ?
|
|
7710
|
+
const name = csproj ? import_node_path14.default.basename(csproj, import_node_path14.default.extname(csproj)) : import_node_path14.default.basename(dir);
|
|
7582
7711
|
let dependencies = {};
|
|
7583
7712
|
if (csproj) {
|
|
7584
|
-
const raw = await
|
|
7713
|
+
const raw = await import_node_fs12.promises.readFile(import_node_path14.default.join(projectDir, csproj), "utf8").catch(() => "");
|
|
7585
7714
|
dependencies = parseCsproj(raw).dependencies;
|
|
7586
7715
|
}
|
|
7587
7716
|
const pkg = { name, dependencies };
|
|
@@ -7593,20 +7722,20 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7593
7722
|
dependencies,
|
|
7594
7723
|
// Anchor on the directory that holds the project and its `.cs` files, so file
|
|
7595
7724
|
// attribution reaches the source whether it sits at the root or under `src/`.
|
|
7596
|
-
repoPath:
|
|
7725
|
+
repoPath: import_node_path14.default.relative(scanPath, projectDir)
|
|
7597
7726
|
};
|
|
7598
7727
|
return { pkg, dir: projectDir, node };
|
|
7599
7728
|
}
|
|
7600
7729
|
|
|
7601
7730
|
// src/extract/java.ts
|
|
7602
7731
|
init_cjs_shims();
|
|
7603
|
-
var
|
|
7604
|
-
var
|
|
7732
|
+
var import_node_fs13 = require("fs");
|
|
7733
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
7605
7734
|
var import_types13 = require("@neat.is/types");
|
|
7606
7735
|
var JAVA_MANIFESTS = ["pom.xml", "build.gradle", "build.gradle.kts"];
|
|
7607
7736
|
async function hasJavaManifest(dir) {
|
|
7608
7737
|
for (const manifest of JAVA_MANIFESTS) {
|
|
7609
|
-
if (await exists(
|
|
7738
|
+
if (await exists(import_node_path15.default.join(dir, manifest))) return true;
|
|
7610
7739
|
}
|
|
7611
7740
|
return false;
|
|
7612
7741
|
}
|
|
@@ -7641,19 +7770,19 @@ function parseGradle(source) {
|
|
|
7641
7770
|
return { dependencies };
|
|
7642
7771
|
}
|
|
7643
7772
|
async function discoverJavaService(scanPath, dir) {
|
|
7644
|
-
const pomPath =
|
|
7645
|
-
const gradlePath =
|
|
7646
|
-
const gradleKtsPath =
|
|
7773
|
+
const pomPath = import_node_path15.default.join(dir, "pom.xml");
|
|
7774
|
+
const gradlePath = import_node_path15.default.join(dir, "build.gradle");
|
|
7775
|
+
const gradleKtsPath = import_node_path15.default.join(dir, "build.gradle.kts");
|
|
7647
7776
|
let manifest = null;
|
|
7648
7777
|
if (await exists(pomPath)) {
|
|
7649
|
-
manifest = parsePomXml(await
|
|
7778
|
+
manifest = parsePomXml(await import_node_fs13.promises.readFile(pomPath, "utf8").catch(() => ""));
|
|
7650
7779
|
} else if (await exists(gradlePath)) {
|
|
7651
|
-
manifest = parseGradle(await
|
|
7780
|
+
manifest = parseGradle(await import_node_fs13.promises.readFile(gradlePath, "utf8").catch(() => ""));
|
|
7652
7781
|
} else if (await exists(gradleKtsPath)) {
|
|
7653
|
-
manifest = parseGradle(await
|
|
7782
|
+
manifest = parseGradle(await import_node_fs13.promises.readFile(gradleKtsPath, "utf8").catch(() => ""));
|
|
7654
7783
|
}
|
|
7655
7784
|
if (!manifest) return null;
|
|
7656
|
-
const name = manifest.name?.trim() ||
|
|
7785
|
+
const name = manifest.name?.trim() || import_node_path15.default.basename(dir);
|
|
7657
7786
|
const dependencies = manifest.dependencies;
|
|
7658
7787
|
const pkg = { name, dependencies };
|
|
7659
7788
|
const node = {
|
|
@@ -7662,15 +7791,15 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
7662
7791
|
name,
|
|
7663
7792
|
language: "java",
|
|
7664
7793
|
dependencies,
|
|
7665
|
-
repoPath:
|
|
7794
|
+
repoPath: import_node_path15.default.relative(scanPath, dir)
|
|
7666
7795
|
};
|
|
7667
7796
|
return { pkg, dir, node };
|
|
7668
7797
|
}
|
|
7669
7798
|
|
|
7670
7799
|
// src/extract/kotlin.ts
|
|
7671
7800
|
init_cjs_shims();
|
|
7672
|
-
var
|
|
7673
|
-
var
|
|
7801
|
+
var import_node_fs14 = require("fs");
|
|
7802
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
7674
7803
|
var import_types14 = require("@neat.is/types");
|
|
7675
7804
|
var KOTLIN_SOURCE_EXT = ".kt";
|
|
7676
7805
|
var JAVA_SOURCE_EXT = ".java";
|
|
@@ -7680,15 +7809,15 @@ async function dominantJvmSourceLanguage(dir) {
|
|
|
7680
7809
|
let java = 0;
|
|
7681
7810
|
async function recurse(current, depth) {
|
|
7682
7811
|
if (depth > SOURCE_PROBE_MAX_DEPTH) return;
|
|
7683
|
-
const entries = await
|
|
7812
|
+
const entries = await import_node_fs14.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
7684
7813
|
for (const entry of entries) {
|
|
7685
7814
|
if (entry.isDirectory()) {
|
|
7686
7815
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
7687
|
-
await recurse(
|
|
7816
|
+
await recurse(import_node_path16.default.join(current, entry.name), depth + 1);
|
|
7688
7817
|
continue;
|
|
7689
7818
|
}
|
|
7690
7819
|
if (!entry.isFile()) continue;
|
|
7691
|
-
const ext =
|
|
7820
|
+
const ext = import_node_path16.default.extname(entry.name).toLowerCase();
|
|
7692
7821
|
if (ext === KOTLIN_SOURCE_EXT) kt++;
|
|
7693
7822
|
else if (ext === JAVA_SOURCE_EXT) java++;
|
|
7694
7823
|
}
|
|
@@ -7699,17 +7828,17 @@ async function dominantJvmSourceLanguage(dir) {
|
|
|
7699
7828
|
return void 0;
|
|
7700
7829
|
}
|
|
7701
7830
|
async function readJvmManifest(dir) {
|
|
7702
|
-
const pomPath =
|
|
7703
|
-
const gradlePath =
|
|
7704
|
-
const gradleKtsPath =
|
|
7831
|
+
const pomPath = import_node_path16.default.join(dir, JAVA_MANIFESTS[0]);
|
|
7832
|
+
const gradlePath = import_node_path16.default.join(dir, JAVA_MANIFESTS[1]);
|
|
7833
|
+
const gradleKtsPath = import_node_path16.default.join(dir, JAVA_MANIFESTS[2]);
|
|
7705
7834
|
if (await exists(pomPath)) {
|
|
7706
|
-
return parsePomXml(await
|
|
7835
|
+
return parsePomXml(await import_node_fs14.promises.readFile(pomPath, "utf8").catch(() => ""));
|
|
7707
7836
|
}
|
|
7708
7837
|
if (await exists(gradlePath)) {
|
|
7709
|
-
return parseGradle(await
|
|
7838
|
+
return parseGradle(await import_node_fs14.promises.readFile(gradlePath, "utf8").catch(() => ""));
|
|
7710
7839
|
}
|
|
7711
7840
|
if (await exists(gradleKtsPath)) {
|
|
7712
|
-
return parseGradle(await
|
|
7841
|
+
return parseGradle(await import_node_fs14.promises.readFile(gradleKtsPath, "utf8").catch(() => ""));
|
|
7713
7842
|
}
|
|
7714
7843
|
return null;
|
|
7715
7844
|
}
|
|
@@ -7718,7 +7847,7 @@ async function discoverKotlinService(scanPath, dir) {
|
|
|
7718
7847
|
if (await dominantJvmSourceLanguage(dir) !== "kotlin") return null;
|
|
7719
7848
|
const manifest = await readJvmManifest(dir);
|
|
7720
7849
|
if (!manifest) return null;
|
|
7721
|
-
const name = manifest.name?.trim() ||
|
|
7850
|
+
const name = manifest.name?.trim() || import_node_path16.default.basename(dir);
|
|
7722
7851
|
const dependencies = manifest.dependencies;
|
|
7723
7852
|
const pkg = { name, dependencies };
|
|
7724
7853
|
const node = {
|
|
@@ -7727,20 +7856,20 @@ async function discoverKotlinService(scanPath, dir) {
|
|
|
7727
7856
|
name,
|
|
7728
7857
|
language: "kotlin",
|
|
7729
7858
|
dependencies,
|
|
7730
|
-
repoPath:
|
|
7859
|
+
repoPath: import_node_path16.default.relative(scanPath, dir)
|
|
7731
7860
|
};
|
|
7732
7861
|
return { pkg, dir, node };
|
|
7733
7862
|
}
|
|
7734
7863
|
|
|
7735
7864
|
// src/extract/rust.ts
|
|
7736
7865
|
init_cjs_shims();
|
|
7737
|
-
var
|
|
7738
|
-
var
|
|
7866
|
+
var import_node_fs15 = require("fs");
|
|
7867
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
7739
7868
|
var import_smol_toml2 = require("smol-toml");
|
|
7740
7869
|
var import_types15 = require("@neat.is/types");
|
|
7741
7870
|
var CARGO_MANIFEST = "Cargo.toml";
|
|
7742
7871
|
async function hasRustManifest(dir) {
|
|
7743
|
-
return exists(
|
|
7872
|
+
return exists(import_node_path17.default.join(dir, CARGO_MANIFEST));
|
|
7744
7873
|
}
|
|
7745
7874
|
function parseCargoToml(source) {
|
|
7746
7875
|
const dependencies = {};
|
|
@@ -7765,10 +7894,10 @@ function parseCargoToml(source) {
|
|
|
7765
7894
|
return { name, dependencies };
|
|
7766
7895
|
}
|
|
7767
7896
|
async function discoverRustService(scanPath, dir) {
|
|
7768
|
-
const cargoPath =
|
|
7897
|
+
const cargoPath = import_node_path17.default.join(dir, CARGO_MANIFEST);
|
|
7769
7898
|
if (!await exists(cargoPath)) return null;
|
|
7770
|
-
const manifest = parseCargoToml(await
|
|
7771
|
-
const name = manifest.name?.trim() ||
|
|
7899
|
+
const manifest = parseCargoToml(await import_node_fs15.promises.readFile(cargoPath, "utf8").catch(() => ""));
|
|
7900
|
+
const name = manifest.name?.trim() || import_node_path17.default.basename(dir);
|
|
7772
7901
|
const dependencies = manifest.dependencies;
|
|
7773
7902
|
const pkg = { name, dependencies };
|
|
7774
7903
|
const node = {
|
|
@@ -7777,19 +7906,19 @@ async function discoverRustService(scanPath, dir) {
|
|
|
7777
7906
|
name,
|
|
7778
7907
|
language: "rust",
|
|
7779
7908
|
dependencies,
|
|
7780
|
-
repoPath:
|
|
7909
|
+
repoPath: import_node_path17.default.relative(scanPath, dir)
|
|
7781
7910
|
};
|
|
7782
7911
|
return { pkg, dir, node };
|
|
7783
7912
|
}
|
|
7784
7913
|
|
|
7785
7914
|
// src/extract/cpp.ts
|
|
7786
7915
|
init_cjs_shims();
|
|
7787
|
-
var
|
|
7788
|
-
var
|
|
7916
|
+
var import_node_fs16 = require("fs");
|
|
7917
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
7789
7918
|
var import_types16 = require("@neat.is/types");
|
|
7790
7919
|
var CMAKE_MANIFEST = "CMakeLists.txt";
|
|
7791
7920
|
async function hasCppManifest(dir) {
|
|
7792
|
-
return exists(
|
|
7921
|
+
return exists(import_node_path18.default.join(dir, CMAKE_MANIFEST));
|
|
7793
7922
|
}
|
|
7794
7923
|
function parseCMakeProjectName(source) {
|
|
7795
7924
|
const withoutComments = source.replace(/#.*$/gm, "");
|
|
@@ -7797,10 +7926,10 @@ function parseCMakeProjectName(source) {
|
|
|
7797
7926
|
return m?.[1];
|
|
7798
7927
|
}
|
|
7799
7928
|
async function discoverCppService(scanPath, dir) {
|
|
7800
|
-
const cmakePath =
|
|
7929
|
+
const cmakePath = import_node_path18.default.join(dir, CMAKE_MANIFEST);
|
|
7801
7930
|
if (!await exists(cmakePath)) return null;
|
|
7802
|
-
const source = await
|
|
7803
|
-
const name = parseCMakeProjectName(source)?.trim() ||
|
|
7931
|
+
const source = await import_node_fs16.promises.readFile(cmakePath, "utf8").catch(() => "");
|
|
7932
|
+
const name = parseCMakeProjectName(source)?.trim() || import_node_path18.default.basename(dir);
|
|
7804
7933
|
const dependencies = {};
|
|
7805
7934
|
const pkg = { name, dependencies };
|
|
7806
7935
|
const node = {
|
|
@@ -7809,15 +7938,15 @@ async function discoverCppService(scanPath, dir) {
|
|
|
7809
7938
|
name,
|
|
7810
7939
|
language: "cpp",
|
|
7811
7940
|
dependencies,
|
|
7812
|
-
repoPath:
|
|
7941
|
+
repoPath: import_node_path18.default.relative(scanPath, dir)
|
|
7813
7942
|
};
|
|
7814
7943
|
return { pkg, dir, node };
|
|
7815
7944
|
}
|
|
7816
7945
|
|
|
7817
7946
|
// src/extract/dockerfile-service.ts
|
|
7818
7947
|
init_cjs_shims();
|
|
7819
|
-
var
|
|
7820
|
-
var
|
|
7948
|
+
var import_node_fs17 = require("fs");
|
|
7949
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
7821
7950
|
var import_types17 = require("@neat.is/types");
|
|
7822
7951
|
function languageForSourceExt(ext) {
|
|
7823
7952
|
switch (ext) {
|
|
@@ -7859,12 +7988,12 @@ function languageForSourceExt(ext) {
|
|
|
7859
7988
|
}
|
|
7860
7989
|
var LANGUAGE_PRECEDENCE = ["typescript", "javascript", "python", "go", "ruby", "php", "csharp", "java", "kotlin", "rust", "cpp"];
|
|
7861
7990
|
async function inferServiceLanguage(dir) {
|
|
7862
|
-
const entries = await
|
|
7991
|
+
const entries = await import_node_fs17.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
7863
7992
|
const counts = /* @__PURE__ */ new Map();
|
|
7864
7993
|
for (const entry of entries) {
|
|
7865
7994
|
if (!entry.isFile()) continue;
|
|
7866
7995
|
if (isNeatAuthoredSourceFile(entry.name)) continue;
|
|
7867
|
-
const ext =
|
|
7996
|
+
const ext = import_node_path19.default.extname(entry.name).toLowerCase();
|
|
7868
7997
|
if (!SERVICE_FILE_EXTENSIONS.has(ext)) continue;
|
|
7869
7998
|
const lang = languageForSourceExt(ext);
|
|
7870
7999
|
if (!lang) continue;
|
|
@@ -7883,7 +8012,7 @@ async function inferServiceLanguage(dir) {
|
|
|
7883
8012
|
return best;
|
|
7884
8013
|
}
|
|
7885
8014
|
async function hasLanguageManifest(dir) {
|
|
7886
|
-
return await exists(
|
|
8015
|
+
return await exists(import_node_path19.default.join(dir, "package.json")) || await exists(import_node_path19.default.join(dir, "pyproject.toml")) || await exists(import_node_path19.default.join(dir, "requirements.txt")) || await exists(import_node_path19.default.join(dir, "setup.py")) || await exists(import_node_path19.default.join(dir, "go.mod")) || await exists(import_node_path19.default.join(dir, "Gemfile")) || await exists(import_node_path19.default.join(dir, "composer.json")) || // C#'s marker is a glob (`*.csproj` / `*.sln`), so it reads the directory
|
|
7887
8016
|
// rather than probing a fixed filename (ADR-196).
|
|
7888
8017
|
await hasCsharpProject(dir) || // Java (and its JVM sibling Kotlin, ADR-199) key on the same Maven / Gradle
|
|
7889
8018
|
// build manifest (ADR-197), so this one check stands the Dockerfile fallback
|
|
@@ -7893,15 +8022,15 @@ async function hasLanguageManifest(dir) {
|
|
|
7893
8022
|
await hasCppManifest(dir);
|
|
7894
8023
|
}
|
|
7895
8024
|
async function hasDockerfileDeclaredService(dir) {
|
|
7896
|
-
if (!await exists(
|
|
8025
|
+
if (!await exists(import_node_path19.default.join(dir, "Dockerfile"))) return false;
|
|
7897
8026
|
return await inferServiceLanguage(dir) !== null;
|
|
7898
8027
|
}
|
|
7899
8028
|
async function discoverDockerfileService(scanPath, dir) {
|
|
7900
|
-
if (!await exists(
|
|
8029
|
+
if (!await exists(import_node_path19.default.join(dir, "Dockerfile"))) return null;
|
|
7901
8030
|
if (await hasLanguageManifest(dir)) return null;
|
|
7902
8031
|
const language = await inferServiceLanguage(dir);
|
|
7903
8032
|
if (!language) return null;
|
|
7904
|
-
const name =
|
|
8033
|
+
const name = import_node_path19.default.basename(dir);
|
|
7905
8034
|
const pkg = { name, dependencies: {} };
|
|
7906
8035
|
const node = {
|
|
7907
8036
|
id: (0, import_types17.serviceId)(name),
|
|
@@ -7909,24 +8038,24 @@ async function discoverDockerfileService(scanPath, dir) {
|
|
|
7909
8038
|
name,
|
|
7910
8039
|
language,
|
|
7911
8040
|
dependencies: {},
|
|
7912
|
-
repoPath:
|
|
8041
|
+
repoPath: import_node_path19.default.relative(scanPath, dir)
|
|
7913
8042
|
};
|
|
7914
8043
|
return { pkg, dir, node };
|
|
7915
8044
|
}
|
|
7916
8045
|
|
|
7917
8046
|
// src/extract/owners.ts
|
|
7918
8047
|
init_cjs_shims();
|
|
7919
|
-
var
|
|
7920
|
-
var
|
|
8048
|
+
var import_node_fs18 = require("fs");
|
|
8049
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
7921
8050
|
var import_minimatch = require("minimatch");
|
|
7922
8051
|
async function loadCodeowners(scanPath) {
|
|
7923
8052
|
const candidates = [
|
|
7924
|
-
|
|
7925
|
-
|
|
8053
|
+
import_node_path20.default.join(scanPath, "CODEOWNERS"),
|
|
8054
|
+
import_node_path20.default.join(scanPath, ".github", "CODEOWNERS")
|
|
7926
8055
|
];
|
|
7927
8056
|
for (const file of candidates) {
|
|
7928
8057
|
if (await exists(file)) {
|
|
7929
|
-
const raw = await
|
|
8058
|
+
const raw = await import_node_fs18.promises.readFile(file, "utf8");
|
|
7930
8059
|
return parseCodeowners(raw);
|
|
7931
8060
|
}
|
|
7932
8061
|
}
|
|
@@ -7944,7 +8073,7 @@ function parseCodeowners(raw) {
|
|
|
7944
8073
|
return { rules };
|
|
7945
8074
|
}
|
|
7946
8075
|
function matchOwner(file, repoPath) {
|
|
7947
|
-
const normalized = repoPath.split(
|
|
8076
|
+
const normalized = repoPath.split(import_node_path20.default.sep).join("/");
|
|
7948
8077
|
for (const rule of file.rules) {
|
|
7949
8078
|
if (matchesPattern(rule.pattern, normalized)) return rule.owners;
|
|
7950
8079
|
}
|
|
@@ -7960,7 +8089,7 @@ function matchesPattern(rawPattern, repoPath) {
|
|
|
7960
8089
|
return false;
|
|
7961
8090
|
}
|
|
7962
8091
|
async function readPackageJsonAuthor(serviceDir) {
|
|
7963
|
-
const pkgPath =
|
|
8092
|
+
const pkgPath = import_node_path20.default.join(serviceDir, "package.json");
|
|
7964
8093
|
if (!await exists(pkgPath)) return null;
|
|
7965
8094
|
try {
|
|
7966
8095
|
const pkg = await readJson(pkgPath);
|
|
@@ -7997,36 +8126,36 @@ function workspaceGlobs(pkg) {
|
|
|
7997
8126
|
return null;
|
|
7998
8127
|
}
|
|
7999
8128
|
async function hasPythonManifest(dir) {
|
|
8000
|
-
return await exists(
|
|
8129
|
+
return await exists(import_node_path21.default.join(dir, "pyproject.toml")) || await exists(import_node_path21.default.join(dir, "requirements.txt")) || await exists(import_node_path21.default.join(dir, "setup.py"));
|
|
8001
8130
|
}
|
|
8002
8131
|
async function hasGoManifest(dir) {
|
|
8003
|
-
return exists(
|
|
8132
|
+
return exists(import_node_path21.default.join(dir, "go.mod"));
|
|
8004
8133
|
}
|
|
8005
8134
|
async function hasRubyManifest(dir) {
|
|
8006
|
-
return exists(
|
|
8135
|
+
return exists(import_node_path21.default.join(dir, "Gemfile"));
|
|
8007
8136
|
}
|
|
8008
8137
|
async function hasPhpManifest(dir) {
|
|
8009
|
-
return exists(
|
|
8138
|
+
return exists(import_node_path21.default.join(dir, "composer.json"));
|
|
8010
8139
|
}
|
|
8011
8140
|
async function hasCsharpManifest(dir) {
|
|
8012
8141
|
return hasCsharpProject(dir);
|
|
8013
8142
|
}
|
|
8014
8143
|
async function loadGitignore(scanPath) {
|
|
8015
|
-
const gitignorePath =
|
|
8144
|
+
const gitignorePath = import_node_path21.default.join(scanPath, ".gitignore");
|
|
8016
8145
|
if (!await exists(gitignorePath)) return null;
|
|
8017
|
-
const raw = await
|
|
8018
|
-
return (0,
|
|
8146
|
+
const raw = await import_node_fs19.promises.readFile(gitignorePath, "utf8");
|
|
8147
|
+
return (0, import_ignore2.default)().add(raw);
|
|
8019
8148
|
}
|
|
8020
8149
|
async function walkDirs(start, scanPath, options, visit) {
|
|
8021
8150
|
async function recurse(current, depth) {
|
|
8022
8151
|
if (depth > options.maxDepth) return;
|
|
8023
|
-
const entries = await
|
|
8152
|
+
const entries = await import_node_fs19.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
8024
8153
|
for (const entry of entries) {
|
|
8025
8154
|
if (!entry.isDirectory()) continue;
|
|
8026
8155
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
8027
|
-
const child =
|
|
8156
|
+
const child = import_node_path21.default.join(current, entry.name);
|
|
8028
8157
|
if (options.ig) {
|
|
8029
|
-
const rel =
|
|
8158
|
+
const rel = import_node_path21.default.relative(scanPath, child).split(import_node_path21.default.sep).join("/");
|
|
8030
8159
|
if (rel && options.ig.ignores(rel + "/")) continue;
|
|
8031
8160
|
}
|
|
8032
8161
|
if (await isPythonVenvDir(child)) continue;
|
|
@@ -8042,8 +8171,8 @@ async function expandWorkspaceGlobs(scanPath, globs) {
|
|
|
8042
8171
|
for (const raw of globs) {
|
|
8043
8172
|
const pattern = raw.replace(/^\.\//, "");
|
|
8044
8173
|
if (!pattern.includes("*")) {
|
|
8045
|
-
const candidate =
|
|
8046
|
-
if (await exists(
|
|
8174
|
+
const candidate = import_node_path21.default.join(scanPath, pattern);
|
|
8175
|
+
if (await exists(import_node_path21.default.join(candidate, "package.json"))) found.add(candidate);
|
|
8047
8176
|
continue;
|
|
8048
8177
|
}
|
|
8049
8178
|
const segments = pattern.split("/");
|
|
@@ -8052,13 +8181,13 @@ async function expandWorkspaceGlobs(scanPath, globs) {
|
|
|
8052
8181
|
if (seg.includes("*")) break;
|
|
8053
8182
|
staticSegments.push(seg);
|
|
8054
8183
|
}
|
|
8055
|
-
const start =
|
|
8184
|
+
const start = import_node_path21.default.join(scanPath, ...staticSegments);
|
|
8056
8185
|
if (!await exists(start)) continue;
|
|
8057
8186
|
const hasDoubleStar = pattern.includes("**");
|
|
8058
8187
|
const walkDepth = hasDoubleStar ? scanDepth : Math.max(0, segments.length - staticSegments.length - 1);
|
|
8059
8188
|
await walkDirs(start, scanPath, { maxDepth: walkDepth, ig: null }, async (dir) => {
|
|
8060
|
-
const rel =
|
|
8061
|
-
if ((0, import_minimatch2.minimatch)(rel, pattern) && await exists(
|
|
8189
|
+
const rel = import_node_path21.default.relative(scanPath, dir).split(import_node_path21.default.sep).join("/");
|
|
8190
|
+
if ((0, import_minimatch2.minimatch)(rel, pattern) && await exists(import_node_path21.default.join(dir, "package.json"))) {
|
|
8062
8191
|
found.add(dir);
|
|
8063
8192
|
}
|
|
8064
8193
|
});
|
|
@@ -8081,18 +8210,18 @@ function detectJsFramework(pkg) {
|
|
|
8081
8210
|
async function detectJsServiceLanguage(dir, pkg) {
|
|
8082
8211
|
const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
8083
8212
|
if (deps["typescript"] !== void 0) return "typescript";
|
|
8084
|
-
const entries = await
|
|
8213
|
+
const entries = await import_node_fs19.promises.readdir(dir).catch(() => []);
|
|
8085
8214
|
if (entries.some((name) => /^tsconfig(\..+)?\.json$/.test(name))) return "typescript";
|
|
8086
8215
|
return "javascript";
|
|
8087
8216
|
}
|
|
8088
8217
|
async function discoverNodeService(scanPath, dir) {
|
|
8089
|
-
const pkgPath =
|
|
8218
|
+
const pkgPath = import_node_path21.default.join(dir, "package.json");
|
|
8090
8219
|
if (!await exists(pkgPath)) return null;
|
|
8091
8220
|
let pkg;
|
|
8092
8221
|
try {
|
|
8093
8222
|
pkg = await readJson(pkgPath);
|
|
8094
8223
|
} catch (err) {
|
|
8095
|
-
recordExtractionError("services",
|
|
8224
|
+
recordExtractionError("services", import_node_path21.default.relative(scanPath, pkgPath), err);
|
|
8096
8225
|
return null;
|
|
8097
8226
|
}
|
|
8098
8227
|
if (!pkg.name) return null;
|
|
@@ -8105,7 +8234,7 @@ async function discoverNodeService(scanPath, dir) {
|
|
|
8105
8234
|
language,
|
|
8106
8235
|
version: pkg.version,
|
|
8107
8236
|
dependencies: pkg.dependencies ?? {},
|
|
8108
|
-
repoPath:
|
|
8237
|
+
repoPath: import_node_path21.default.relative(scanPath, dir),
|
|
8109
8238
|
...pkg.engines?.node ? { nodeEngine: pkg.engines.node } : {},
|
|
8110
8239
|
...framework ? { framework } : {}
|
|
8111
8240
|
};
|
|
@@ -8122,12 +8251,12 @@ async function discoverPyService(scanPath, dir) {
|
|
|
8122
8251
|
language: "python",
|
|
8123
8252
|
version: py.version,
|
|
8124
8253
|
dependencies: py.dependencies,
|
|
8125
|
-
repoPath:
|
|
8254
|
+
repoPath: import_node_path21.default.relative(scanPath, dir)
|
|
8126
8255
|
};
|
|
8127
8256
|
return { pkg, dir, node };
|
|
8128
8257
|
}
|
|
8129
8258
|
async function discoverServices(scanPath) {
|
|
8130
|
-
const rootPkgPath =
|
|
8259
|
+
const rootPkgPath = import_node_path21.default.join(scanPath, "package.json");
|
|
8131
8260
|
let rootPkg = null;
|
|
8132
8261
|
if (await exists(rootPkgPath)) {
|
|
8133
8262
|
try {
|
|
@@ -8135,7 +8264,7 @@ async function discoverServices(scanPath) {
|
|
|
8135
8264
|
} catch (err) {
|
|
8136
8265
|
recordExtractionError(
|
|
8137
8266
|
"services workspaces",
|
|
8138
|
-
|
|
8267
|
+
import_node_path21.default.relative(scanPath, rootPkgPath),
|
|
8139
8268
|
err
|
|
8140
8269
|
);
|
|
8141
8270
|
}
|
|
@@ -8156,7 +8285,7 @@ async function discoverServices(scanPath) {
|
|
|
8156
8285
|
scanPath,
|
|
8157
8286
|
{ maxDepth: parseScanDepth(), ig },
|
|
8158
8287
|
async (dir) => {
|
|
8159
|
-
if (await exists(
|
|
8288
|
+
if (await exists(import_node_path21.default.join(dir, "package.json"))) {
|
|
8160
8289
|
candidateDirs.push(dir);
|
|
8161
8290
|
} else if (await hasPythonManifest(dir) || await hasGoManifest(dir) || await hasRubyManifest(dir) || await hasPhpManifest(dir) || await hasCsharpManifest(dir) || await hasJavaManifest(dir) || await hasRustManifest(dir) || await hasCppManifest(dir)) {
|
|
8162
8291
|
candidateDirs.push(dir);
|
|
@@ -8184,8 +8313,8 @@ async function discoverServices(scanPath) {
|
|
|
8184
8313
|
seenDirs.add(service.dir);
|
|
8185
8314
|
const existingDir = seen.get(service.node.name);
|
|
8186
8315
|
if (existingDir !== void 0) {
|
|
8187
|
-
const a =
|
|
8188
|
-
const b =
|
|
8316
|
+
const a = import_node_path21.default.relative(scanPath, existingDir) || ".";
|
|
8317
|
+
const b = import_node_path21.default.relative(scanPath, dir) || ".";
|
|
8189
8318
|
console.warn(
|
|
8190
8319
|
`[neat] duplicate package name "${service.node.name}" \u2014 keeping ${a}, ignoring ${b}`
|
|
8191
8320
|
);
|
|
@@ -8199,14 +8328,14 @@ async function discoverServices(scanPath) {
|
|
|
8199
8328
|
const owner = await computeServiceOwner(codeowners, service.node.repoPath, service.dir);
|
|
8200
8329
|
if (owner !== void 0) service.node.owner = owner;
|
|
8201
8330
|
}
|
|
8202
|
-
const resolvedDirs = out.map((s) =>
|
|
8331
|
+
const resolvedDirs = out.map((s) => import_node_path21.default.resolve(s.dir));
|
|
8203
8332
|
for (let i = 0; i < out.length; i++) {
|
|
8204
8333
|
const self = resolvedDirs[i];
|
|
8205
8334
|
const nested = [];
|
|
8206
8335
|
for (let j = 0; j < out.length; j++) {
|
|
8207
8336
|
if (i === j) continue;
|
|
8208
8337
|
const other = resolvedDirs[j];
|
|
8209
|
-
if (other.startsWith(self +
|
|
8338
|
+
if (other.startsWith(self + import_node_path21.default.sep)) nested.push(other);
|
|
8210
8339
|
}
|
|
8211
8340
|
out[i].excludeDirs = nested;
|
|
8212
8341
|
}
|
|
@@ -8233,8 +8362,8 @@ function addServiceNodes(graph, services) {
|
|
|
8233
8362
|
|
|
8234
8363
|
// src/extract/aliases.ts
|
|
8235
8364
|
init_cjs_shims();
|
|
8236
|
-
var
|
|
8237
|
-
var
|
|
8365
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
8366
|
+
var import_node_fs20 = require("fs");
|
|
8238
8367
|
var import_yaml2 = require("yaml");
|
|
8239
8368
|
var import_types19 = require("@neat.is/types");
|
|
8240
8369
|
var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
@@ -8261,14 +8390,14 @@ function indexServicesByName(services) {
|
|
|
8261
8390
|
const map = /* @__PURE__ */ new Map();
|
|
8262
8391
|
for (const s of services) {
|
|
8263
8392
|
map.set(s.node.name, s.node.id);
|
|
8264
|
-
map.set(
|
|
8393
|
+
map.set(import_node_path22.default.basename(s.dir), s.node.id);
|
|
8265
8394
|
}
|
|
8266
8395
|
return map;
|
|
8267
8396
|
}
|
|
8268
8397
|
async function collectComposeAliases(graph, scanPath, serviceIndex) {
|
|
8269
8398
|
let composePath = null;
|
|
8270
8399
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
8271
|
-
const abs =
|
|
8400
|
+
const abs = import_node_path22.default.join(scanPath, name);
|
|
8272
8401
|
if (await exists(abs)) {
|
|
8273
8402
|
composePath = abs;
|
|
8274
8403
|
break;
|
|
@@ -8281,7 +8410,7 @@ async function collectComposeAliases(graph, scanPath, serviceIndex) {
|
|
|
8281
8410
|
} catch (err) {
|
|
8282
8411
|
recordExtractionError(
|
|
8283
8412
|
"aliases compose",
|
|
8284
|
-
|
|
8413
|
+
import_node_path22.default.relative(scanPath, composePath),
|
|
8285
8414
|
err
|
|
8286
8415
|
);
|
|
8287
8416
|
return;
|
|
@@ -8324,11 +8453,11 @@ function parseDockerfileLabels(content) {
|
|
|
8324
8453
|
}
|
|
8325
8454
|
async function collectDockerfileAliases(graph, services) {
|
|
8326
8455
|
for (const service of services) {
|
|
8327
|
-
const dockerfilePath =
|
|
8456
|
+
const dockerfilePath = import_node_path22.default.join(service.dir, "Dockerfile");
|
|
8328
8457
|
if (!await exists(dockerfilePath)) continue;
|
|
8329
8458
|
let content;
|
|
8330
8459
|
try {
|
|
8331
|
-
content = await
|
|
8460
|
+
content = await import_node_fs20.promises.readFile(dockerfilePath, "utf8");
|
|
8332
8461
|
} catch (err) {
|
|
8333
8462
|
recordExtractionError("aliases dockerfile", dockerfilePath, err);
|
|
8334
8463
|
continue;
|
|
@@ -8340,15 +8469,15 @@ async function collectDockerfileAliases(graph, services) {
|
|
|
8340
8469
|
async function walkYamlFiles(start, depth = 0, max = 5) {
|
|
8341
8470
|
if (depth > max) return [];
|
|
8342
8471
|
const out = [];
|
|
8343
|
-
const entries = await
|
|
8472
|
+
const entries = await import_node_fs20.promises.readdir(start, { withFileTypes: true }).catch(() => []);
|
|
8344
8473
|
for (const entry of entries) {
|
|
8345
8474
|
if (entry.isDirectory()) {
|
|
8346
8475
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
8347
|
-
const child =
|
|
8476
|
+
const child = import_node_path22.default.join(start, entry.name);
|
|
8348
8477
|
if (await isPythonVenvDir(child)) continue;
|
|
8349
8478
|
out.push(...await walkYamlFiles(child, depth + 1, max));
|
|
8350
|
-
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(
|
|
8351
|
-
out.push(
|
|
8479
|
+
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path22.default.extname(entry.name))) {
|
|
8480
|
+
out.push(import_node_path22.default.join(start, entry.name));
|
|
8352
8481
|
}
|
|
8353
8482
|
}
|
|
8354
8483
|
return out;
|
|
@@ -8375,7 +8504,7 @@ function k8sServiceTarget(doc, byName) {
|
|
|
8375
8504
|
async function collectK8sAliases(graph, scanPath, serviceIndex) {
|
|
8376
8505
|
const files = await walkYamlFiles(scanPath);
|
|
8377
8506
|
for (const file of files) {
|
|
8378
|
-
const content = await
|
|
8507
|
+
const content = await import_node_fs20.promises.readFile(file, "utf8");
|
|
8379
8508
|
let docs;
|
|
8380
8509
|
try {
|
|
8381
8510
|
docs = (0, import_yaml2.parseAllDocuments)(content).map((d) => d.toJSON());
|
|
@@ -8400,14 +8529,14 @@ async function addServiceAliases(graph, scanPath, services) {
|
|
|
8400
8529
|
|
|
8401
8530
|
// src/extract/files.ts
|
|
8402
8531
|
init_cjs_shims();
|
|
8403
|
-
var
|
|
8532
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
8404
8533
|
async function addFiles(graph, services) {
|
|
8405
8534
|
let nodesAdded = 0;
|
|
8406
8535
|
let edgesAdded = 0;
|
|
8407
8536
|
for (const service of services) {
|
|
8408
8537
|
const filePaths = await walkSourceFiles(service.dir, service.excludeDirs);
|
|
8409
8538
|
for (const filePath of filePaths) {
|
|
8410
|
-
const relPath = toPosix(
|
|
8539
|
+
const relPath = toPosix(import_node_path23.default.relative(service.dir, filePath));
|
|
8411
8540
|
const { nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
8412
8541
|
graph,
|
|
8413
8542
|
service.pkg.name,
|
|
@@ -8423,7 +8552,7 @@ async function addFiles(graph, services) {
|
|
|
8423
8552
|
|
|
8424
8553
|
// src/extract/symbols.ts
|
|
8425
8554
|
init_cjs_shims();
|
|
8426
|
-
var
|
|
8555
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
8427
8556
|
var import_tree_sitter3 = __toESM(require("tree-sitter"), 1);
|
|
8428
8557
|
var import_tree_sitter_javascript3 = __toESM(require("tree-sitter-javascript"), 1);
|
|
8429
8558
|
var import_tree_sitter_typescript = __toESM(require("tree-sitter-typescript"), 1);
|
|
@@ -9175,10 +9304,10 @@ async function addSymbols(graph, services) {
|
|
|
9175
9304
|
for (const service of services) {
|
|
9176
9305
|
const files = await loadSourceFiles(service.dir, service.excludeDirs);
|
|
9177
9306
|
for (const file of files) {
|
|
9178
|
-
const ext =
|
|
9307
|
+
const ext = import_node_path24.default.extname(file.path);
|
|
9179
9308
|
const parser = parserForExt5(ext);
|
|
9180
9309
|
if (!parser) continue;
|
|
9181
|
-
const relPath = toPosix(
|
|
9310
|
+
const relPath = toPosix(import_node_path24.default.relative(service.dir, file.path));
|
|
9182
9311
|
let defs;
|
|
9183
9312
|
try {
|
|
9184
9313
|
const tree = parseSource3(parser, file.content);
|
|
@@ -9238,7 +9367,7 @@ async function addSymbols(graph, services) {
|
|
|
9238
9367
|
|
|
9239
9368
|
// src/extract/symbol-edges.ts
|
|
9240
9369
|
init_cjs_shims();
|
|
9241
|
-
var
|
|
9370
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
9242
9371
|
var import_tree_sitter4 = __toESM(require("tree-sitter"), 1);
|
|
9243
9372
|
var import_types21 = require("@neat.is/types");
|
|
9244
9373
|
function extendsInfo(classHeritage) {
|
|
@@ -9345,10 +9474,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
9345
9474
|
const tsPaths = await loadTsPathConfig(service.dir);
|
|
9346
9475
|
const files = await loadSourceFiles(service.dir, service.excludeDirs);
|
|
9347
9476
|
for (const file of files) {
|
|
9348
|
-
const parser = parserForExt5(
|
|
9477
|
+
const parser = parserForExt5(import_node_path25.default.extname(file.path));
|
|
9349
9478
|
if (!parser) continue;
|
|
9350
|
-
const relPath = toPosix(
|
|
9351
|
-
const fileDir =
|
|
9479
|
+
const relPath = toPosix(import_node_path25.default.relative(service.dir, file.path));
|
|
9480
|
+
const fileDir = import_node_path25.default.dirname(file.path);
|
|
9352
9481
|
let root;
|
|
9353
9482
|
try {
|
|
9354
9483
|
root = parseSource3(parser, file.content).rootNode;
|
|
@@ -9483,7 +9612,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9483
9612
|
|
|
9484
9613
|
// src/extract/actions.ts
|
|
9485
9614
|
init_cjs_shims();
|
|
9486
|
-
var
|
|
9615
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
9487
9616
|
var import_tree_sitter5 = __toESM(require("tree-sitter"), 1);
|
|
9488
9617
|
var import_types22 = require("@neat.is/types");
|
|
9489
9618
|
function stringLiteralText2(node) {
|
|
@@ -9630,9 +9759,9 @@ async function addServerActions(graph, services) {
|
|
|
9630
9759
|
const files = await loadSourceFiles(service.dir, service.excludeDirs);
|
|
9631
9760
|
for (const file of files) {
|
|
9632
9761
|
if (isTestPath(file.path)) continue;
|
|
9633
|
-
const parser = parserForExt5(
|
|
9762
|
+
const parser = parserForExt5(import_node_path26.default.extname(file.path));
|
|
9634
9763
|
if (!parser) continue;
|
|
9635
|
-
const relPath = toPosix(
|
|
9764
|
+
const relPath = toPosix(import_node_path26.default.relative(service.dir, file.path));
|
|
9636
9765
|
let root;
|
|
9637
9766
|
try {
|
|
9638
9767
|
root = parseSource3(parser, file.content).rootNode;
|
|
@@ -9693,10 +9822,10 @@ async function addServerActions(graph, services) {
|
|
|
9693
9822
|
}
|
|
9694
9823
|
for (const file of files) {
|
|
9695
9824
|
if (isTestPath(file.path)) continue;
|
|
9696
|
-
const parser = parserForExt5(
|
|
9825
|
+
const parser = parserForExt5(import_node_path26.default.extname(file.path));
|
|
9697
9826
|
if (!parser) continue;
|
|
9698
|
-
const relPath = toPosix(
|
|
9699
|
-
const fileDir =
|
|
9827
|
+
const relPath = toPosix(import_node_path26.default.relative(service.dir, file.path));
|
|
9828
|
+
const fileDir = import_node_path26.default.dirname(file.path);
|
|
9700
9829
|
let root;
|
|
9701
9830
|
try {
|
|
9702
9831
|
root = parseSource3(parser, file.content).rootNode;
|
|
@@ -9749,14 +9878,14 @@ async function addServerActions(graph, services) {
|
|
|
9749
9878
|
|
|
9750
9879
|
// src/extract/databases/index.ts
|
|
9751
9880
|
init_cjs_shims();
|
|
9752
|
-
var
|
|
9881
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
9753
9882
|
var import_types23 = require("@neat.is/types");
|
|
9754
9883
|
|
|
9755
9884
|
// src/extract/databases/db-config-yaml.ts
|
|
9756
9885
|
init_cjs_shims();
|
|
9757
|
-
var
|
|
9886
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
9758
9887
|
async function parse(serviceDir) {
|
|
9759
|
-
const yamlPath =
|
|
9888
|
+
const yamlPath = import_node_path27.default.join(serviceDir, "db-config.yaml");
|
|
9760
9889
|
if (!await exists(yamlPath)) return [];
|
|
9761
9890
|
const raw = await readYaml(yamlPath);
|
|
9762
9891
|
return [
|
|
@@ -9774,13 +9903,13 @@ var dbConfigYamlParser = { name: "db-config.yaml", parse };
|
|
|
9774
9903
|
|
|
9775
9904
|
// src/extract/databases/dotenv.ts
|
|
9776
9905
|
init_cjs_shims();
|
|
9777
|
-
var
|
|
9778
|
-
var
|
|
9906
|
+
var import_node_fs22 = require("fs");
|
|
9907
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
9779
9908
|
|
|
9780
9909
|
// src/extract/databases/shared.ts
|
|
9781
9910
|
init_cjs_shims();
|
|
9782
|
-
var
|
|
9783
|
-
var
|
|
9911
|
+
var import_node_fs21 = require("fs");
|
|
9912
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
9784
9913
|
function schemeToEngine(scheme) {
|
|
9785
9914
|
const s = scheme.toLowerCase().split("+")[0];
|
|
9786
9915
|
switch (s) {
|
|
@@ -9819,18 +9948,18 @@ function parseConnectionString(url) {
|
|
|
9819
9948
|
}
|
|
9820
9949
|
async function readIfExists(filePath) {
|
|
9821
9950
|
try {
|
|
9822
|
-
return await
|
|
9951
|
+
return await import_node_fs21.promises.readFile(filePath, "utf8");
|
|
9823
9952
|
} catch {
|
|
9824
9953
|
return null;
|
|
9825
9954
|
}
|
|
9826
9955
|
}
|
|
9827
9956
|
async function resolveEnvVar(serviceDir, name) {
|
|
9828
|
-
const entries = await
|
|
9957
|
+
const entries = await import_node_fs21.promises.readdir(serviceDir, { withFileTypes: true }).catch(() => []);
|
|
9829
9958
|
const envNames = entries.filter((e) => e.isFile() && (e.name === ".env" || e.name.startsWith(".env."))).map((e) => e.name);
|
|
9830
9959
|
const rank = (n) => n === ".env.local" ? 0 : n === ".env" ? 1 : 2;
|
|
9831
9960
|
envNames.sort((a, b) => rank(a) - rank(b) || a.localeCompare(b));
|
|
9832
9961
|
for (const fileName of envNames) {
|
|
9833
|
-
const content = await readIfExists(
|
|
9962
|
+
const content = await readIfExists(import_node_path28.default.join(serviceDir, fileName));
|
|
9834
9963
|
if (!content) continue;
|
|
9835
9964
|
for (const line of content.split("\n")) {
|
|
9836
9965
|
const trimmed = line.trim();
|
|
@@ -9849,7 +9978,7 @@ async function resolveEnvVar(serviceDir, name) {
|
|
|
9849
9978
|
}
|
|
9850
9979
|
async function findFirst(serviceDir, candidates) {
|
|
9851
9980
|
for (const rel of candidates) {
|
|
9852
|
-
const abs =
|
|
9981
|
+
const abs = import_node_path28.default.join(serviceDir, rel);
|
|
9853
9982
|
const content = await readIfExists(abs);
|
|
9854
9983
|
if (content !== null) return abs;
|
|
9855
9984
|
}
|
|
@@ -9907,15 +10036,15 @@ function parseDotenvLine(line) {
|
|
|
9907
10036
|
return { key, value };
|
|
9908
10037
|
}
|
|
9909
10038
|
async function parse2(serviceDir) {
|
|
9910
|
-
const entries = await
|
|
10039
|
+
const entries = await import_node_fs22.promises.readdir(serviceDir, { withFileTypes: true }).catch(() => []);
|
|
9911
10040
|
const configs = [];
|
|
9912
10041
|
const seen = /* @__PURE__ */ new Set();
|
|
9913
10042
|
for (const entry of entries) {
|
|
9914
10043
|
if (!entry.isFile()) continue;
|
|
9915
10044
|
const match = isConfigFile(entry.name);
|
|
9916
10045
|
if (!match.match || match.fileType !== "env") continue;
|
|
9917
|
-
const filePath =
|
|
9918
|
-
const content = await
|
|
10046
|
+
const filePath = import_node_path29.default.join(serviceDir, entry.name);
|
|
10047
|
+
const content = await import_node_fs22.promises.readFile(filePath, "utf8");
|
|
9919
10048
|
for (const line of content.split("\n")) {
|
|
9920
10049
|
const parsed = parseDotenvLine(line);
|
|
9921
10050
|
if (!parsed) continue;
|
|
@@ -9934,9 +10063,9 @@ var dotenvParser = { name: ".env", parse: parse2 };
|
|
|
9934
10063
|
|
|
9935
10064
|
// src/extract/databases/prisma.ts
|
|
9936
10065
|
init_cjs_shims();
|
|
9937
|
-
var
|
|
10066
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
9938
10067
|
async function parse3(serviceDir) {
|
|
9939
|
-
const schemaPath =
|
|
10068
|
+
const schemaPath = import_node_path30.default.join(serviceDir, "prisma", "schema.prisma");
|
|
9940
10069
|
const content = await readIfExists(schemaPath);
|
|
9941
10070
|
if (!content) return [];
|
|
9942
10071
|
const block = content.match(/datasource\s+\w+\s*\{([^}]*)\}/s);
|
|
@@ -10094,10 +10223,10 @@ var knexParser = { name: "knex", parse: parse5 };
|
|
|
10094
10223
|
|
|
10095
10224
|
// src/extract/databases/ormconfig.ts
|
|
10096
10225
|
init_cjs_shims();
|
|
10097
|
-
var
|
|
10226
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
10098
10227
|
async function parse6(serviceDir) {
|
|
10099
10228
|
for (const candidate of ["ormconfig.json", "ormconfig.yaml", "ormconfig.yml"]) {
|
|
10100
|
-
const abs =
|
|
10229
|
+
const abs = import_node_path31.default.join(serviceDir, candidate);
|
|
10101
10230
|
if (!await exists(abs)) continue;
|
|
10102
10231
|
const raw = candidate.endsWith(".json") ? await readJson(abs) : await readYaml(abs);
|
|
10103
10232
|
const entries = Array.isArray(raw) ? raw : [raw];
|
|
@@ -10157,9 +10286,9 @@ var typeormParser = { name: "typeorm", parse: parse7 };
|
|
|
10157
10286
|
|
|
10158
10287
|
// src/extract/databases/sequelize.ts
|
|
10159
10288
|
init_cjs_shims();
|
|
10160
|
-
var
|
|
10289
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
10161
10290
|
async function parse8(serviceDir) {
|
|
10162
|
-
const configPath =
|
|
10291
|
+
const configPath = import_node_path32.default.join(serviceDir, "config", "config.json");
|
|
10163
10292
|
if (!await exists(configPath)) return [];
|
|
10164
10293
|
const raw = await readJson(configPath);
|
|
10165
10294
|
const out = [];
|
|
@@ -10186,8 +10315,8 @@ var sequelizeParser = { name: "sequelize", parse: parse8 };
|
|
|
10186
10315
|
|
|
10187
10316
|
// src/extract/databases/csharp.ts
|
|
10188
10317
|
init_cjs_shims();
|
|
10189
|
-
var
|
|
10190
|
-
var
|
|
10318
|
+
var import_node_fs23 = require("fs");
|
|
10319
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
10191
10320
|
var CS_EXT = ".cs";
|
|
10192
10321
|
var NPGSQL_GATE = /\bUseNpgsql\b|\bNpgsql\b/;
|
|
10193
10322
|
var REDIS_GATE = /\bConnectionMultiplexer\b|\bStackExchange\.Redis\b|\bConfigurationOptions\.Parse\b|\bAddStackExchangeRedisCache\b/;
|
|
@@ -10234,12 +10363,12 @@ function parseRedisEndpoint(raw) {
|
|
|
10234
10363
|
return { host, port, database: "", engine: "redis", engineVersion: "unknown" };
|
|
10235
10364
|
}
|
|
10236
10365
|
async function resolveEnvUpTree(startDir, name) {
|
|
10237
|
-
let dir =
|
|
10366
|
+
let dir = import_node_path33.default.resolve(startDir);
|
|
10238
10367
|
for (let depth = 0; depth < 12; depth++) {
|
|
10239
10368
|
const value = await resolveEnvVar(dir, name);
|
|
10240
10369
|
if (value !== null) return value;
|
|
10241
|
-
const atRepoRoot = await
|
|
10242
|
-
const parent =
|
|
10370
|
+
const atRepoRoot = await import_node_fs23.promises.access(import_node_path33.default.join(dir, ".git")).then(() => true).catch(() => false);
|
|
10371
|
+
const parent = import_node_path33.default.dirname(dir);
|
|
10243
10372
|
if (atRepoRoot || parent === dir) break;
|
|
10244
10373
|
dir = parent;
|
|
10245
10374
|
}
|
|
@@ -10294,12 +10423,12 @@ async function resolveConfigs(literals, keys, serviceDir, looksLike, parse11) {
|
|
|
10294
10423
|
}
|
|
10295
10424
|
async function parse9(serviceDir) {
|
|
10296
10425
|
const files = (await walkSourceFiles(serviceDir).catch(() => [])).filter(
|
|
10297
|
-
(f) =>
|
|
10426
|
+
(f) => import_node_path33.default.extname(f) === CS_EXT
|
|
10298
10427
|
);
|
|
10299
10428
|
if (files.length === 0) return [];
|
|
10300
10429
|
const sources = [];
|
|
10301
10430
|
for (const file of files) {
|
|
10302
|
-
const content = await
|
|
10431
|
+
const content = await import_node_fs23.promises.readFile(file, "utf8").catch(() => null);
|
|
10303
10432
|
if (content !== null) sources.push({ file, content });
|
|
10304
10433
|
}
|
|
10305
10434
|
let pgGateFile = null;
|
|
@@ -10340,7 +10469,7 @@ var csharpParser = { name: "csharp", parse: parse9 };
|
|
|
10340
10469
|
|
|
10341
10470
|
// src/extract/databases/docker-compose.ts
|
|
10342
10471
|
init_cjs_shims();
|
|
10343
|
-
var
|
|
10472
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
10344
10473
|
function portFromService(svc) {
|
|
10345
10474
|
for (const raw of svc.ports ?? []) {
|
|
10346
10475
|
const str = String(raw);
|
|
@@ -10367,7 +10496,7 @@ function databaseFromEnv(svc) {
|
|
|
10367
10496
|
}
|
|
10368
10497
|
async function parse10(serviceDir) {
|
|
10369
10498
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
10370
|
-
const abs =
|
|
10499
|
+
const abs = import_node_path34.default.join(serviceDir, name);
|
|
10371
10500
|
if (!await exists(abs)) continue;
|
|
10372
10501
|
const raw = await readYaml(abs);
|
|
10373
10502
|
if (!raw?.services) return [];
|
|
@@ -10540,7 +10669,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10540
10669
|
discoveredVia: mergedDiscoveredVia
|
|
10541
10670
|
});
|
|
10542
10671
|
}
|
|
10543
|
-
const relConfigFile = toPosix(
|
|
10672
|
+
const relConfigFile = toPosix(import_node_path35.default.relative(service.dir, config.sourceFile));
|
|
10544
10673
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
10545
10674
|
graph,
|
|
10546
10675
|
service.pkg.name,
|
|
@@ -10549,7 +10678,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10549
10678
|
);
|
|
10550
10679
|
nodesAdded += fn;
|
|
10551
10680
|
edgesAdded += fe;
|
|
10552
|
-
const evidenceFile = toPosix(
|
|
10681
|
+
const evidenceFile = toPosix(import_node_path35.default.relative(scanPath, config.sourceFile));
|
|
10553
10682
|
const edge = {
|
|
10554
10683
|
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id, import_types23.EdgeType.CONNECTS_TO),
|
|
10555
10684
|
source: fileNodeId,
|
|
@@ -10570,15 +10699,15 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10570
10699
|
if (allConfigs.length === 1) {
|
|
10571
10700
|
const primary = allConfigs[0];
|
|
10572
10701
|
service.node.dbConnectionTarget = primary.port ? `${primary.host}:${primary.port}` : primary.host;
|
|
10573
|
-
const relPath =
|
|
10702
|
+
const relPath = import_node_path35.default.relative(scanPath, primary.sourceFile);
|
|
10574
10703
|
const cfgId = (0, import_types23.configId)(relPath);
|
|
10575
10704
|
if (!graph.hasNode(cfgId)) {
|
|
10576
10705
|
const cfgNode = {
|
|
10577
10706
|
id: cfgId,
|
|
10578
10707
|
type: import_types23.NodeType.ConfigNode,
|
|
10579
|
-
name:
|
|
10708
|
+
name: import_node_path35.default.basename(primary.sourceFile),
|
|
10580
10709
|
path: relPath,
|
|
10581
|
-
fileType: isConfigFile(
|
|
10710
|
+
fileType: isConfigFile(import_node_path35.default.basename(primary.sourceFile)).fileType || "config"
|
|
10582
10711
|
};
|
|
10583
10712
|
graph.addNode(cfgId, cfgNode);
|
|
10584
10713
|
nodesAdded++;
|
|
@@ -10619,19 +10748,19 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10619
10748
|
|
|
10620
10749
|
// src/extract/configs.ts
|
|
10621
10750
|
init_cjs_shims();
|
|
10622
|
-
var
|
|
10623
|
-
var
|
|
10751
|
+
var import_node_fs24 = require("fs");
|
|
10752
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
10624
10753
|
var import_types24 = require("@neat.is/types");
|
|
10625
10754
|
async function walkConfigFiles(dir, excludeDirs = []) {
|
|
10626
|
-
const excluded = new Set(excludeDirs.map((d) =>
|
|
10755
|
+
const excluded = new Set(excludeDirs.map((d) => import_node_path36.default.resolve(d)));
|
|
10627
10756
|
const out = [];
|
|
10628
10757
|
async function walk11(current) {
|
|
10629
|
-
const entries = await
|
|
10758
|
+
const entries = await import_node_fs24.promises.readdir(current, { withFileTypes: true });
|
|
10630
10759
|
for (const entry of entries) {
|
|
10631
|
-
const full =
|
|
10760
|
+
const full = import_node_path36.default.join(current, entry.name);
|
|
10632
10761
|
if (entry.isDirectory()) {
|
|
10633
10762
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
10634
|
-
if (excluded.has(
|
|
10763
|
+
if (excluded.has(import_node_path36.default.resolve(full))) continue;
|
|
10635
10764
|
if (await isPythonVenvDir(full)) continue;
|
|
10636
10765
|
await walk11(full);
|
|
10637
10766
|
} else if (entry.isFile() && isConfigFile(entry.name).match) {
|
|
@@ -10648,19 +10777,19 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10648
10777
|
for (const service of services) {
|
|
10649
10778
|
const configFiles = await walkConfigFiles(service.dir, service.excludeDirs);
|
|
10650
10779
|
for (const file of configFiles) {
|
|
10651
|
-
const relPath =
|
|
10780
|
+
const relPath = import_node_path36.default.relative(scanPath, file);
|
|
10652
10781
|
const node = {
|
|
10653
10782
|
id: (0, import_types24.configId)(relPath),
|
|
10654
10783
|
type: import_types24.NodeType.ConfigNode,
|
|
10655
|
-
name:
|
|
10784
|
+
name: import_node_path36.default.basename(file),
|
|
10656
10785
|
path: relPath,
|
|
10657
|
-
fileType: isConfigFile(
|
|
10786
|
+
fileType: isConfigFile(import_node_path36.default.basename(file)).fileType
|
|
10658
10787
|
};
|
|
10659
10788
|
if (!graph.hasNode(node.id)) {
|
|
10660
10789
|
graph.addNode(node.id, node);
|
|
10661
10790
|
nodesAdded++;
|
|
10662
10791
|
}
|
|
10663
|
-
const relToService = toPosix(
|
|
10792
|
+
const relToService = toPosix(import_node_path36.default.relative(service.dir, file));
|
|
10664
10793
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
10665
10794
|
graph,
|
|
10666
10795
|
service.pkg.name,
|
|
@@ -10676,7 +10805,7 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10676
10805
|
type: import_types24.EdgeType.CONFIGURED_BY,
|
|
10677
10806
|
provenance: import_types24.Provenance.EXTRACTED,
|
|
10678
10807
|
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10679
|
-
evidence: { file: relPath.split(
|
|
10808
|
+
evidence: { file: relPath.split(import_node_path36.default.sep).join("/") }
|
|
10680
10809
|
};
|
|
10681
10810
|
if (!graph.hasEdge(edge.id)) {
|
|
10682
10811
|
graph.addEdgeWithKey(edge.id, edge.source, edge.target, edge);
|
|
@@ -10689,8 +10818,8 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10689
10818
|
|
|
10690
10819
|
// src/extract/proto.ts
|
|
10691
10820
|
init_cjs_shims();
|
|
10692
|
-
var
|
|
10693
|
-
var
|
|
10821
|
+
var import_node_fs25 = require("fs");
|
|
10822
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
10694
10823
|
var import_types25 = require("@neat.is/types");
|
|
10695
10824
|
var PROTO_EXTENSION = ".proto";
|
|
10696
10825
|
function packageOf(content) {
|
|
@@ -10728,18 +10857,18 @@ function grpcMethodsFromProto(content, fqPackage) {
|
|
|
10728
10857
|
return out;
|
|
10729
10858
|
}
|
|
10730
10859
|
async function walkProtoFiles(dir, excludeDirs = []) {
|
|
10731
|
-
const excluded = new Set(excludeDirs.map((d) =>
|
|
10860
|
+
const excluded = new Set(excludeDirs.map((d) => import_node_path37.default.resolve(d)));
|
|
10732
10861
|
const out = [];
|
|
10733
10862
|
async function walk11(current) {
|
|
10734
|
-
const entries = await
|
|
10863
|
+
const entries = await import_node_fs25.promises.readdir(current, { withFileTypes: true }).catch(() => []);
|
|
10735
10864
|
for (const entry of entries) {
|
|
10736
|
-
const full =
|
|
10865
|
+
const full = import_node_path37.default.join(current, entry.name);
|
|
10737
10866
|
if (entry.isDirectory()) {
|
|
10738
10867
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
10739
|
-
if (excluded.has(
|
|
10868
|
+
if (excluded.has(import_node_path37.default.resolve(full))) continue;
|
|
10740
10869
|
if (await isPythonVenvDir(full)) continue;
|
|
10741
10870
|
await walk11(full);
|
|
10742
|
-
} else if (entry.isFile() &&
|
|
10871
|
+
} else if (entry.isFile() && import_node_path37.default.extname(entry.name) === PROTO_EXTENSION) {
|
|
10743
10872
|
out.push(full);
|
|
10744
10873
|
}
|
|
10745
10874
|
}
|
|
@@ -10754,10 +10883,10 @@ async function addGrpcMethods(graph, services) {
|
|
|
10754
10883
|
const protoPaths = await walkProtoFiles(service.dir, service.excludeDirs);
|
|
10755
10884
|
for (const protoPath of protoPaths) {
|
|
10756
10885
|
if (isTestPath(protoPath)) continue;
|
|
10757
|
-
const relFile = toPosix(
|
|
10886
|
+
const relFile = toPosix(import_node_path37.default.relative(service.dir, protoPath));
|
|
10758
10887
|
let content;
|
|
10759
10888
|
try {
|
|
10760
|
-
content = await
|
|
10889
|
+
content = await import_node_fs25.promises.readFile(protoPath, "utf8");
|
|
10761
10890
|
} catch (err) {
|
|
10762
10891
|
recordExtractionError("proto extraction", protoPath, err);
|
|
10763
10892
|
continue;
|
|
@@ -10816,7 +10945,7 @@ var import_types45 = require("@neat.is/types");
|
|
|
10816
10945
|
|
|
10817
10946
|
// src/extract/calls/http.ts
|
|
10818
10947
|
init_cjs_shims();
|
|
10819
|
-
var
|
|
10948
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
10820
10949
|
var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
10821
10950
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
10822
10951
|
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
@@ -10899,7 +11028,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
10899
11028
|
const seen = /* @__PURE__ */ new Set();
|
|
10900
11029
|
for (const file of files) {
|
|
10901
11030
|
if (isTestPath(file.path)) continue;
|
|
10902
|
-
const parser = parserForExt(
|
|
11031
|
+
const parser = parserForExt(import_node_path38.default.extname(file.path), parserCache);
|
|
10903
11032
|
let sites;
|
|
10904
11033
|
try {
|
|
10905
11034
|
sites = callsFromSource(file.content, parser, knownHosts);
|
|
@@ -10908,7 +11037,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
10908
11037
|
continue;
|
|
10909
11038
|
}
|
|
10910
11039
|
if (sites.length === 0) continue;
|
|
10911
|
-
const relFile = toPosix(
|
|
11040
|
+
const relFile = toPosix(import_node_path38.default.relative(service.dir, file.path));
|
|
10912
11041
|
for (const site of sites) {
|
|
10913
11042
|
const targetId = hostToNodeId.get(site.host);
|
|
10914
11043
|
if (!targetId || targetId === service.node.id) continue;
|
|
@@ -10962,7 +11091,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
10962
11091
|
|
|
10963
11092
|
// src/extract/calls/route-match.ts
|
|
10964
11093
|
init_cjs_shims();
|
|
10965
|
-
var
|
|
11094
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
10966
11095
|
var import_tree_sitter7 = __toESM(require("tree-sitter"), 1);
|
|
10967
11096
|
var import_tree_sitter_javascript5 = __toESM(require("tree-sitter-javascript"), 1);
|
|
10968
11097
|
var import_types27 = require("@neat.is/types");
|
|
@@ -11240,7 +11369,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11240
11369
|
const seen = /* @__PURE__ */ new Set();
|
|
11241
11370
|
for (const file of files) {
|
|
11242
11371
|
if (isTestPath(file.path)) continue;
|
|
11243
|
-
if (!JS_CLIENT_EXTENSIONS.has(
|
|
11372
|
+
if (!JS_CLIENT_EXTENSIONS.has(import_node_path39.default.extname(file.path))) continue;
|
|
11244
11373
|
let sites;
|
|
11245
11374
|
try {
|
|
11246
11375
|
sites = clientCallSitesFromSource(file.content, jsParser, knownHosts);
|
|
@@ -11249,7 +11378,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11249
11378
|
continue;
|
|
11250
11379
|
}
|
|
11251
11380
|
if (sites.length === 0) continue;
|
|
11252
|
-
const relFile = toPosix(
|
|
11381
|
+
const relFile = toPosix(import_node_path39.default.relative(service.dir, file.path));
|
|
11253
11382
|
for (const site of sites) {
|
|
11254
11383
|
if (site.host === null) {
|
|
11255
11384
|
const dedupKey2 = `${relFile}|unresolved-host`;
|
|
@@ -11342,7 +11471,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11342
11471
|
|
|
11343
11472
|
// src/extract/calls/kafka.ts
|
|
11344
11473
|
init_cjs_shims();
|
|
11345
|
-
var
|
|
11474
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
11346
11475
|
var import_types28 = require("@neat.is/types");
|
|
11347
11476
|
var PRODUCER_TOPIC_RE = /(?:producer|kafkaProducer)[\s\S]{0,40}?\.send\s*\(\s*\{[\s\S]{0,200}?topic\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11348
11477
|
var CONSUMER_TOPIC_RE = /(?:consumer|kafkaConsumer)[\s\S]{0,40}?\.(?:subscribe|run)\s*\(\s*\{[\s\S]{0,200}?topic[s]?\s*:\s*(?:\[\s*)?['"`]([^'"`]+)['"`]/g;
|
|
@@ -11430,13 +11559,13 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11430
11559
|
// call sites — verified-call-site tier (ADR-066).
|
|
11431
11560
|
confidenceKind: "verified-call-site",
|
|
11432
11561
|
evidence: {
|
|
11433
|
-
file:
|
|
11562
|
+
file: import_node_path40.default.relative(serviceDir, file.path),
|
|
11434
11563
|
line,
|
|
11435
11564
|
snippet: snippet(file.content, line)
|
|
11436
11565
|
}
|
|
11437
11566
|
});
|
|
11438
11567
|
};
|
|
11439
|
-
if (
|
|
11568
|
+
if (import_node_path40.default.extname(file.path) === ".go") {
|
|
11440
11569
|
goSaramaEndpoints(file.content, make);
|
|
11441
11570
|
} else {
|
|
11442
11571
|
for (const { topic } of findAll(PRODUCER_TOPIC_RE, file.content)) make(topic, "PUBLISHES_TO");
|
|
@@ -11447,7 +11576,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11447
11576
|
|
|
11448
11577
|
// src/extract/calls/redis.ts
|
|
11449
11578
|
init_cjs_shims();
|
|
11450
|
-
var
|
|
11579
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
11451
11580
|
var import_types29 = require("@neat.is/types");
|
|
11452
11581
|
var REDIS_URL_RE = /redis(?:s)?:\/\/(?:[^@'"`\s]+@)?([^:/'"`\s]+)(?::(\d+))?/g;
|
|
11453
11582
|
function redisEndpointsFromFile(file, serviceDir) {
|
|
@@ -11470,7 +11599,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11470
11599
|
// support tier (ADR-066).
|
|
11471
11600
|
confidenceKind: "url-with-structural-support",
|
|
11472
11601
|
evidence: {
|
|
11473
|
-
file:
|
|
11602
|
+
file: import_node_path41.default.relative(serviceDir, file.path),
|
|
11474
11603
|
line,
|
|
11475
11604
|
snippet: snippet(file.content, line)
|
|
11476
11605
|
}
|
|
@@ -11481,7 +11610,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11481
11610
|
|
|
11482
11611
|
// src/extract/calls/aws.ts
|
|
11483
11612
|
init_cjs_shims();
|
|
11484
|
-
var
|
|
11613
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
11485
11614
|
var import_types30 = require("@neat.is/types");
|
|
11486
11615
|
var S3_BUCKET_RE = /Bucket\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11487
11616
|
var DYNAMO_TABLE_RE = /TableName\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
@@ -11515,7 +11644,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11515
11644
|
// (ADR-066).
|
|
11516
11645
|
confidenceKind: "verified-call-site",
|
|
11517
11646
|
evidence: {
|
|
11518
|
-
file:
|
|
11647
|
+
file: import_node_path42.default.relative(serviceDir, file.path),
|
|
11519
11648
|
line,
|
|
11520
11649
|
snippet: snippet(file.content, line)
|
|
11521
11650
|
}
|
|
@@ -11540,7 +11669,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11540
11669
|
|
|
11541
11670
|
// src/extract/calls/grpc.ts
|
|
11542
11671
|
init_cjs_shims();
|
|
11543
|
-
var
|
|
11672
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
11544
11673
|
var import_types31 = require("@neat.is/types");
|
|
11545
11674
|
var GRPC_CLIENT_RE = /new\s+([A-Z][A-Za-z0-9_]*)Client\s*\(\s*['"`]?([^,'"`)]+)?/g;
|
|
11546
11675
|
var AWS_SDK_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@aws-sdk\/client-([a-z0-9-]+)['"`]/g;
|
|
@@ -11599,7 +11728,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11599
11728
|
// tier (ADR-066).
|
|
11600
11729
|
confidenceKind: "verified-call-site",
|
|
11601
11730
|
evidence: {
|
|
11602
|
-
file:
|
|
11731
|
+
file: import_node_path43.default.relative(serviceDir, file.path),
|
|
11603
11732
|
line,
|
|
11604
11733
|
snippet: snippet(file.content, line)
|
|
11605
11734
|
}
|
|
@@ -11610,7 +11739,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11610
11739
|
|
|
11611
11740
|
// src/extract/calls/supabase.ts
|
|
11612
11741
|
init_cjs_shims();
|
|
11613
|
-
var
|
|
11742
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
11614
11743
|
var import_types32 = require("@neat.is/types");
|
|
11615
11744
|
var SUPABASE_JS_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/supabase-js['"`]/;
|
|
11616
11745
|
var SUPABASE_SSR_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/ssr['"`]/;
|
|
@@ -11669,7 +11798,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11669
11798
|
// tier (ADR-066), the same grade aws.ts / grpc.ts emit at.
|
|
11670
11799
|
confidenceKind: "verified-call-site",
|
|
11671
11800
|
evidence: {
|
|
11672
|
-
file:
|
|
11801
|
+
file: import_node_path44.default.relative(serviceDir, file.path),
|
|
11673
11802
|
line,
|
|
11674
11803
|
snippet: snippet(file.content, line)
|
|
11675
11804
|
}
|
|
@@ -11696,7 +11825,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11696
11825
|
edgeType: "CALLS",
|
|
11697
11826
|
confidenceKind: "verified-call-site",
|
|
11698
11827
|
evidence: {
|
|
11699
|
-
file:
|
|
11828
|
+
file: import_node_path44.default.relative(serviceDir, file.path),
|
|
11700
11829
|
line,
|
|
11701
11830
|
snippet: snippet(file.content, line)
|
|
11702
11831
|
}
|
|
@@ -11708,7 +11837,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11708
11837
|
|
|
11709
11838
|
// src/extract/calls/firestore.ts
|
|
11710
11839
|
init_cjs_shims();
|
|
11711
|
-
var
|
|
11840
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
11712
11841
|
var import_tree_sitter8 = __toESM(require("tree-sitter"), 1);
|
|
11713
11842
|
var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11714
11843
|
var import_types33 = require("@neat.is/types");
|
|
@@ -11881,7 +12010,7 @@ function firestoreEndpointsFromFile(file, serviceDir, imported) {
|
|
|
11881
12010
|
if (!hasClient && !hasAdmin && importedNames.size === 0) return [];
|
|
11882
12011
|
const ownSdk = hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
|
|
11883
12012
|
const fileSdk = !hasClient && !hasAdmin ? imported?.sdk ?? null : ownSdk;
|
|
11884
|
-
const tree = parseSource3(parserForExt2(
|
|
12013
|
+
const tree = parseSource3(parserForExt2(import_node_path45.default.extname(file.path)), file.content);
|
|
11885
12014
|
const clientVars = firestoreClientVars(tree.rootNode);
|
|
11886
12015
|
for (const n of importedNames) clientVars.add(n);
|
|
11887
12016
|
const collLine = /* @__PURE__ */ new Map();
|
|
@@ -11986,7 +12115,7 @@ function firestoreEndpointsFromFile(file, serviceDir, imported) {
|
|
|
11986
12115
|
...columnSet.size > 0 ? { columns: [...columnSet] } : {},
|
|
11987
12116
|
...sdkWrites ? { sdkWrites } : {},
|
|
11988
12117
|
evidence: {
|
|
11989
|
-
file:
|
|
12118
|
+
file: import_node_path45.default.relative(serviceDir, file.path),
|
|
11990
12119
|
line,
|
|
11991
12120
|
snippet: snippet(file.content, line)
|
|
11992
12121
|
}
|
|
@@ -12046,7 +12175,7 @@ function sdkOf(content) {
|
|
|
12046
12175
|
return hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
|
|
12047
12176
|
}
|
|
12048
12177
|
function parseOrNull(file) {
|
|
12049
|
-
const ext =
|
|
12178
|
+
const ext = import_node_path45.default.extname(file.path);
|
|
12050
12179
|
if (!(ext in GRAMMAR_BY_EXT)) return null;
|
|
12051
12180
|
try {
|
|
12052
12181
|
return parseSource3(parserForExt2(ext), file.content).rootNode;
|
|
@@ -12062,7 +12191,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
|
12062
12191
|
if (!root) continue;
|
|
12063
12192
|
const names = exportedFirestoreClients(root);
|
|
12064
12193
|
if (names.size === 0) continue;
|
|
12065
|
-
registry.set(toPosix(
|
|
12194
|
+
registry.set(toPosix(import_node_path45.default.relative(serviceDir, f.path)), { names, sdk: sdkOf(f.content) });
|
|
12066
12195
|
}
|
|
12067
12196
|
if (registry.size === 0) return [];
|
|
12068
12197
|
const out = [];
|
|
@@ -12075,7 +12204,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
|
12075
12204
|
const names = /* @__PURE__ */ new Set();
|
|
12076
12205
|
let sdk = null;
|
|
12077
12206
|
for (const b of bindings) {
|
|
12078
|
-
const rel = await resolveJsImport(b.specifier,
|
|
12207
|
+
const rel = await resolveJsImport(b.specifier, import_node_path45.default.dirname(f.path), serviceDir, null);
|
|
12079
12208
|
if (!rel) continue;
|
|
12080
12209
|
const entry = registry.get(rel);
|
|
12081
12210
|
if (!entry || !entry.names.has(b.imported)) continue;
|
|
@@ -12090,7 +12219,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
|
12090
12219
|
|
|
12091
12220
|
// src/extract/calls/mongoose.ts
|
|
12092
12221
|
init_cjs_shims();
|
|
12093
|
-
var
|
|
12222
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
12094
12223
|
var import_types34 = require("@neat.is/types");
|
|
12095
12224
|
var MONGOOSE_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongoose['"`]/;
|
|
12096
12225
|
var MONGODB_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongodb['"`]/;
|
|
@@ -12241,7 +12370,7 @@ function endpoint(r, file, serviceDir, matchText) {
|
|
|
12241
12370
|
kind: r.kind,
|
|
12242
12371
|
edgeType: "CALLS",
|
|
12243
12372
|
confidenceKind: "verified-call-site",
|
|
12244
|
-
evidence: { file:
|
|
12373
|
+
evidence: { file: import_node_path46.default.relative(serviceDir, file.path), line, snippet: snippet(file.content, line) }
|
|
12245
12374
|
};
|
|
12246
12375
|
}
|
|
12247
12376
|
function mongooseEndpointsFromFile(file, serviceDir) {
|
|
@@ -12331,7 +12460,7 @@ async function mongooseCrossFileEndpoints(files, serviceDir) {
|
|
|
12331
12460
|
const registry = /* @__PURE__ */ new Map();
|
|
12332
12461
|
for (const f of mongooseFiles) {
|
|
12333
12462
|
const fx = fileExportsOf(f.content, pluralizeOn);
|
|
12334
|
-
if (fx) registry.set(toPosix(
|
|
12463
|
+
if (fx) registry.set(toPosix(import_node_path46.default.relative(serviceDir, f.path)), fx);
|
|
12335
12464
|
}
|
|
12336
12465
|
if (registry.size === 0) return [];
|
|
12337
12466
|
const out = [];
|
|
@@ -12342,7 +12471,7 @@ async function mongooseCrossFileEndpoints(files, serviceDir) {
|
|
|
12342
12471
|
const directColl = /* @__PURE__ */ new Map();
|
|
12343
12472
|
const nsExports = /* @__PURE__ */ new Map();
|
|
12344
12473
|
for (const b of bindings) {
|
|
12345
|
-
const resolvedRel = await resolveJsImport(b.specifier,
|
|
12474
|
+
const resolvedRel = await resolveJsImport(b.specifier, import_node_path46.default.dirname(f.path), serviceDir, null);
|
|
12346
12475
|
if (!resolvedRel) continue;
|
|
12347
12476
|
const fx = registry.get(resolvedRel);
|
|
12348
12477
|
if (!fx) continue;
|
|
@@ -12386,7 +12515,7 @@ async function mongooseCrossFileEndpoints(files, serviceDir) {
|
|
|
12386
12515
|
|
|
12387
12516
|
// src/extract/calls/sqlalchemy.ts
|
|
12388
12517
|
init_cjs_shims();
|
|
12389
|
-
var
|
|
12518
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
12390
12519
|
var import_tree_sitter9 = __toESM(require("tree-sitter"), 1);
|
|
12391
12520
|
var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
12392
12521
|
var import_types35 = require("@neat.is/types");
|
|
@@ -12525,7 +12654,7 @@ function sqlalchemyForeignKeys(file, serviceDir) {
|
|
|
12525
12654
|
childTable,
|
|
12526
12655
|
parentTable,
|
|
12527
12656
|
evidence: {
|
|
12528
|
-
file:
|
|
12657
|
+
file: import_node_path47.default.relative(serviceDir, file.path),
|
|
12529
12658
|
line,
|
|
12530
12659
|
snippet: snippet(file.content, line)
|
|
12531
12660
|
}
|
|
@@ -12550,7 +12679,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
12550
12679
|
confidenceKind: "verified-call-site",
|
|
12551
12680
|
...columns && columns.length > 0 ? { columns } : {},
|
|
12552
12681
|
evidence: {
|
|
12553
|
-
file:
|
|
12682
|
+
file: import_node_path47.default.relative(serviceDir, file.path),
|
|
12554
12683
|
line,
|
|
12555
12684
|
snippet: snippet(file.content, line)
|
|
12556
12685
|
}
|
|
@@ -12657,7 +12786,7 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
12657
12786
|
edgeType: "CALLS",
|
|
12658
12787
|
confidenceKind: "verified-call-site",
|
|
12659
12788
|
evidence: {
|
|
12660
|
-
file:
|
|
12789
|
+
file: import_node_path47.default.relative(serviceDir, file.path),
|
|
12661
12790
|
line,
|
|
12662
12791
|
snippet: snippet(file.content, line)
|
|
12663
12792
|
}
|
|
@@ -12669,7 +12798,7 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
12669
12798
|
|
|
12670
12799
|
// src/extract/calls/socket.ts
|
|
12671
12800
|
init_cjs_shims();
|
|
12672
|
-
var
|
|
12801
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
12673
12802
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
12674
12803
|
var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
|
|
12675
12804
|
var import_types36 = require("@neat.is/types");
|
|
@@ -12745,7 +12874,7 @@ function socketEndpointsFromFile(file, serviceDir) {
|
|
|
12745
12874
|
// A verified `socket.socket(...)` + `.connect((host, port))` call site.
|
|
12746
12875
|
confidenceKind: "verified-call-site",
|
|
12747
12876
|
evidence: {
|
|
12748
|
-
file:
|
|
12877
|
+
file: import_node_path48.default.relative(serviceDir, file.path),
|
|
12749
12878
|
line,
|
|
12750
12879
|
snippet: snippet(file.content, line)
|
|
12751
12880
|
}
|
|
@@ -12756,7 +12885,7 @@ function socketEndpointsFromFile(file, serviceDir) {
|
|
|
12756
12885
|
|
|
12757
12886
|
// src/extract/calls/django-orm.ts
|
|
12758
12887
|
init_cjs_shims();
|
|
12759
|
-
var
|
|
12888
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
12760
12889
|
var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
|
|
12761
12890
|
var import_tree_sitter_python7 = __toESM(require("tree-sitter-python"), 1);
|
|
12762
12891
|
var import_types37 = require("@neat.is/types");
|
|
@@ -12826,7 +12955,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
12826
12955
|
const tree = parseSource8(makePyParser5(), file.content);
|
|
12827
12956
|
const out = [];
|
|
12828
12957
|
const seen = /* @__PURE__ */ new Set();
|
|
12829
|
-
const defaultAppLabel =
|
|
12958
|
+
const defaultAppLabel = import_node_path49.default.basename(import_node_path49.default.dirname(file.path));
|
|
12830
12959
|
walk5(tree.rootNode, (node) => {
|
|
12831
12960
|
if (node.type !== "class_definition") return;
|
|
12832
12961
|
if (!extendsDjangoModel(node)) return;
|
|
@@ -12844,7 +12973,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
12844
12973
|
kind: "sql-table",
|
|
12845
12974
|
edgeType: "CALLS",
|
|
12846
12975
|
confidenceKind: "verified-call-site",
|
|
12847
|
-
evidence: { file:
|
|
12976
|
+
evidence: { file: import_node_path49.default.relative(serviceDir, file.path), line, snippet: snippet(file.content, line) }
|
|
12848
12977
|
});
|
|
12849
12978
|
});
|
|
12850
12979
|
return out;
|
|
@@ -12852,7 +12981,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
12852
12981
|
|
|
12853
12982
|
// src/extract/calls/drizzle.ts
|
|
12854
12983
|
init_cjs_shims();
|
|
12855
|
-
var
|
|
12984
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
12856
12985
|
var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
|
|
12857
12986
|
var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
|
|
12858
12987
|
var import_types38 = require("@neat.is/types");
|
|
@@ -12930,7 +13059,7 @@ function columnsFromObject(obj) {
|
|
|
12930
13059
|
}
|
|
12931
13060
|
function drizzleEndpointsFromFile(file, serviceDir) {
|
|
12932
13061
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
12933
|
-
const tree = parseSource3(parserForExt3(
|
|
13062
|
+
const tree = parseSource3(parserForExt3(import_node_path50.default.extname(file.path)), file.content);
|
|
12934
13063
|
const out = [];
|
|
12935
13064
|
const seen = /* @__PURE__ */ new Set();
|
|
12936
13065
|
const walk11 = (node) => {
|
|
@@ -12953,7 +13082,7 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
12953
13082
|
confidenceKind: "structural",
|
|
12954
13083
|
columns,
|
|
12955
13084
|
evidence: {
|
|
12956
|
-
file:
|
|
13085
|
+
file: import_node_path50.default.relative(serviceDir, file.path),
|
|
12957
13086
|
line,
|
|
12958
13087
|
snippet: snippet(file.content, line)
|
|
12959
13088
|
}
|
|
@@ -13019,7 +13148,7 @@ function referencesTargetVar(call) {
|
|
|
13019
13148
|
}
|
|
13020
13149
|
function drizzleForeignKeys(file, serviceDir) {
|
|
13021
13150
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
13022
|
-
const tree = parseSource3(parserForExt3(
|
|
13151
|
+
const tree = parseSource3(parserForExt3(import_node_path50.default.extname(file.path)), file.content);
|
|
13023
13152
|
const { tables, varToTable } = collectDrizzleTables(tree.rootNode);
|
|
13024
13153
|
const out = [];
|
|
13025
13154
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -13038,7 +13167,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13038
13167
|
childTable: table.tableName,
|
|
13039
13168
|
parentTable,
|
|
13040
13169
|
evidence: {
|
|
13041
|
-
file:
|
|
13170
|
+
file: import_node_path50.default.relative(serviceDir, file.path),
|
|
13042
13171
|
line,
|
|
13043
13172
|
snippet: snippet(file.content, line)
|
|
13044
13173
|
}
|
|
@@ -13055,7 +13184,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13055
13184
|
|
|
13056
13185
|
// src/extract/calls/prisma.ts
|
|
13057
13186
|
init_cjs_shims();
|
|
13058
|
-
var
|
|
13187
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
13059
13188
|
var import_types39 = require("@neat.is/types");
|
|
13060
13189
|
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
13061
13190
|
"Int",
|
|
@@ -13111,7 +13240,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13111
13240
|
confidenceKind: "structural",
|
|
13112
13241
|
columns: b.columns,
|
|
13113
13242
|
evidence: {
|
|
13114
|
-
file:
|
|
13243
|
+
file: import_node_path51.default.relative(serviceDir, file.path),
|
|
13115
13244
|
line: b.startLine,
|
|
13116
13245
|
snippet: snippet(content, b.startLine)
|
|
13117
13246
|
}
|
|
@@ -13172,7 +13301,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13172
13301
|
}
|
|
13173
13302
|
async function prismaColumnEndpoints(serviceDir) {
|
|
13174
13303
|
const schemaPath = await findFirst(serviceDir, [
|
|
13175
|
-
|
|
13304
|
+
import_node_path51.default.join("prisma", "schema.prisma"),
|
|
13176
13305
|
"schema.prisma"
|
|
13177
13306
|
]);
|
|
13178
13307
|
if (!schemaPath) return [];
|
|
@@ -13247,7 +13376,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
|
|
|
13247
13376
|
childTable: current.table,
|
|
13248
13377
|
parentTable,
|
|
13249
13378
|
evidence: {
|
|
13250
|
-
file:
|
|
13379
|
+
file: import_node_path51.default.relative(serviceDir, file.path),
|
|
13251
13380
|
line: lineNo,
|
|
13252
13381
|
snippet: snippet(content, lineNo)
|
|
13253
13382
|
}
|
|
@@ -13262,7 +13391,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
|
|
|
13262
13391
|
}
|
|
13263
13392
|
async function prismaForeignKeys(serviceDir) {
|
|
13264
13393
|
const schemaPath = await findFirst(serviceDir, [
|
|
13265
|
-
|
|
13394
|
+
import_node_path51.default.join("prisma", "schema.prisma"),
|
|
13266
13395
|
"schema.prisma"
|
|
13267
13396
|
]);
|
|
13268
13397
|
if (!schemaPath) return [];
|
|
@@ -13273,7 +13402,7 @@ async function prismaForeignKeys(serviceDir) {
|
|
|
13273
13402
|
|
|
13274
13403
|
// src/extract/calls/activerecord.ts
|
|
13275
13404
|
init_cjs_shims();
|
|
13276
|
-
var
|
|
13405
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
13277
13406
|
var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
|
|
13278
13407
|
var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
|
|
13279
13408
|
var import_types40 = require("@neat.is/types");
|
|
@@ -13481,7 +13610,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
|
13481
13610
|
confidenceKind: "structural",
|
|
13482
13611
|
...table.columns.length > 0 ? { columns: table.columns } : {},
|
|
13483
13612
|
evidence: {
|
|
13484
|
-
file:
|
|
13613
|
+
file: import_node_path52.default.relative(serviceDir, file.path),
|
|
13485
13614
|
line: table.line,
|
|
13486
13615
|
snippet: snippet(file.content, table.line)
|
|
13487
13616
|
}
|
|
@@ -13503,7 +13632,7 @@ function railsSchemaForeignKeys(file, serviceDir) {
|
|
|
13503
13632
|
childTable,
|
|
13504
13633
|
parentTable,
|
|
13505
13634
|
evidence: {
|
|
13506
|
-
file:
|
|
13635
|
+
file: import_node_path52.default.relative(serviceDir, file.path),
|
|
13507
13636
|
line,
|
|
13508
13637
|
snippet: snippet(file.content, line)
|
|
13509
13638
|
}
|
|
@@ -13586,7 +13715,7 @@ function railsModelEndpointsFromFile(file, serviceDir) {
|
|
|
13586
13715
|
edgeType: "CALLS",
|
|
13587
13716
|
confidenceKind: "verified-call-site",
|
|
13588
13717
|
evidence: {
|
|
13589
|
-
file:
|
|
13718
|
+
file: import_node_path52.default.relative(serviceDir, file.path),
|
|
13590
13719
|
line,
|
|
13591
13720
|
snippet: snippet(file.content, line)
|
|
13592
13721
|
}
|
|
@@ -13623,7 +13752,7 @@ function railsModelForeignKeys(file, serviceDir) {
|
|
|
13623
13752
|
childTable,
|
|
13624
13753
|
parentTable,
|
|
13625
13754
|
evidence: {
|
|
13626
|
-
file:
|
|
13755
|
+
file: import_node_path52.default.relative(serviceDir, file.path),
|
|
13627
13756
|
line,
|
|
13628
13757
|
snippet: snippet(file.content, line)
|
|
13629
13758
|
}
|
|
@@ -13635,7 +13764,7 @@ function railsModelForeignKeys(file, serviceDir) {
|
|
|
13635
13764
|
|
|
13636
13765
|
// src/extract/calls/eloquent.ts
|
|
13637
13766
|
init_cjs_shims();
|
|
13638
|
-
var
|
|
13767
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
13639
13768
|
var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
|
|
13640
13769
|
var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
|
|
13641
13770
|
var import_types41 = require("@neat.is/types");
|
|
@@ -13892,7 +14021,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
13892
14021
|
confidenceKind: "structural",
|
|
13893
14022
|
...columns.length > 0 ? { columns } : {},
|
|
13894
14023
|
evidence: {
|
|
13895
|
-
file:
|
|
14024
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
13896
14025
|
line: bp.line,
|
|
13897
14026
|
snippet: snippet(file.content, bp.line)
|
|
13898
14027
|
}
|
|
@@ -13914,7 +14043,7 @@ function laravelMigrationForeignKeys(file, serviceDir) {
|
|
|
13914
14043
|
childTable,
|
|
13915
14044
|
parentTable,
|
|
13916
14045
|
evidence: {
|
|
13917
|
-
file:
|
|
14046
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
13918
14047
|
line,
|
|
13919
14048
|
snippet: snippet(file.content, line)
|
|
13920
14049
|
}
|
|
@@ -14034,7 +14163,7 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
|
14034
14163
|
edgeType: "CALLS",
|
|
14035
14164
|
confidenceKind: "verified-call-site",
|
|
14036
14165
|
evidence: {
|
|
14037
|
-
file:
|
|
14166
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
14038
14167
|
line,
|
|
14039
14168
|
snippet: snippet(file.content, line)
|
|
14040
14169
|
}
|
|
@@ -14070,7 +14199,7 @@ function laravelModelForeignKeys(file, serviceDir) {
|
|
|
14070
14199
|
childTable,
|
|
14071
14200
|
parentTable,
|
|
14072
14201
|
evidence: {
|
|
14073
|
-
file:
|
|
14202
|
+
file: import_node_path53.default.relative(serviceDir, file.path),
|
|
14074
14203
|
line,
|
|
14075
14204
|
snippet: snippet(file.content, line)
|
|
14076
14205
|
}
|
|
@@ -14082,7 +14211,7 @@ function laravelModelForeignKeys(file, serviceDir) {
|
|
|
14082
14211
|
|
|
14083
14212
|
// src/extract/calls/go.ts
|
|
14084
14213
|
init_cjs_shims();
|
|
14085
|
-
var
|
|
14214
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
14086
14215
|
var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
|
|
14087
14216
|
var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
|
|
14088
14217
|
var import_types42 = require("@neat.is/types");
|
|
@@ -14157,7 +14286,7 @@ function firstStringLiteralArg(argsNode) {
|
|
|
14157
14286
|
return null;
|
|
14158
14287
|
}
|
|
14159
14288
|
function goSqlEndpointsFromFile(file, serviceDir) {
|
|
14160
|
-
if (
|
|
14289
|
+
if (import_node_path56.default.extname(file.path) !== ".go") return [];
|
|
14161
14290
|
if (!file.content.includes(DATABASE_SQL_IMPORT) && !file.content.includes(SQLX_IMPORT)) return [];
|
|
14162
14291
|
const tree = parseSource11(makeGoParser3(), file.content);
|
|
14163
14292
|
const importsDatabaseSql = goImportsAny(tree.rootNode, /* @__PURE__ */ new Set([DATABASE_SQL_IMPORT]));
|
|
@@ -14186,7 +14315,7 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14186
14315
|
confidenceKind: "verified-call-site",
|
|
14187
14316
|
...columns.length > 0 ? { columns } : {},
|
|
14188
14317
|
evidence: {
|
|
14189
|
-
file: toPosix(
|
|
14318
|
+
file: toPosix(import_node_path56.default.relative(serviceDir, file.path)),
|
|
14190
14319
|
line,
|
|
14191
14320
|
snippet: snippet(file.content, line)
|
|
14192
14321
|
}
|
|
@@ -14197,7 +14326,7 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14197
14326
|
|
|
14198
14327
|
// src/extract/calls/gorm.ts
|
|
14199
14328
|
init_cjs_shims();
|
|
14200
|
-
var
|
|
14329
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
14201
14330
|
var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
|
|
14202
14331
|
var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
|
|
14203
14332
|
var import_types43 = require("@neat.is/types");
|
|
@@ -14630,7 +14759,7 @@ function collectColumns(struct, structs, seen, prefix, out, emitted) {
|
|
|
14630
14759
|
seen.delete(struct.name);
|
|
14631
14760
|
}
|
|
14632
14761
|
function gormEndpointsFromFile(file, serviceDir) {
|
|
14633
|
-
if (
|
|
14762
|
+
if (import_node_path57.default.extname(file.path) !== ".go") return [];
|
|
14634
14763
|
if (!GORM_IMPORT_RE.test(file.content)) return [];
|
|
14635
14764
|
const tree = parseSource12(makeGoParser4(), file.content);
|
|
14636
14765
|
const { structs, models, tableFor } = analyze(tree);
|
|
@@ -14652,7 +14781,7 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
14652
14781
|
confidenceKind: "structural",
|
|
14653
14782
|
...columns.length > 0 ? { columns } : {},
|
|
14654
14783
|
evidence: {
|
|
14655
|
-
file: toPosix(
|
|
14784
|
+
file: toPosix(import_node_path57.default.relative(serviceDir, file.path)),
|
|
14656
14785
|
line: struct.line,
|
|
14657
14786
|
snippet: snippet(file.content, struct.line)
|
|
14658
14787
|
}
|
|
@@ -14661,7 +14790,7 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
14661
14790
|
return out;
|
|
14662
14791
|
}
|
|
14663
14792
|
function gormForeignKeys(file, serviceDir) {
|
|
14664
|
-
if (
|
|
14793
|
+
if (import_node_path57.default.extname(file.path) !== ".go") return [];
|
|
14665
14794
|
if (!GORM_IMPORT_RE.test(file.content)) return [];
|
|
14666
14795
|
const tree = parseSource12(makeGoParser4(), file.content);
|
|
14667
14796
|
const { structs, models, tableFor } = analyze(tree);
|
|
@@ -14676,7 +14805,7 @@ function gormForeignKeys(file, serviceDir) {
|
|
|
14676
14805
|
childTable,
|
|
14677
14806
|
parentTable,
|
|
14678
14807
|
evidence: {
|
|
14679
|
-
file: toPosix(
|
|
14808
|
+
file: toPosix(import_node_path57.default.relative(serviceDir, file.path)),
|
|
14680
14809
|
line,
|
|
14681
14810
|
snippet: snippet(file.content, line)
|
|
14682
14811
|
}
|
|
@@ -14713,7 +14842,7 @@ function gormForeignKeys(file, serviceDir) {
|
|
|
14713
14842
|
|
|
14714
14843
|
// src/extract/calls/efcore.ts
|
|
14715
14844
|
init_cjs_shims();
|
|
14716
|
-
var
|
|
14845
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
14717
14846
|
var import_tree_sitter17 = __toESM(require("tree-sitter"), 1);
|
|
14718
14847
|
var import_tree_sitter_c_sharp2 = __toESM(require("tree-sitter-c-sharp"), 1);
|
|
14719
14848
|
var import_types44 = require("@neat.is/types");
|
|
@@ -14792,7 +14921,7 @@ function tableFromToTable(call) {
|
|
|
14792
14921
|
return value ? csStringLiteral(value) : null;
|
|
14793
14922
|
}
|
|
14794
14923
|
function efcoreEndpointsFromFile(file, serviceDir) {
|
|
14795
|
-
if (
|
|
14924
|
+
if (import_node_path58.default.extname(file.path) !== ".cs") return [];
|
|
14796
14925
|
if (!EFCORE_GATE.test(file.content)) return [];
|
|
14797
14926
|
const tree = parseSource13(makeCsParser(), file.content);
|
|
14798
14927
|
const out = [];
|
|
@@ -14807,7 +14936,7 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
14807
14936
|
edgeType: "CALLS",
|
|
14808
14937
|
confidenceKind: "structural",
|
|
14809
14938
|
evidence: {
|
|
14810
|
-
file: toPosix(
|
|
14939
|
+
file: toPosix(import_node_path58.default.relative(serviceDir, file.path)),
|
|
14811
14940
|
line,
|
|
14812
14941
|
snippet: snippet(file.content, line)
|
|
14813
14942
|
}
|
|
@@ -15062,7 +15191,7 @@ init_cjs_shims();
|
|
|
15062
15191
|
|
|
15063
15192
|
// src/extract/infra/docker-compose.ts
|
|
15064
15193
|
init_cjs_shims();
|
|
15065
|
-
var
|
|
15194
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
15066
15195
|
var import_types48 = require("@neat.is/types");
|
|
15067
15196
|
|
|
15068
15197
|
// src/extract/infra/shared.ts
|
|
@@ -15133,7 +15262,7 @@ function dependsOnList(value) {
|
|
|
15133
15262
|
}
|
|
15134
15263
|
function serviceNameToServiceNode(name, services) {
|
|
15135
15264
|
for (const s of services) {
|
|
15136
|
-
if (s.node.name === name ||
|
|
15265
|
+
if (s.node.name === name || import_node_path59.default.basename(s.dir) === name) return s.node.id;
|
|
15137
15266
|
}
|
|
15138
15267
|
return null;
|
|
15139
15268
|
}
|
|
@@ -15142,7 +15271,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15142
15271
|
let edgesAdded = 0;
|
|
15143
15272
|
let composePath = null;
|
|
15144
15273
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
15145
|
-
const abs =
|
|
15274
|
+
const abs = import_node_path59.default.join(scanPath, name);
|
|
15146
15275
|
if (await exists(abs)) {
|
|
15147
15276
|
composePath = abs;
|
|
15148
15277
|
break;
|
|
@@ -15155,13 +15284,13 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15155
15284
|
} catch (err) {
|
|
15156
15285
|
recordExtractionError(
|
|
15157
15286
|
"infra docker-compose",
|
|
15158
|
-
|
|
15287
|
+
import_node_path59.default.relative(scanPath, composePath),
|
|
15159
15288
|
err
|
|
15160
15289
|
);
|
|
15161
15290
|
return { nodesAdded, edgesAdded };
|
|
15162
15291
|
}
|
|
15163
15292
|
if (!compose?.services) return { nodesAdded, edgesAdded };
|
|
15164
|
-
const evidenceFile =
|
|
15293
|
+
const evidenceFile = import_node_path59.default.relative(scanPath, composePath).split(import_node_path59.default.sep).join("/");
|
|
15165
15294
|
const composeNameToNodeId = /* @__PURE__ */ new Map();
|
|
15166
15295
|
for (const [composeName, svc] of Object.entries(compose.services)) {
|
|
15167
15296
|
const matchedServiceId = serviceNameToServiceNode(composeName, services);
|
|
@@ -15203,8 +15332,8 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15203
15332
|
|
|
15204
15333
|
// src/extract/infra/dockerfile.ts
|
|
15205
15334
|
init_cjs_shims();
|
|
15206
|
-
var
|
|
15207
|
-
var
|
|
15335
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
15336
|
+
var import_node_fs26 = require("fs");
|
|
15208
15337
|
var import_types49 = require("@neat.is/types");
|
|
15209
15338
|
function readDockerfile(content) {
|
|
15210
15339
|
let image = null;
|
|
@@ -15234,15 +15363,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15234
15363
|
let nodesAdded = 0;
|
|
15235
15364
|
let edgesAdded = 0;
|
|
15236
15365
|
for (const service of services) {
|
|
15237
|
-
const dockerfilePath =
|
|
15366
|
+
const dockerfilePath = import_node_path60.default.join(service.dir, "Dockerfile");
|
|
15238
15367
|
if (!await exists(dockerfilePath)) continue;
|
|
15239
15368
|
let content;
|
|
15240
15369
|
try {
|
|
15241
|
-
content = await
|
|
15370
|
+
content = await import_node_fs26.promises.readFile(dockerfilePath, "utf8");
|
|
15242
15371
|
} catch (err) {
|
|
15243
15372
|
recordExtractionError(
|
|
15244
15373
|
"infra dockerfile",
|
|
15245
|
-
|
|
15374
|
+
import_node_path60.default.relative(scanPath, dockerfilePath),
|
|
15246
15375
|
err
|
|
15247
15376
|
);
|
|
15248
15377
|
continue;
|
|
@@ -15254,8 +15383,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15254
15383
|
graph.addNode(node.id, node);
|
|
15255
15384
|
nodesAdded++;
|
|
15256
15385
|
}
|
|
15257
|
-
const relDockerfile = toPosix(
|
|
15258
|
-
const evidenceFile = toPosix(
|
|
15386
|
+
const relDockerfile = toPosix(import_node_path60.default.relative(service.dir, dockerfilePath));
|
|
15387
|
+
const evidenceFile = toPosix(import_node_path60.default.relative(scanPath, dockerfilePath));
|
|
15259
15388
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
15260
15389
|
graph,
|
|
15261
15390
|
service.pkg.name,
|
|
@@ -15307,23 +15436,23 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15307
15436
|
|
|
15308
15437
|
// src/extract/infra/terraform.ts
|
|
15309
15438
|
init_cjs_shims();
|
|
15310
|
-
var
|
|
15311
|
-
var
|
|
15439
|
+
var import_node_fs27 = require("fs");
|
|
15440
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
15312
15441
|
var import_types50 = require("@neat.is/types");
|
|
15313
15442
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
15314
15443
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
15315
15444
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
15316
15445
|
if (depth > max) return [];
|
|
15317
15446
|
const out = [];
|
|
15318
|
-
const entries = await
|
|
15447
|
+
const entries = await import_node_fs27.promises.readdir(start, { withFileTypes: true }).catch(() => []);
|
|
15319
15448
|
for (const entry of entries) {
|
|
15320
15449
|
if (entry.isDirectory()) {
|
|
15321
15450
|
if (IGNORED_DIRS.has(entry.name) || entry.name === ".terraform") continue;
|
|
15322
|
-
const child =
|
|
15451
|
+
const child = import_node_path61.default.join(start, entry.name);
|
|
15323
15452
|
if (await isPythonVenvDir(child)) continue;
|
|
15324
15453
|
out.push(...await walkTfFiles(child, depth + 1, max));
|
|
15325
15454
|
} else if (entry.isFile() && entry.name.endsWith(".tf")) {
|
|
15326
|
-
out.push(
|
|
15455
|
+
out.push(import_node_path61.default.join(start, entry.name));
|
|
15327
15456
|
}
|
|
15328
15457
|
}
|
|
15329
15458
|
return out;
|
|
@@ -15354,8 +15483,8 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15354
15483
|
let edgesAdded = 0;
|
|
15355
15484
|
const files = await walkTfFiles(scanPath);
|
|
15356
15485
|
for (const file of files) {
|
|
15357
|
-
const content = await
|
|
15358
|
-
const evidenceFile = toPosix(
|
|
15486
|
+
const content = await import_node_fs27.promises.readFile(file, "utf8");
|
|
15487
|
+
const evidenceFile = toPosix(import_node_path61.default.relative(scanPath, file));
|
|
15359
15488
|
const resources = [];
|
|
15360
15489
|
const byKey = /* @__PURE__ */ new Map();
|
|
15361
15490
|
RESOURCE_RE.lastIndex = 0;
|
|
@@ -15412,8 +15541,8 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15412
15541
|
|
|
15413
15542
|
// src/extract/infra/k8s.ts
|
|
15414
15543
|
init_cjs_shims();
|
|
15415
|
-
var
|
|
15416
|
-
var
|
|
15544
|
+
var import_node_fs28 = require("fs");
|
|
15545
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
15417
15546
|
var import_yaml3 = require("yaml");
|
|
15418
15547
|
var import_types51 = require("@neat.is/types");
|
|
15419
15548
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
@@ -15429,15 +15558,15 @@ var WORKLOAD_KINDS = /* @__PURE__ */ new Set(["Deployment", "StatefulSet", "Daem
|
|
|
15429
15558
|
async function walkYamlFiles2(start, depth = 0, max = 5) {
|
|
15430
15559
|
if (depth > max) return [];
|
|
15431
15560
|
const out = [];
|
|
15432
|
-
const entries = await
|
|
15561
|
+
const entries = await import_node_fs28.promises.readdir(start, { withFileTypes: true }).catch(() => []);
|
|
15433
15562
|
for (const entry of entries) {
|
|
15434
15563
|
if (entry.isDirectory()) {
|
|
15435
15564
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
15436
|
-
const child =
|
|
15565
|
+
const child = import_node_path62.default.join(start, entry.name);
|
|
15437
15566
|
if (await isPythonVenvDir(child)) continue;
|
|
15438
15567
|
out.push(...await walkYamlFiles2(child, depth + 1, max));
|
|
15439
|
-
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(
|
|
15440
|
-
out.push(
|
|
15568
|
+
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path62.default.extname(entry.name))) {
|
|
15569
|
+
out.push(import_node_path62.default.join(start, entry.name));
|
|
15441
15570
|
}
|
|
15442
15571
|
}
|
|
15443
15572
|
return out;
|
|
@@ -15447,14 +15576,14 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15447
15576
|
let edgesAdded = 0;
|
|
15448
15577
|
const files = await walkYamlFiles2(scanPath);
|
|
15449
15578
|
for (const file of files) {
|
|
15450
|
-
const content = await
|
|
15579
|
+
const content = await import_node_fs28.promises.readFile(file, "utf8");
|
|
15451
15580
|
let docs;
|
|
15452
15581
|
try {
|
|
15453
15582
|
docs = (0, import_yaml3.parseAllDocuments)(content).map((d) => d.toJSON());
|
|
15454
15583
|
} catch {
|
|
15455
15584
|
continue;
|
|
15456
15585
|
}
|
|
15457
|
-
const relFile = toPosix(
|
|
15586
|
+
const relFile = toPosix(import_node_path62.default.relative(scanPath, file));
|
|
15458
15587
|
for (const doc of docs) {
|
|
15459
15588
|
if (!doc?.kind || !doc.metadata?.name) continue;
|
|
15460
15589
|
const infraKind = K8S_KIND_TO_INFRA_KIND[doc.kind];
|
|
@@ -15503,16 +15632,16 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15503
15632
|
|
|
15504
15633
|
// src/extract/infra/cloudflare.ts
|
|
15505
15634
|
init_cjs_shims();
|
|
15506
|
-
var
|
|
15507
|
-
var
|
|
15635
|
+
var import_node_fs29 = require("fs");
|
|
15636
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
15508
15637
|
var import_smol_toml3 = require("smol-toml");
|
|
15509
15638
|
var import_types52 = require("@neat.is/types");
|
|
15510
15639
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
15511
15640
|
async function readWranglerConfig(dir) {
|
|
15512
15641
|
for (const filename of WRANGLER_FILENAMES) {
|
|
15513
|
-
const abs =
|
|
15642
|
+
const abs = import_node_path63.default.join(dir, filename);
|
|
15514
15643
|
if (!await exists(abs)) continue;
|
|
15515
|
-
const raw = await
|
|
15644
|
+
const raw = await import_node_fs29.promises.readFile(abs, "utf8");
|
|
15516
15645
|
const config = filename === "wrangler.toml" ? (0, import_smol_toml3.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
15517
15646
|
return { config, relFile: filename, raw };
|
|
15518
15647
|
}
|
|
@@ -15573,11 +15702,11 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15573
15702
|
try {
|
|
15574
15703
|
read = await readWranglerConfig(service.dir);
|
|
15575
15704
|
} catch (err) {
|
|
15576
|
-
recordExtractionError("infra cloudflare",
|
|
15705
|
+
recordExtractionError("infra cloudflare", import_node_path63.default.relative(scanPath, service.dir), err);
|
|
15577
15706
|
continue;
|
|
15578
15707
|
}
|
|
15579
15708
|
if (!read || !read.config.name) continue;
|
|
15580
|
-
const evidenceFile = toPosix(
|
|
15709
|
+
const evidenceFile = toPosix(import_node_path63.default.relative(scanPath, import_node_path63.default.join(service.dir, read.relFile)));
|
|
15581
15710
|
discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
|
|
15582
15711
|
}
|
|
15583
15712
|
for (const worker of discovered) {
|
|
@@ -15589,7 +15718,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15589
15718
|
}
|
|
15590
15719
|
let anchorId = service.node.id;
|
|
15591
15720
|
if (config.main) {
|
|
15592
|
-
const entryRelPath = toPosix(
|
|
15721
|
+
const entryRelPath = toPosix(import_node_path63.default.normalize(config.main));
|
|
15593
15722
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
15594
15723
|
graph,
|
|
15595
15724
|
service.pkg.name,
|
|
@@ -15736,24 +15865,24 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15736
15865
|
|
|
15737
15866
|
// src/extract/infra/vercel.ts
|
|
15738
15867
|
init_cjs_shims();
|
|
15739
|
-
var
|
|
15740
|
-
var
|
|
15868
|
+
var import_node_fs30 = require("fs");
|
|
15869
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
15741
15870
|
var import_types53 = require("@neat.is/types");
|
|
15742
15871
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
15743
15872
|
async function readVercelConfig(dir) {
|
|
15744
15873
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
15745
|
-
const abs =
|
|
15874
|
+
const abs = import_node_path64.default.join(dir, filename);
|
|
15746
15875
|
if (!await exists(abs)) continue;
|
|
15747
|
-
const raw = await
|
|
15876
|
+
const raw = await import_node_fs30.promises.readFile(abs, "utf8");
|
|
15748
15877
|
const config = JSON.parse(maskCommentsInSource(raw));
|
|
15749
15878
|
return { config, relFile: filename, raw };
|
|
15750
15879
|
}
|
|
15751
15880
|
return null;
|
|
15752
15881
|
}
|
|
15753
15882
|
async function readLinkedProjectName(dir) {
|
|
15754
|
-
const abs =
|
|
15883
|
+
const abs = import_node_path64.default.join(dir, ".vercel", "project.json");
|
|
15755
15884
|
if (!await exists(abs)) return void 0;
|
|
15756
|
-
const parsed = JSON.parse(await
|
|
15885
|
+
const parsed = JSON.parse(await import_node_fs30.promises.readFile(abs, "utf8"));
|
|
15757
15886
|
return typeof parsed.projectName === "string" ? parsed.projectName : void 0;
|
|
15758
15887
|
}
|
|
15759
15888
|
function routeSource(route) {
|
|
@@ -15769,7 +15898,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
15769
15898
|
read = await readVercelConfig(service.dir);
|
|
15770
15899
|
projectName = await readLinkedProjectName(service.dir);
|
|
15771
15900
|
} catch (err) {
|
|
15772
|
-
recordExtractionError("infra vercel",
|
|
15901
|
+
recordExtractionError("infra vercel", import_node_path64.default.relative(scanPath, service.dir), err);
|
|
15773
15902
|
continue;
|
|
15774
15903
|
}
|
|
15775
15904
|
if (!read && !projectName) continue;
|
|
@@ -15785,7 +15914,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
15785
15914
|
const anchorId = service.node.id;
|
|
15786
15915
|
if (!read) continue;
|
|
15787
15916
|
const { config, relFile, raw } = read;
|
|
15788
|
-
const evidenceFile = toPosix(
|
|
15917
|
+
const evidenceFile = toPosix(import_node_path64.default.relative(scanPath, import_node_path64.default.join(service.dir, relFile)));
|
|
15789
15918
|
const add = (edgeType, kind, name) => {
|
|
15790
15919
|
if (!name) return;
|
|
15791
15920
|
const result = emitPlatformResourceEdge(
|
|
@@ -15814,16 +15943,16 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
15814
15943
|
|
|
15815
15944
|
// src/extract/infra/railway.ts
|
|
15816
15945
|
init_cjs_shims();
|
|
15817
|
-
var
|
|
15818
|
-
var
|
|
15946
|
+
var import_node_fs31 = require("fs");
|
|
15947
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
15819
15948
|
var import_smol_toml4 = require("smol-toml");
|
|
15820
15949
|
var import_types54 = require("@neat.is/types");
|
|
15821
15950
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
15822
15951
|
async function readRailwayConfig(dir) {
|
|
15823
15952
|
for (const filename of RAILWAY_FILENAMES) {
|
|
15824
|
-
const abs =
|
|
15953
|
+
const abs = import_node_path65.default.join(dir, filename);
|
|
15825
15954
|
if (!await exists(abs)) continue;
|
|
15826
|
-
const raw = await
|
|
15955
|
+
const raw = await import_node_fs31.promises.readFile(abs, "utf8");
|
|
15827
15956
|
const config = filename === "railway.toml" ? (0, import_smol_toml4.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
15828
15957
|
return { config, relFile: filename, raw };
|
|
15829
15958
|
}
|
|
@@ -15837,7 +15966,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
15837
15966
|
try {
|
|
15838
15967
|
read = await readRailwayConfig(service.dir);
|
|
15839
15968
|
} catch (err) {
|
|
15840
|
-
recordExtractionError("infra railway",
|
|
15969
|
+
recordExtractionError("infra railway", import_node_path65.default.relative(scanPath, service.dir), err);
|
|
15841
15970
|
continue;
|
|
15842
15971
|
}
|
|
15843
15972
|
if (!read) continue;
|
|
@@ -15847,7 +15976,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
15847
15976
|
}
|
|
15848
15977
|
const anchorId = service.node.id;
|
|
15849
15978
|
const { config, relFile, raw } = read;
|
|
15850
|
-
const evidenceFile = toPosix(
|
|
15979
|
+
const evidenceFile = toPosix(import_node_path65.default.relative(scanPath, import_node_path65.default.join(service.dir, relFile)));
|
|
15851
15980
|
const add = (edgeType, kind, name) => {
|
|
15852
15981
|
if (!name) return;
|
|
15853
15982
|
const result = emitPlatformResourceEdge(
|
|
@@ -15872,15 +16001,15 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
15872
16001
|
|
|
15873
16002
|
// src/extract/infra/supabase.ts
|
|
15874
16003
|
init_cjs_shims();
|
|
15875
|
-
var
|
|
15876
|
-
var
|
|
16004
|
+
var import_node_fs32 = require("fs");
|
|
16005
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
15877
16006
|
var import_smol_toml5 = require("smol-toml");
|
|
15878
16007
|
var import_types55 = require("@neat.is/types");
|
|
15879
16008
|
async function readSupabaseConfig(dir) {
|
|
15880
|
-
const relFile =
|
|
15881
|
-
const abs =
|
|
16009
|
+
const relFile = import_node_path66.default.join("supabase", "config.toml");
|
|
16010
|
+
const abs = import_node_path66.default.join(dir, relFile);
|
|
15882
16011
|
if (!await exists(abs)) return null;
|
|
15883
|
-
const raw = await
|
|
16012
|
+
const raw = await import_node_fs32.promises.readFile(abs, "utf8");
|
|
15884
16013
|
const config = (0, import_smol_toml5.parse)(raw);
|
|
15885
16014
|
return { config, relFile, raw };
|
|
15886
16015
|
}
|
|
@@ -15892,7 +16021,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
15892
16021
|
try {
|
|
15893
16022
|
read = await readSupabaseConfig(service.dir);
|
|
15894
16023
|
} catch (err) {
|
|
15895
|
-
recordExtractionError("infra supabase",
|
|
16024
|
+
recordExtractionError("infra supabase", import_node_path66.default.relative(scanPath, service.dir), err);
|
|
15896
16025
|
continue;
|
|
15897
16026
|
}
|
|
15898
16027
|
if (!read) continue;
|
|
@@ -15907,7 +16036,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
15907
16036
|
});
|
|
15908
16037
|
}
|
|
15909
16038
|
const anchorId = service.node.id;
|
|
15910
|
-
const evidenceFile = toPosix(
|
|
16039
|
+
const evidenceFile = toPosix(import_node_path66.default.relative(scanPath, import_node_path66.default.join(service.dir, relFile)));
|
|
15911
16040
|
const add = (edgeType, kind, name) => {
|
|
15912
16041
|
if (!name) return;
|
|
15913
16042
|
const result = emitPlatformResourceEdge(
|
|
@@ -15949,7 +16078,7 @@ async function addInfra(graph, scanPath, services) {
|
|
|
15949
16078
|
|
|
15950
16079
|
// src/extract/zod-shapes.ts
|
|
15951
16080
|
init_cjs_shims();
|
|
15952
|
-
var
|
|
16081
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
15953
16082
|
var import_tree_sitter18 = __toESM(require("tree-sitter"), 1);
|
|
15954
16083
|
var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
|
|
15955
16084
|
var import_types56 = require("@neat.is/types");
|
|
@@ -16044,7 +16173,7 @@ function topLevelSchemas(root) {
|
|
|
16044
16173
|
}
|
|
16045
16174
|
function zodShapesFromFile(file, serviceDir) {
|
|
16046
16175
|
if (!ZOD_IMPORT_RE.test(file.content)) return [];
|
|
16047
|
-
const tree = parseSource3(parserForExt4(
|
|
16176
|
+
const tree = parseSource3(parserForExt4(import_node_path67.default.extname(file.path)), file.content);
|
|
16048
16177
|
const out = [];
|
|
16049
16178
|
const seen = /* @__PURE__ */ new Set();
|
|
16050
16179
|
for (const { name, call } of topLevelSchemas(tree.rootNode)) {
|
|
@@ -16062,7 +16191,7 @@ function zodShapesFromFile(file, serviceDir) {
|
|
|
16062
16191
|
name,
|
|
16063
16192
|
fields,
|
|
16064
16193
|
evidence: {
|
|
16065
|
-
file:
|
|
16194
|
+
file: import_node_path67.default.relative(serviceDir, file.path),
|
|
16066
16195
|
line,
|
|
16067
16196
|
snippet: snippet(file.content, line)
|
|
16068
16197
|
}
|
|
@@ -16330,12 +16459,12 @@ async function addFirestoreRules(graph, services) {
|
|
|
16330
16459
|
}
|
|
16331
16460
|
|
|
16332
16461
|
// src/extract/index.ts
|
|
16333
|
-
var
|
|
16462
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
16334
16463
|
|
|
16335
16464
|
// src/extract/retire.ts
|
|
16336
16465
|
init_cjs_shims();
|
|
16337
|
-
var
|
|
16338
|
-
var
|
|
16466
|
+
var import_node_fs33 = require("fs");
|
|
16467
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
16339
16468
|
var import_types58 = require("@neat.is/types");
|
|
16340
16469
|
function dropOrphanedFileNodes(graph) {
|
|
16341
16470
|
const orphans = [];
|
|
@@ -16356,11 +16485,11 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
|
|
|
16356
16485
|
if (edge.provenance !== import_types58.Provenance.EXTRACTED) return;
|
|
16357
16486
|
const evidenceFile = edge.evidence?.file;
|
|
16358
16487
|
if (!evidenceFile) return;
|
|
16359
|
-
if (
|
|
16360
|
-
if (!(0,
|
|
16488
|
+
if (import_node_path68.default.isAbsolute(evidenceFile)) {
|
|
16489
|
+
if (!(0, import_node_fs33.existsSync)(evidenceFile)) toDrop.push(id);
|
|
16361
16490
|
return;
|
|
16362
16491
|
}
|
|
16363
|
-
const found = bases.some((base) => (0,
|
|
16492
|
+
const found = bases.some((base) => (0, import_node_fs33.existsSync)(import_node_path68.default.join(base, evidenceFile)));
|
|
16364
16493
|
if (!found) toDrop.push(id);
|
|
16365
16494
|
});
|
|
16366
16495
|
for (const id of toDrop) graph.dropEdge(id);
|
|
@@ -16372,6 +16501,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
|
|
|
16372
16501
|
async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
16373
16502
|
await ensureCompatLoaded();
|
|
16374
16503
|
drainExtractionErrors();
|
|
16504
|
+
drainSkippedFiles();
|
|
16375
16505
|
const services = await discoverServices(scanPath);
|
|
16376
16506
|
const phase1Nodes = addServiceNodes(graph, services);
|
|
16377
16507
|
await addServiceAliases(graph, scanPath, services);
|
|
@@ -16416,8 +16546,9 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
16416
16546
|
}
|
|
16417
16547
|
}
|
|
16418
16548
|
const droppedEntries = drainDroppedExtracted();
|
|
16549
|
+
const skippedEntries = drainSkippedFiles();
|
|
16419
16550
|
if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
|
|
16420
|
-
const rejectedPath =
|
|
16551
|
+
const rejectedPath = import_node_path69.default.join(import_node_path69.default.dirname(opts.errorsPath), "rejected.ndjson");
|
|
16421
16552
|
try {
|
|
16422
16553
|
await writeRejectedExtracted(droppedEntries, rejectedPath);
|
|
16423
16554
|
} catch (err) {
|
|
@@ -16434,7 +16565,9 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
16434
16565
|
errorEntries,
|
|
16435
16566
|
ghostsRetired,
|
|
16436
16567
|
extractedDropped: droppedEntries.length,
|
|
16437
|
-
droppedEntries
|
|
16568
|
+
droppedEntries,
|
|
16569
|
+
skippedFiles: skippedEntries.length,
|
|
16570
|
+
skippedEntries
|
|
16438
16571
|
};
|
|
16439
16572
|
emitNeatEvent({
|
|
16440
16573
|
type: "extraction-complete",
|
|
@@ -16451,8 +16584,8 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
16451
16584
|
|
|
16452
16585
|
// src/persist.ts
|
|
16453
16586
|
init_cjs_shims();
|
|
16454
|
-
var
|
|
16455
|
-
var
|
|
16587
|
+
var import_node_fs34 = require("fs");
|
|
16588
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
16456
16589
|
var import_types59 = require("@neat.is/types");
|
|
16457
16590
|
var SCHEMA_VERSION = 7;
|
|
16458
16591
|
function migrateV1ToV2(payload) {
|
|
@@ -16507,7 +16640,43 @@ function migrateV2ToV3(payload) {
|
|
|
16507
16640
|
return { ...payload, schemaVersion: 3 };
|
|
16508
16641
|
}
|
|
16509
16642
|
async function ensureDir(filePath) {
|
|
16510
|
-
await
|
|
16643
|
+
await import_node_fs34.promises.mkdir(import_node_path70.default.dirname(filePath), { recursive: true });
|
|
16644
|
+
}
|
|
16645
|
+
var WRITE_FLUSH_CHARS = 4 * 1024 * 1024;
|
|
16646
|
+
function jsonOrUndefined(value) {
|
|
16647
|
+
return JSON.stringify(value);
|
|
16648
|
+
}
|
|
16649
|
+
function* serializeArray(items) {
|
|
16650
|
+
yield "[";
|
|
16651
|
+
for (let i = 0; i < items.length; i++) {
|
|
16652
|
+
if (i > 0) yield ",";
|
|
16653
|
+
yield jsonOrUndefined(items[i]) ?? "null";
|
|
16654
|
+
}
|
|
16655
|
+
yield "]";
|
|
16656
|
+
}
|
|
16657
|
+
function isPlainObject(value) {
|
|
16658
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
16659
|
+
const proto = Object.getPrototypeOf(value);
|
|
16660
|
+
return proto === Object.prototype || proto === null;
|
|
16661
|
+
}
|
|
16662
|
+
function* serializeObject(obj) {
|
|
16663
|
+
yield "{";
|
|
16664
|
+
let first = true;
|
|
16665
|
+
for (const key of Object.keys(obj)) {
|
|
16666
|
+
const value = obj[key];
|
|
16667
|
+
const descend = Array.isArray(value) || isPlainObject(value);
|
|
16668
|
+
if (!descend && jsonOrUndefined(value) === void 0) continue;
|
|
16669
|
+
if (!first) yield ",";
|
|
16670
|
+
first = false;
|
|
16671
|
+
yield `${JSON.stringify(key)}:`;
|
|
16672
|
+
if (Array.isArray(value)) yield* serializeArray(value);
|
|
16673
|
+
else if (isPlainObject(value)) yield* serializeObject(value);
|
|
16674
|
+
else yield jsonOrUndefined(value);
|
|
16675
|
+
}
|
|
16676
|
+
yield "}";
|
|
16677
|
+
}
|
|
16678
|
+
function* serializeGraphChunks(payload) {
|
|
16679
|
+
yield* serializeObject(payload);
|
|
16511
16680
|
}
|
|
16512
16681
|
async function saveGraphToDisk(graph, outPath) {
|
|
16513
16682
|
await ensureDir(outPath);
|
|
@@ -16517,13 +16686,26 @@ async function saveGraphToDisk(graph, outPath) {
|
|
|
16517
16686
|
graph: graph.export()
|
|
16518
16687
|
};
|
|
16519
16688
|
const tmp = `${outPath}.tmp`;
|
|
16520
|
-
await
|
|
16521
|
-
|
|
16689
|
+
const handle = await import_node_fs34.promises.open(tmp, "w");
|
|
16690
|
+
try {
|
|
16691
|
+
let buffered = "";
|
|
16692
|
+
for (const chunk of serializeGraphChunks(payload)) {
|
|
16693
|
+
buffered += chunk;
|
|
16694
|
+
if (buffered.length >= WRITE_FLUSH_CHARS) {
|
|
16695
|
+
await handle.write(buffered, null, "utf8");
|
|
16696
|
+
buffered = "";
|
|
16697
|
+
}
|
|
16698
|
+
}
|
|
16699
|
+
if (buffered.length > 0) await handle.write(buffered, null, "utf8");
|
|
16700
|
+
} finally {
|
|
16701
|
+
await handle.close();
|
|
16702
|
+
}
|
|
16703
|
+
await import_node_fs34.promises.rename(tmp, outPath);
|
|
16522
16704
|
}
|
|
16523
16705
|
async function loadGraphFromDisk(graph, outPath) {
|
|
16524
16706
|
let raw;
|
|
16525
16707
|
try {
|
|
16526
|
-
raw = await
|
|
16708
|
+
raw = await import_node_fs34.promises.readFile(outPath, "utf8");
|
|
16527
16709
|
} catch (err) {
|
|
16528
16710
|
if (err.code === "ENOENT") return;
|
|
16529
16711
|
throw err;
|
|
@@ -16603,15 +16785,15 @@ var import_types101 = require("@neat.is/types");
|
|
|
16603
16785
|
|
|
16604
16786
|
// src/extend/index.ts
|
|
16605
16787
|
init_cjs_shims();
|
|
16606
|
-
var
|
|
16607
|
-
var
|
|
16788
|
+
var import_node_fs36 = require("fs");
|
|
16789
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
16608
16790
|
var import_node_os2 = __toESM(require("os"), 1);
|
|
16609
16791
|
var import_instrumentation_registry = require("@neat.is/instrumentation-registry");
|
|
16610
16792
|
|
|
16611
16793
|
// src/installers/package-manager.ts
|
|
16612
16794
|
init_cjs_shims();
|
|
16613
|
-
var
|
|
16614
|
-
var
|
|
16795
|
+
var import_node_fs35 = require("fs");
|
|
16796
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
16615
16797
|
var import_node_child_process = require("child_process");
|
|
16616
16798
|
var LOCKFILE_PRIORITY = [
|
|
16617
16799
|
{ lockfile: "bun.lockb", pm: "bun", args: ["install", "--no-summary"] },
|
|
@@ -16626,29 +16808,29 @@ var LOCKFILE_PRIORITY = [
|
|
|
16626
16808
|
var NPM_FALLBACK_ARGS = ["install", "--no-audit", "--no-fund", "--prefer-offline"];
|
|
16627
16809
|
async function exists2(p) {
|
|
16628
16810
|
try {
|
|
16629
|
-
await
|
|
16811
|
+
await import_node_fs35.promises.access(p);
|
|
16630
16812
|
return true;
|
|
16631
16813
|
} catch {
|
|
16632
16814
|
return false;
|
|
16633
16815
|
}
|
|
16634
16816
|
}
|
|
16635
16817
|
async function detectPackageManager(serviceDir) {
|
|
16636
|
-
let dir =
|
|
16818
|
+
let dir = import_node_path71.default.resolve(serviceDir);
|
|
16637
16819
|
const stops = /* @__PURE__ */ new Set();
|
|
16638
16820
|
for (let i = 0; i < 64; i++) {
|
|
16639
16821
|
if (stops.has(dir)) break;
|
|
16640
16822
|
stops.add(dir);
|
|
16641
16823
|
for (const candidate of LOCKFILE_PRIORITY) {
|
|
16642
|
-
const lockPath =
|
|
16824
|
+
const lockPath = import_node_path71.default.join(dir, candidate.lockfile);
|
|
16643
16825
|
if (await exists2(lockPath)) {
|
|
16644
16826
|
return { pm: candidate.pm, cwd: dir, args: [...candidate.args] };
|
|
16645
16827
|
}
|
|
16646
16828
|
}
|
|
16647
|
-
const parent =
|
|
16829
|
+
const parent = import_node_path71.default.dirname(dir);
|
|
16648
16830
|
if (parent === dir) break;
|
|
16649
16831
|
dir = parent;
|
|
16650
16832
|
}
|
|
16651
|
-
return { pm: "npm", cwd:
|
|
16833
|
+
return { pm: "npm", cwd: import_node_path71.default.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
|
|
16652
16834
|
}
|
|
16653
16835
|
async function runPackageManagerInstall(cmd) {
|
|
16654
16836
|
return new Promise((resolve) => {
|
|
@@ -16690,15 +16872,15 @@ ${err.message}`
|
|
|
16690
16872
|
// src/extend/index.ts
|
|
16691
16873
|
async function fileExists2(p) {
|
|
16692
16874
|
try {
|
|
16693
|
-
await
|
|
16875
|
+
await import_node_fs36.promises.access(p);
|
|
16694
16876
|
return true;
|
|
16695
16877
|
} catch {
|
|
16696
16878
|
return false;
|
|
16697
16879
|
}
|
|
16698
16880
|
}
|
|
16699
16881
|
async function readPackageJson(scanPath) {
|
|
16700
|
-
const pkgPath =
|
|
16701
|
-
const raw = await
|
|
16882
|
+
const pkgPath = import_node_path72.default.join(scanPath, "package.json");
|
|
16883
|
+
const raw = await import_node_fs36.promises.readFile(pkgPath, "utf8");
|
|
16702
16884
|
return JSON.parse(raw);
|
|
16703
16885
|
}
|
|
16704
16886
|
var HOOK_WALK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -16712,15 +16894,15 @@ var HOOK_WALK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
16712
16894
|
async function findHookFiles(scanPath) {
|
|
16713
16895
|
const found = [];
|
|
16714
16896
|
const walk11 = async (dir) => {
|
|
16715
|
-
const entries = await
|
|
16897
|
+
const entries = await import_node_fs36.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
16716
16898
|
for (const entry of entries) {
|
|
16717
16899
|
if (entry.isDirectory()) {
|
|
16718
16900
|
if (entry.name.startsWith(".") || HOOK_WALK_SKIP_DIRS.has(entry.name)) continue;
|
|
16719
|
-
await walk11(
|
|
16901
|
+
await walk11(import_node_path72.default.join(dir, entry.name));
|
|
16720
16902
|
} else if (entry.isFile()) {
|
|
16721
16903
|
if ((entry.name.startsWith("instrumentation") || entry.name.startsWith("otel-init")) && /\.(ts|js|cjs|mjs)$/.test(entry.name)) {
|
|
16722
|
-
const rel =
|
|
16723
|
-
found.push(rel.split(
|
|
16904
|
+
const rel = import_node_path72.default.relative(scanPath, import_node_path72.default.join(dir, entry.name));
|
|
16905
|
+
found.push(rel.split(import_node_path72.default.sep).join("/"));
|
|
16724
16906
|
}
|
|
16725
16907
|
}
|
|
16726
16908
|
}
|
|
@@ -16731,7 +16913,7 @@ async function findHookFiles(scanPath) {
|
|
|
16731
16913
|
async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
|
|
16732
16914
|
let fallback = null;
|
|
16733
16915
|
for (const file of hookFiles) {
|
|
16734
|
-
const content = await
|
|
16916
|
+
const content = await import_node_fs36.promises.readFile(import_node_path72.default.join(scanPath, file), "utf8");
|
|
16735
16917
|
const patched = splicedContent(content, snippet2);
|
|
16736
16918
|
if (patched !== null) return { file, content, patched };
|
|
16737
16919
|
if (fallback === null) fallback = { file, content };
|
|
@@ -16739,12 +16921,12 @@ async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
|
|
|
16739
16921
|
return { file: fallback.file, content: fallback.content, patched: null };
|
|
16740
16922
|
}
|
|
16741
16923
|
function extendLogPath() {
|
|
16742
|
-
return process.env.NEAT_EXTEND_LOG ??
|
|
16924
|
+
return process.env.NEAT_EXTEND_LOG ?? import_node_path72.default.join(import_node_os2.default.homedir(), ".neat", "extend-log.ndjson");
|
|
16743
16925
|
}
|
|
16744
16926
|
async function appendExtendLog(entry) {
|
|
16745
16927
|
const logPath = extendLogPath();
|
|
16746
|
-
await
|
|
16747
|
-
await
|
|
16928
|
+
await import_node_fs36.promises.mkdir(import_node_path72.default.dirname(logPath), { recursive: true });
|
|
16929
|
+
await import_node_fs36.promises.appendFile(logPath, JSON.stringify(entry) + "\n", "utf8");
|
|
16748
16930
|
}
|
|
16749
16931
|
function splicedContent(fileContent, snippet2) {
|
|
16750
16932
|
if (fileContent.includes("__INSTRUMENTATION_BLOCK__")) {
|
|
@@ -16802,7 +16984,7 @@ function lookupInstrumentation(library, installedVersion) {
|
|
|
16802
16984
|
}
|
|
16803
16985
|
async function describeProjectInstrumentation(ctx) {
|
|
16804
16986
|
const hookFiles = await findHookFiles(ctx.scanPath);
|
|
16805
|
-
const envNeat = await fileExists2(
|
|
16987
|
+
const envNeat = await fileExists2(import_node_path72.default.join(ctx.scanPath, ".env.neat"));
|
|
16806
16988
|
const registryInstrPackages = new Set(
|
|
16807
16989
|
(0, import_instrumentation_registry.list)().map((e) => e.instrumentation_package).filter((p) => !!p)
|
|
16808
16990
|
);
|
|
@@ -16824,7 +17006,7 @@ async function applyExtension(ctx, args, options) {
|
|
|
16824
17006
|
);
|
|
16825
17007
|
}
|
|
16826
17008
|
for (const file of hookFiles) {
|
|
16827
|
-
const content = await
|
|
17009
|
+
const content = await import_node_fs36.promises.readFile(import_node_path72.default.join(ctx.scanPath, file), "utf8");
|
|
16828
17010
|
if (content.includes(args.registration_snippet)) {
|
|
16829
17011
|
return { library: args.library, filesTouched: [], depsAdded: [], installOutput: "", alreadyApplied: true };
|
|
16830
17012
|
}
|
|
@@ -16836,18 +17018,18 @@ async function applyExtension(ctx, args, options) {
|
|
|
16836
17018
|
);
|
|
16837
17019
|
}
|
|
16838
17020
|
const primaryFile = primary.file;
|
|
16839
|
-
const primaryPath =
|
|
17021
|
+
const primaryPath = import_node_path72.default.join(ctx.scanPath, primaryFile);
|
|
16840
17022
|
const filesTouched = [];
|
|
16841
17023
|
const depsAdded = [];
|
|
16842
|
-
const pkgPath =
|
|
17024
|
+
const pkgPath = import_node_path72.default.join(ctx.scanPath, "package.json");
|
|
16843
17025
|
const pkg = await readPackageJson(ctx.scanPath);
|
|
16844
17026
|
if (!(pkg.dependencies ?? {})[args.instrumentation_package]) {
|
|
16845
17027
|
pkg.dependencies = { ...pkg.dependencies ?? {}, [args.instrumentation_package]: args.version };
|
|
16846
|
-
await
|
|
17028
|
+
await import_node_fs36.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
16847
17029
|
filesTouched.push("package.json");
|
|
16848
17030
|
depsAdded.push(`${args.instrumentation_package}@${args.version}`);
|
|
16849
17031
|
}
|
|
16850
|
-
await
|
|
17032
|
+
await import_node_fs36.promises.writeFile(primaryPath, primary.patched, "utf8");
|
|
16851
17033
|
filesTouched.push(primaryFile);
|
|
16852
17034
|
const cmd = await detectPackageManager(ctx.scanPath);
|
|
16853
17035
|
const installer = options?.runInstall ?? runPackageManagerInstall;
|
|
@@ -16878,7 +17060,7 @@ async function dryRunExtension(ctx, args) {
|
|
|
16878
17060
|
};
|
|
16879
17061
|
}
|
|
16880
17062
|
for (const file of hookFiles) {
|
|
16881
|
-
const content = await
|
|
17063
|
+
const content = await import_node_fs36.promises.readFile(import_node_path72.default.join(ctx.scanPath, file), "utf8");
|
|
16882
17064
|
if (content.includes(args.registration_snippet)) {
|
|
16883
17065
|
return {
|
|
16884
17066
|
library: args.library,
|
|
@@ -16913,28 +17095,28 @@ async function rollbackExtension(ctx, args) {
|
|
|
16913
17095
|
if (!await fileExists2(logPath)) {
|
|
16914
17096
|
return { undone: false, message: "no apply found for library" };
|
|
16915
17097
|
}
|
|
16916
|
-
const raw = await
|
|
17098
|
+
const raw = await import_node_fs36.promises.readFile(logPath, "utf8");
|
|
16917
17099
|
const entries = raw.trim().split("\n").filter(Boolean).map((line) => JSON.parse(line));
|
|
16918
17100
|
const match = [...entries].reverse().find((e) => e.project === ctx.project && e.library === args.library);
|
|
16919
17101
|
if (!match) {
|
|
16920
17102
|
return { undone: false, message: "no apply found for library" };
|
|
16921
17103
|
}
|
|
16922
|
-
const pkgPath =
|
|
17104
|
+
const pkgPath = import_node_path72.default.join(ctx.scanPath, "package.json");
|
|
16923
17105
|
if (await fileExists2(pkgPath)) {
|
|
16924
17106
|
const pkg = await readPackageJson(ctx.scanPath);
|
|
16925
17107
|
if (pkg.dependencies?.[match.instrumentation_package]) {
|
|
16926
17108
|
const { [match.instrumentation_package]: _removed, ...rest } = pkg.dependencies;
|
|
16927
17109
|
pkg.dependencies = rest;
|
|
16928
|
-
await
|
|
17110
|
+
await import_node_fs36.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
|
16929
17111
|
}
|
|
16930
17112
|
}
|
|
16931
17113
|
const hookFiles = await findHookFiles(ctx.scanPath);
|
|
16932
17114
|
for (const file of hookFiles) {
|
|
16933
|
-
const filePath =
|
|
16934
|
-
const content = await
|
|
17115
|
+
const filePath = import_node_path72.default.join(ctx.scanPath, file);
|
|
17116
|
+
const content = await import_node_fs36.promises.readFile(filePath, "utf8");
|
|
16935
17117
|
if (content.includes(match.registration_snippet)) {
|
|
16936
17118
|
const filtered = content.split("\n").filter((line) => !line.includes(match.registration_snippet)).join("\n");
|
|
16937
|
-
await
|
|
17119
|
+
await import_node_fs36.promises.writeFile(filePath, filtered, "utf8");
|
|
16938
17120
|
break;
|
|
16939
17121
|
}
|
|
16940
17122
|
}
|
|
@@ -18571,7 +18753,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18571
18753
|
|
|
18572
18754
|
// src/diff.ts
|
|
18573
18755
|
init_cjs_shims();
|
|
18574
|
-
var
|
|
18756
|
+
var import_node_fs37 = require("fs");
|
|
18575
18757
|
async function loadSnapshotForDiff(target) {
|
|
18576
18758
|
if (/^https?:\/\//i.test(target)) {
|
|
18577
18759
|
const res = await fetch(target);
|
|
@@ -18580,7 +18762,7 @@ async function loadSnapshotForDiff(target) {
|
|
|
18580
18762
|
}
|
|
18581
18763
|
return await res.json();
|
|
18582
18764
|
}
|
|
18583
|
-
const raw = await
|
|
18765
|
+
const raw = await import_node_fs37.promises.readFile(target, "utf8");
|
|
18584
18766
|
return JSON.parse(raw);
|
|
18585
18767
|
}
|
|
18586
18768
|
function indexEntries(entries) {
|
|
@@ -18648,23 +18830,23 @@ function canonicalJson(value) {
|
|
|
18648
18830
|
|
|
18649
18831
|
// src/projects.ts
|
|
18650
18832
|
init_cjs_shims();
|
|
18651
|
-
var
|
|
18833
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
18652
18834
|
function pathsForProject(project, baseDir) {
|
|
18653
18835
|
if (project === DEFAULT_PROJECT) {
|
|
18654
18836
|
return {
|
|
18655
|
-
snapshotPath:
|
|
18656
|
-
errorsPath:
|
|
18657
|
-
staleEventsPath:
|
|
18658
|
-
embeddingsCachePath:
|
|
18659
|
-
policyViolationsPath:
|
|
18837
|
+
snapshotPath: import_node_path73.default.join(baseDir, "graph.json"),
|
|
18838
|
+
errorsPath: import_node_path73.default.join(baseDir, "errors.ndjson"),
|
|
18839
|
+
staleEventsPath: import_node_path73.default.join(baseDir, "stale-events.ndjson"),
|
|
18840
|
+
embeddingsCachePath: import_node_path73.default.join(baseDir, "embeddings.json"),
|
|
18841
|
+
policyViolationsPath: import_node_path73.default.join(baseDir, "policy-violations.ndjson")
|
|
18660
18842
|
};
|
|
18661
18843
|
}
|
|
18662
18844
|
return {
|
|
18663
|
-
snapshotPath:
|
|
18664
|
-
errorsPath:
|
|
18665
|
-
staleEventsPath:
|
|
18666
|
-
embeddingsCachePath:
|
|
18667
|
-
policyViolationsPath:
|
|
18845
|
+
snapshotPath: import_node_path73.default.join(baseDir, `${project}.json`),
|
|
18846
|
+
errorsPath: import_node_path73.default.join(baseDir, `errors.${project}.ndjson`),
|
|
18847
|
+
staleEventsPath: import_node_path73.default.join(baseDir, `stale-events.${project}.ndjson`),
|
|
18848
|
+
embeddingsCachePath: import_node_path73.default.join(baseDir, `embeddings.${project}.json`),
|
|
18849
|
+
policyViolationsPath: import_node_path73.default.join(baseDir, `policy-violations.${project}.ndjson`)
|
|
18668
18850
|
};
|
|
18669
18851
|
}
|
|
18670
18852
|
var Projects = class {
|
|
@@ -18700,28 +18882,28 @@ var Projects = class {
|
|
|
18700
18882
|
|
|
18701
18883
|
// src/registry.ts
|
|
18702
18884
|
init_cjs_shims();
|
|
18703
|
-
var
|
|
18885
|
+
var import_node_fs38 = require("fs");
|
|
18704
18886
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
18705
|
-
var
|
|
18887
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
18706
18888
|
var import_types63 = require("@neat.is/types");
|
|
18707
18889
|
var LOCK_TIMEOUT_MS = 5e3;
|
|
18708
18890
|
var LOCK_RETRY_MS = 50;
|
|
18709
18891
|
function neatHome() {
|
|
18710
18892
|
const override = process.env.NEAT_HOME;
|
|
18711
|
-
if (override && override.length > 0) return
|
|
18712
|
-
return
|
|
18893
|
+
if (override && override.length > 0) return import_node_path74.default.resolve(override);
|
|
18894
|
+
return import_node_path74.default.join(import_node_os3.default.homedir(), ".neat");
|
|
18713
18895
|
}
|
|
18714
18896
|
function registryPath() {
|
|
18715
|
-
return
|
|
18897
|
+
return import_node_path74.default.join(neatHome(), "projects.json");
|
|
18716
18898
|
}
|
|
18717
18899
|
function registryLockPath() {
|
|
18718
|
-
return
|
|
18900
|
+
return import_node_path74.default.join(neatHome(), "projects.json.lock");
|
|
18719
18901
|
}
|
|
18720
18902
|
function daemonPidPath() {
|
|
18721
|
-
return
|
|
18903
|
+
return import_node_path74.default.join(neatHome(), "neatd.pid");
|
|
18722
18904
|
}
|
|
18723
18905
|
function daemonsDir() {
|
|
18724
|
-
return
|
|
18906
|
+
return import_node_path74.default.join(neatHome(), "daemons");
|
|
18725
18907
|
}
|
|
18726
18908
|
function isFiniteInt(v) {
|
|
18727
18909
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -18754,7 +18936,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
|
|
|
18754
18936
|
const dir = daemonsDir();
|
|
18755
18937
|
let names;
|
|
18756
18938
|
try {
|
|
18757
|
-
names = await
|
|
18939
|
+
names = await import_node_fs38.promises.readdir(dir);
|
|
18758
18940
|
} catch (err) {
|
|
18759
18941
|
if (err.code === "ENOENT") return [];
|
|
18760
18942
|
throw err;
|
|
@@ -18762,10 +18944,10 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
|
|
|
18762
18944
|
const out = [];
|
|
18763
18945
|
for (const name of names) {
|
|
18764
18946
|
if (!name.endsWith(".json")) continue;
|
|
18765
|
-
const file =
|
|
18947
|
+
const file = import_node_path74.default.join(dir, name);
|
|
18766
18948
|
let raw;
|
|
18767
18949
|
try {
|
|
18768
|
-
raw = await
|
|
18950
|
+
raw = await import_node_fs38.promises.readFile(file, "utf8");
|
|
18769
18951
|
} catch {
|
|
18770
18952
|
continue;
|
|
18771
18953
|
}
|
|
@@ -18791,7 +18973,7 @@ function isPidAliveDefault(pid) {
|
|
|
18791
18973
|
}
|
|
18792
18974
|
async function readPidFile(file) {
|
|
18793
18975
|
try {
|
|
18794
|
-
const raw = await
|
|
18976
|
+
const raw = await import_node_fs38.promises.readFile(file, "utf8");
|
|
18795
18977
|
const pid = Number.parseInt(raw.trim(), 10);
|
|
18796
18978
|
return Number.isInteger(pid) && pid > 0 ? pid : void 0;
|
|
18797
18979
|
} catch {
|
|
@@ -18817,14 +18999,12 @@ async function readLockPid(lockPath) {
|
|
|
18817
18999
|
async function classifyLockHolder(lockPath, probe = defaultLockHolderProbe) {
|
|
18818
19000
|
const lockPid = await readLockPid(lockPath);
|
|
18819
19001
|
const daemonPid = await probe.daemonPidFromFile();
|
|
18820
|
-
if (daemonPid !== void 0 && daemonPid !== process.pid && probe.isPidAlive(daemonPid) && // The lock already names the daemon, or the daemon answers on its port.
|
|
18821
|
-
// Either confirms a live daemon is in the picture (the second guards
|
|
18822
|
-
// against a stale pidfile whose PID got reused).
|
|
18823
|
-
(daemonPid === lockPid || await probe.daemonResponds())) {
|
|
18824
|
-
return { kind: "daemon", pid: daemonPid };
|
|
18825
|
-
}
|
|
18826
19002
|
if (lockPid !== void 0 && lockPid !== process.pid && probe.isPidAlive(lockPid)) {
|
|
18827
|
-
return { kind: "command", pid: lockPid };
|
|
19003
|
+
return { kind: lockPid === daemonPid ? "daemon" : "command", pid: lockPid };
|
|
19004
|
+
}
|
|
19005
|
+
if (daemonPid !== void 0 && daemonPid !== process.pid && probe.isPidAlive(daemonPid) && // Guards against a stale pidfile whose PID got reused.
|
|
19006
|
+
await probe.daemonResponds()) {
|
|
19007
|
+
return { kind: "daemon", pid: daemonPid };
|
|
18828
19008
|
}
|
|
18829
19009
|
return { kind: "stale" };
|
|
18830
19010
|
}
|
|
@@ -18835,36 +19015,36 @@ function lockHolderMessage(holder, lockPath, timeoutMs) {
|
|
|
18835
19015
|
case "command":
|
|
18836
19016
|
return `Another neat command (pid ${holder.pid}) is holding the registry lock. Wait for it to finish, or check \`ps\` if you're not sure what's running.`;
|
|
18837
19017
|
case "stale":
|
|
18838
|
-
return `
|
|
19018
|
+
return `timed out after ${timeoutMs}ms waiting for ${lockPath}. Another neat process is holding the lock; if no such process exists, remove the file by hand.`;
|
|
18839
19019
|
}
|
|
18840
19020
|
}
|
|
18841
19021
|
async function normalizeProjectPath(input) {
|
|
18842
|
-
const resolved =
|
|
19022
|
+
const resolved = import_node_path74.default.resolve(input);
|
|
18843
19023
|
try {
|
|
18844
|
-
return await
|
|
19024
|
+
return await import_node_fs38.promises.realpath(resolved);
|
|
18845
19025
|
} catch {
|
|
18846
19026
|
return resolved;
|
|
18847
19027
|
}
|
|
18848
19028
|
}
|
|
18849
19029
|
async function writeAtomically(target, contents) {
|
|
18850
|
-
await
|
|
19030
|
+
await import_node_fs38.promises.mkdir(import_node_path74.default.dirname(target), { recursive: true });
|
|
18851
19031
|
const tmp = `${target}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
|
|
18852
|
-
const fd = await
|
|
19032
|
+
const fd = await import_node_fs38.promises.open(tmp, "w");
|
|
18853
19033
|
try {
|
|
18854
19034
|
await fd.writeFile(contents, "utf8");
|
|
18855
19035
|
await fd.sync();
|
|
18856
19036
|
} finally {
|
|
18857
19037
|
await fd.close();
|
|
18858
19038
|
}
|
|
18859
|
-
await
|
|
19039
|
+
await import_node_fs38.promises.rename(tmp, target);
|
|
18860
19040
|
}
|
|
18861
19041
|
async function acquireLock(lockPath, timeoutMs = LOCK_TIMEOUT_MS, probe = defaultLockHolderProbe) {
|
|
18862
19042
|
const deadline = Date.now() + timeoutMs;
|
|
18863
|
-
await
|
|
19043
|
+
await import_node_fs38.promises.mkdir(import_node_path74.default.dirname(lockPath), { recursive: true });
|
|
18864
19044
|
let probedHolder = false;
|
|
18865
19045
|
while (true) {
|
|
18866
19046
|
try {
|
|
18867
|
-
const fd = await
|
|
19047
|
+
const fd = await import_node_fs38.promises.open(lockPath, "wx");
|
|
18868
19048
|
try {
|
|
18869
19049
|
await fd.writeFile(`${process.pid}
|
|
18870
19050
|
`, "utf8");
|
|
@@ -18878,18 +19058,36 @@ async function acquireLock(lockPath, timeoutMs = LOCK_TIMEOUT_MS, probe = defaul
|
|
|
18878
19058
|
if (!probedHolder) {
|
|
18879
19059
|
probedHolder = true;
|
|
18880
19060
|
const holder = await classifyLockHolder(lockPath, probe);
|
|
18881
|
-
if (holder.kind === "daemon")
|
|
19061
|
+
if (holder.kind === "daemon") {
|
|
19062
|
+
throw new RegistryLockError(lockHolderMessage(holder, lockPath, timeoutMs));
|
|
19063
|
+
}
|
|
19064
|
+
if (holder.kind === "stale" && await isReclaimableLock(lockPath)) {
|
|
19065
|
+
await import_node_fs38.promises.unlink(lockPath).catch(() => {
|
|
19066
|
+
});
|
|
19067
|
+
continue;
|
|
19068
|
+
}
|
|
18882
19069
|
}
|
|
18883
19070
|
if (Date.now() >= deadline) {
|
|
18884
19071
|
const holder = await classifyLockHolder(lockPath, probe);
|
|
18885
|
-
throw new
|
|
19072
|
+
throw new RegistryLockError(lockHolderMessage(holder, lockPath, timeoutMs));
|
|
18886
19073
|
}
|
|
18887
19074
|
await new Promise((r) => setTimeout(r, LOCK_RETRY_MS));
|
|
18888
19075
|
}
|
|
18889
19076
|
}
|
|
18890
19077
|
}
|
|
19078
|
+
var LOCK_UNSTAMPED_GRACE_MS = 5e3;
|
|
19079
|
+
async function isReclaimableLock(lockPath) {
|
|
19080
|
+
const pid = await readLockPid(lockPath);
|
|
19081
|
+
if (pid !== void 0) return true;
|
|
19082
|
+
try {
|
|
19083
|
+
const stat = await import_node_fs38.promises.stat(lockPath);
|
|
19084
|
+
return Date.now() - stat.mtimeMs > LOCK_UNSTAMPED_GRACE_MS;
|
|
19085
|
+
} catch {
|
|
19086
|
+
return false;
|
|
19087
|
+
}
|
|
19088
|
+
}
|
|
18891
19089
|
async function releaseLock(lockPath) {
|
|
18892
|
-
await
|
|
19090
|
+
await import_node_fs38.promises.unlink(lockPath).catch(() => {
|
|
18893
19091
|
});
|
|
18894
19092
|
}
|
|
18895
19093
|
async function withLock(fn) {
|
|
@@ -18905,7 +19103,7 @@ async function readRegistry() {
|
|
|
18905
19103
|
const file = registryPath();
|
|
18906
19104
|
let raw;
|
|
18907
19105
|
try {
|
|
18908
|
-
raw = await
|
|
19106
|
+
raw = await import_node_fs38.promises.readFile(file, "utf8");
|
|
18909
19107
|
} catch (err) {
|
|
18910
19108
|
if (err.code === "ENOENT") {
|
|
18911
19109
|
return { version: 1, projects: [] };
|
|
@@ -18919,10 +19117,22 @@ async function writeRegistry(reg) {
|
|
|
18919
19117
|
const validated = import_types63.RegistryFileSchema.parse(reg);
|
|
18920
19118
|
await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
|
|
18921
19119
|
}
|
|
18922
|
-
var
|
|
19120
|
+
var RegistryError = class extends Error {
|
|
19121
|
+
constructor(message) {
|
|
19122
|
+
super(message);
|
|
19123
|
+
this.name = "RegistryError";
|
|
19124
|
+
}
|
|
19125
|
+
};
|
|
19126
|
+
var RegistryLockError = class extends RegistryError {
|
|
19127
|
+
constructor(message) {
|
|
19128
|
+
super(message);
|
|
19129
|
+
this.name = "RegistryLockError";
|
|
19130
|
+
}
|
|
19131
|
+
};
|
|
19132
|
+
var ProjectNameCollisionError = class extends RegistryError {
|
|
18923
19133
|
projectName;
|
|
18924
19134
|
constructor(name) {
|
|
18925
|
-
super(`
|
|
19135
|
+
super(`a project named "${name}" is already registered`);
|
|
18926
19136
|
this.name = "ProjectNameCollisionError";
|
|
18927
19137
|
this.projectName = name;
|
|
18928
19138
|
}
|
|
@@ -18971,7 +19181,7 @@ async function setStatus(name, status2) {
|
|
|
18971
19181
|
return withLock(async () => {
|
|
18972
19182
|
const reg = await readRegistry();
|
|
18973
19183
|
const entry = reg.projects.find((p) => p.name === name);
|
|
18974
|
-
if (!entry) throw new
|
|
19184
|
+
if (!entry) throw new RegistryError(`no project named "${name}"`);
|
|
18975
19185
|
entry.status = status2;
|
|
18976
19186
|
await writeRegistry(reg);
|
|
18977
19187
|
return entry;
|
|
@@ -19010,7 +19220,7 @@ function pruneTtlMs() {
|
|
|
19010
19220
|
}
|
|
19011
19221
|
async function statPathStatus(p) {
|
|
19012
19222
|
try {
|
|
19013
|
-
const stat = await
|
|
19223
|
+
const stat = await import_node_fs38.promises.stat(p);
|
|
19014
19224
|
return stat.isDirectory() ? "present" : "unknown";
|
|
19015
19225
|
} catch (err) {
|
|
19016
19226
|
return err.code === "ENOENT" ? "gone" : "unknown";
|
|
@@ -19111,8 +19321,8 @@ init_auth();
|
|
|
19111
19321
|
// src/connectors-config.ts
|
|
19112
19322
|
init_cjs_shims();
|
|
19113
19323
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
19114
|
-
var
|
|
19115
|
-
var
|
|
19324
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
19325
|
+
var import_node_fs39 = require("fs");
|
|
19116
19326
|
var CONNECTORS_CONFIG_VERSION = 1;
|
|
19117
19327
|
var EnvRefUnsetError = class extends Error {
|
|
19118
19328
|
ref;
|
|
@@ -19126,17 +19336,17 @@ var EnvRefUnsetError = class extends Error {
|
|
|
19126
19336
|
};
|
|
19127
19337
|
function neatHome2() {
|
|
19128
19338
|
const override = process.env.NEAT_HOME;
|
|
19129
|
-
if (override && override.length > 0) return
|
|
19130
|
-
return
|
|
19339
|
+
if (override && override.length > 0) return import_node_path75.default.resolve(override);
|
|
19340
|
+
return import_node_path75.default.join(import_node_os4.default.homedir(), ".neat");
|
|
19131
19341
|
}
|
|
19132
19342
|
function connectorsConfigPath(home = neatHome2()) {
|
|
19133
|
-
return
|
|
19343
|
+
return import_node_path75.default.join(home, "connectors.json");
|
|
19134
19344
|
}
|
|
19135
19345
|
var MODE_MASK_LOOSER_THAN_0600 = 63;
|
|
19136
19346
|
async function warnIfModeLooserThan0600(file) {
|
|
19137
19347
|
if (process.platform === "win32") return;
|
|
19138
19348
|
try {
|
|
19139
|
-
const stat = await
|
|
19349
|
+
const stat = await import_node_fs39.promises.stat(file);
|
|
19140
19350
|
if ((stat.mode & MODE_MASK_LOOSER_THAN_0600) !== 0) {
|
|
19141
19351
|
const mode = (stat.mode & 511).toString(8).padStart(3, "0");
|
|
19142
19352
|
console.warn(
|
|
@@ -19150,7 +19360,7 @@ async function readConnectorsConfig(home = neatHome2()) {
|
|
|
19150
19360
|
const file = connectorsConfigPath(home);
|
|
19151
19361
|
let raw;
|
|
19152
19362
|
try {
|
|
19153
|
-
raw = await
|
|
19363
|
+
raw = await import_node_fs39.promises.readFile(file, "utf8");
|
|
19154
19364
|
} catch (err) {
|
|
19155
19365
|
if (err.code === "ENOENT") {
|
|
19156
19366
|
return { version: CONNECTORS_CONFIG_VERSION, connectors: [] };
|
|
@@ -19946,10 +20156,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
|
|
|
19946
20156
|
// src/connectors/supabase/map.ts
|
|
19947
20157
|
var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
|
|
19948
20158
|
var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
|
|
19949
|
-
function targetFromRestPath(
|
|
19950
|
-
const rpcMatch = REST_RPC_PATH_RE.exec(
|
|
20159
|
+
function targetFromRestPath(path80) {
|
|
20160
|
+
const rpcMatch = REST_RPC_PATH_RE.exec(path80);
|
|
19951
20161
|
if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
|
|
19952
|
-
const tableMatch = REST_TABLE_PATH_RE.exec(
|
|
20162
|
+
const tableMatch = REST_TABLE_PATH_RE.exec(path80);
|
|
19953
20163
|
if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
|
|
19954
20164
|
return null;
|
|
19955
20165
|
}
|
|
@@ -20553,9 +20763,9 @@ function parseFirebaseTargetName(targetName) {
|
|
|
20553
20763
|
const secondSep = rest.indexOf(FIELD_SEP);
|
|
20554
20764
|
if (secondSep === -1) return null;
|
|
20555
20765
|
const method = rest.slice(0, secondSep);
|
|
20556
|
-
const
|
|
20557
|
-
if (!resourceName || !method || !
|
|
20558
|
-
return { resourceName, method, path:
|
|
20766
|
+
const path80 = rest.slice(secondSep + 1);
|
|
20767
|
+
if (!resourceName || !method || !path80) return null;
|
|
20768
|
+
return { resourceName, method, path: path80 };
|
|
20559
20769
|
}
|
|
20560
20770
|
function resourceNameFor(type, labels) {
|
|
20561
20771
|
if (!labels) return null;
|
|
@@ -20593,14 +20803,14 @@ function mapLogEntryToSignal(entry) {
|
|
|
20593
20803
|
if (!req) return null;
|
|
20594
20804
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
20595
20805
|
const method = req.requestMethod.toUpperCase();
|
|
20596
|
-
const
|
|
20597
|
-
if (
|
|
20806
|
+
const path80 = pathFromRequestUrl(req.requestUrl);
|
|
20807
|
+
if (path80 === null) return null;
|
|
20598
20808
|
const timestamp = entry.timestamp;
|
|
20599
20809
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
20600
20810
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
|
|
20601
20811
|
return {
|
|
20602
20812
|
targetKind: resourceType,
|
|
20603
|
-
targetName: packFirebaseTargetName({ resourceName, method, path:
|
|
20813
|
+
targetName: packFirebaseTargetName({ resourceName, method, path: path80 }),
|
|
20604
20814
|
callCount: 1,
|
|
20605
20815
|
errorCount: isError ? 1 : 0,
|
|
20606
20816
|
lastObservedIso: timestamp
|
|
@@ -20625,9 +20835,9 @@ var import_types71 = require("@neat.is/types");
|
|
|
20625
20835
|
function normalizeName(name) {
|
|
20626
20836
|
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
20627
20837
|
}
|
|
20628
|
-
function inferServiceName(graph, resourceName, method,
|
|
20838
|
+
function inferServiceName(graph, resourceName, method, path80) {
|
|
20629
20839
|
const wantedMethod = method.toUpperCase();
|
|
20630
|
-
const wantedPath = normalizePathTemplate(
|
|
20840
|
+
const wantedPath = normalizePathTemplate(path80);
|
|
20631
20841
|
const services = [];
|
|
20632
20842
|
const owners = /* @__PURE__ */ new Set();
|
|
20633
20843
|
graph.forEachNode((_id, attrs) => {
|
|
@@ -20844,7 +21054,7 @@ function mapEventToSignal(event) {
|
|
|
20844
21054
|
if (Number.isNaN(observedAt.getTime())) return null;
|
|
20845
21055
|
const statusCode = metadata?.statusCode;
|
|
20846
21056
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
20847
|
-
const
|
|
21057
|
+
const path80 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
20848
21058
|
return {
|
|
20849
21059
|
targetKind: CLOUDFLARE_TARGET_KIND,
|
|
20850
21060
|
targetName: scriptName,
|
|
@@ -20852,7 +21062,7 @@ function mapEventToSignal(event) {
|
|
|
20852
21062
|
errorCount: isError ? 1 : 0,
|
|
20853
21063
|
lastObservedIso: observedAt.toISOString(),
|
|
20854
21064
|
method,
|
|
20855
|
-
...
|
|
21065
|
+
...path80 ? { path: path80 } : {},
|
|
20856
21066
|
...typeof statusCode === "number" ? { statusCode } : {},
|
|
20857
21067
|
...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
|
|
20858
21068
|
};
|
|
@@ -20898,8 +21108,8 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
20898
21108
|
});
|
|
20899
21109
|
return found;
|
|
20900
21110
|
}
|
|
20901
|
-
function findMatchingRouteNode(graph, serviceName, method,
|
|
20902
|
-
const normalizedPath = normalizePathTemplate(
|
|
21111
|
+
function findMatchingRouteNode(graph, serviceName, method, path80) {
|
|
21112
|
+
const normalizedPath = normalizePathTemplate(path80);
|
|
20903
21113
|
let found = null;
|
|
20904
21114
|
graph.forEachNode((id, attrs) => {
|
|
20905
21115
|
if (found) return;
|
|
@@ -20916,10 +21126,10 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
20916
21126
|
return (signal) => {
|
|
20917
21127
|
if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
|
|
20918
21128
|
const scriptName = signal.targetName;
|
|
20919
|
-
const { method, path:
|
|
21129
|
+
const { method, path: path80 } = signal;
|
|
20920
21130
|
const resolveRouteGrain = (serviceName, wholeFileId) => {
|
|
20921
|
-
if (!method || !
|
|
20922
|
-
return findMatchingRouteNode(graph, serviceName, method,
|
|
21131
|
+
if (!method || !path80) return wholeFileId;
|
|
21132
|
+
return findMatchingRouteNode(graph, serviceName, method, path80) ?? wholeFileId;
|
|
20923
21133
|
};
|
|
20924
21134
|
const mapping = config.workers?.[scriptName];
|
|
20925
21135
|
if (mapping) {
|
|
@@ -21271,9 +21481,9 @@ function parseCloudRunTargetName(targetName) {
|
|
|
21271
21481
|
const secondSep = rest.indexOf(FIELD_SEP2);
|
|
21272
21482
|
if (secondSep === -1) return null;
|
|
21273
21483
|
const method = rest.slice(0, secondSep);
|
|
21274
|
-
const
|
|
21275
|
-
if (!serviceName || !method || !
|
|
21276
|
-
return { serviceName, method, path:
|
|
21484
|
+
const path80 = rest.slice(secondSep + 1);
|
|
21485
|
+
if (!serviceName || !method || !path80) return null;
|
|
21486
|
+
return { serviceName, method, path: path80 };
|
|
21277
21487
|
}
|
|
21278
21488
|
|
|
21279
21489
|
// src/connectors/cloud-run/map.ts
|
|
@@ -21302,14 +21512,14 @@ function mapLogEntryToSignal2(entry) {
|
|
|
21302
21512
|
if (!req) return null;
|
|
21303
21513
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
21304
21514
|
const method = req.requestMethod.toUpperCase();
|
|
21305
|
-
const
|
|
21306
|
-
if (
|
|
21515
|
+
const path80 = pathFromRequestUrl2(req.requestUrl);
|
|
21516
|
+
if (path80 === null) return null;
|
|
21307
21517
|
const timestamp = entry.timestamp;
|
|
21308
21518
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
21309
21519
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD4;
|
|
21310
21520
|
return {
|
|
21311
21521
|
targetKind: CLOUD_RUN_TARGET_KIND,
|
|
21312
|
-
targetName: packCloudRunTargetName({ serviceName, method, path:
|
|
21522
|
+
targetName: packCloudRunTargetName({ serviceName, method, path: path80 }),
|
|
21313
21523
|
callCount: 1,
|
|
21314
21524
|
errorCount: isError ? 1 : 0,
|
|
21315
21525
|
lastObservedIso: timestamp
|
|
@@ -21348,14 +21558,14 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
21348
21558
|
if (signal.targetKind !== CLOUD_RUN_TARGET_KIND) return null;
|
|
21349
21559
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
21350
21560
|
if (!identity) return null;
|
|
21351
|
-
const { serviceName: gcpServiceName, method, path:
|
|
21352
|
-
const mappedService = config.serviceMap?.[gcpServiceName] ?? (config.inferServices ? inferServiceName(graph, gcpServiceName, method,
|
|
21561
|
+
const { serviceName: gcpServiceName, method, path: path80 } = identity;
|
|
21562
|
+
const mappedService = config.serviceMap?.[gcpServiceName] ?? (config.inferServices ? inferServiceName(graph, gcpServiceName, method, path80) ?? void 0 : void 0);
|
|
21353
21563
|
if (mappedService) {
|
|
21354
21564
|
const routeNodeId = findMatchingRouteNode2(
|
|
21355
21565
|
graph,
|
|
21356
21566
|
mappedService,
|
|
21357
21567
|
method,
|
|
21358
|
-
normalizePathTemplate(
|
|
21568
|
+
normalizePathTemplate(path80)
|
|
21359
21569
|
);
|
|
21360
21570
|
if (routeNodeId) {
|
|
21361
21571
|
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types82.EdgeType.CALLS };
|
|
@@ -21491,9 +21701,9 @@ function parseGcpLbTargetName(targetName) {
|
|
|
21491
21701
|
const secondSep = rest.indexOf(FIELD_SEP3);
|
|
21492
21702
|
if (secondSep === -1) return null;
|
|
21493
21703
|
const method = rest.slice(0, secondSep);
|
|
21494
|
-
const
|
|
21495
|
-
if (!backendServiceName || !method || !
|
|
21496
|
-
return { backendServiceName, method, path:
|
|
21704
|
+
const path80 = rest.slice(secondSep + 1);
|
|
21705
|
+
if (!backendServiceName || !method || !path80) return null;
|
|
21706
|
+
return { backendServiceName, method, path: path80 };
|
|
21497
21707
|
}
|
|
21498
21708
|
|
|
21499
21709
|
// src/connectors/gcp-lb/map.ts
|
|
@@ -21522,14 +21732,14 @@ function mapLogEntryToSignal3(entry) {
|
|
|
21522
21732
|
if (!req) return null;
|
|
21523
21733
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
21524
21734
|
const method = req.requestMethod.toUpperCase();
|
|
21525
|
-
const
|
|
21526
|
-
if (
|
|
21735
|
+
const path80 = pathFromRequestUrl3(req.requestUrl);
|
|
21736
|
+
if (path80 === null) return null;
|
|
21527
21737
|
const timestamp = entry.timestamp;
|
|
21528
21738
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
21529
21739
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD5;
|
|
21530
21740
|
return {
|
|
21531
21741
|
targetKind: GCP_LB_TARGET_KIND,
|
|
21532
|
-
targetName: packGcpLbTargetName({ backendServiceName, method, path:
|
|
21742
|
+
targetName: packGcpLbTargetName({ backendServiceName, method, path: path80 }),
|
|
21533
21743
|
callCount: 1,
|
|
21534
21744
|
errorCount: isError ? 1 : 0,
|
|
21535
21745
|
lastObservedIso: timestamp
|
|
@@ -21568,14 +21778,14 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21568
21778
|
if (signal.targetKind !== GCP_LB_TARGET_KIND) return null;
|
|
21569
21779
|
const identity = parseGcpLbTargetName(signal.targetName);
|
|
21570
21780
|
if (!identity) return null;
|
|
21571
|
-
const { backendServiceName, method, path:
|
|
21572
|
-
const mappedService = config.backendServiceMap?.[backendServiceName] ?? (config.inferServices ? inferServiceName(graph, backendServiceName, method,
|
|
21781
|
+
const { backendServiceName, method, path: path80 } = identity;
|
|
21782
|
+
const mappedService = config.backendServiceMap?.[backendServiceName] ?? (config.inferServices ? inferServiceName(graph, backendServiceName, method, path80) ?? void 0 : void 0);
|
|
21573
21783
|
if (mappedService) {
|
|
21574
21784
|
const routeNodeId = findMatchingRouteNode3(
|
|
21575
21785
|
graph,
|
|
21576
21786
|
mappedService,
|
|
21577
21787
|
method,
|
|
21578
|
-
normalizePathTemplate(
|
|
21788
|
+
normalizePathTemplate(path80)
|
|
21579
21789
|
);
|
|
21580
21790
|
if (routeNodeId) {
|
|
21581
21791
|
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types86.EdgeType.CALLS };
|
|
@@ -22893,16 +23103,18 @@ function serializeGraph(graph) {
|
|
|
22893
23103
|
});
|
|
22894
23104
|
return { nodes, edges };
|
|
22895
23105
|
}
|
|
22896
|
-
function projectFromReq(req, singleProject) {
|
|
23106
|
+
function projectFromReq(req, singleProject, registry) {
|
|
22897
23107
|
const params = req.params;
|
|
22898
23108
|
const named2 = params.project;
|
|
22899
23109
|
if (singleProject) {
|
|
22900
23110
|
return named2 === void 0 || named2 === DEFAULT_PROJECT ? singleProject : named2;
|
|
22901
23111
|
}
|
|
22902
|
-
|
|
23112
|
+
if (named2 !== void 0) return named2;
|
|
23113
|
+
const hosted = registry?.list() ?? [];
|
|
23114
|
+
return hosted.length === 1 ? hosted[0] : DEFAULT_PROJECT;
|
|
22903
23115
|
}
|
|
22904
23116
|
function resolveProject(registry, req, reply, bootstrap, singleProject) {
|
|
22905
|
-
const name = projectFromReq(req, singleProject);
|
|
23117
|
+
const name = projectFromReq(req, singleProject, registry);
|
|
22906
23118
|
const ctx = registry.get(name);
|
|
22907
23119
|
if (!ctx) {
|
|
22908
23120
|
const phase = bootstrap?.status(name);
|
|
@@ -22914,10 +23126,13 @@ function resolveProject(registry, req, reply, bootstrap, singleProject) {
|
|
|
22914
23126
|
void reply.code(503).send({ ready: false, project: name, status: "broken" });
|
|
22915
23127
|
return null;
|
|
22916
23128
|
}
|
|
23129
|
+
const unnamed = req.params.project === void 0;
|
|
23130
|
+
const hosted = registry.list();
|
|
23131
|
+
const hint = unnamed && name === DEFAULT_PROJECT && hosted.length > 1 ? `This daemon hosts ${hosted.length} projects and none is named \`default\`: ${hosted.join(", ")}. Name one as /projects/<name>/\u2026 , or reach that project's own daemon.` : "This daemon does not host that project. GET /projects lists what it serves (see hostedHere).";
|
|
22917
23132
|
void reply.code(404).send({
|
|
22918
23133
|
error: "project not found",
|
|
22919
23134
|
project: name,
|
|
22920
|
-
hint
|
|
23135
|
+
hint
|
|
22921
23136
|
});
|
|
22922
23137
|
return null;
|
|
22923
23138
|
}
|
|
@@ -23800,8 +24015,8 @@ init_otel_grpc();
|
|
|
23800
24015
|
|
|
23801
24016
|
// src/daemon.ts
|
|
23802
24017
|
init_cjs_shims();
|
|
23803
|
-
var
|
|
23804
|
-
var
|
|
24018
|
+
var import_node_fs42 = require("fs");
|
|
24019
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
23805
24020
|
var import_node_module = require("module");
|
|
23806
24021
|
init_otel();
|
|
23807
24022
|
|
|
@@ -23838,7 +24053,7 @@ async function reconcileFrontierSurfaces(graph, errorsPath) {
|
|
|
23838
24053
|
// src/connectors/hosted.ts
|
|
23839
24054
|
init_cjs_shims();
|
|
23840
24055
|
var import_promises = require("fs/promises");
|
|
23841
|
-
var
|
|
24056
|
+
var import_node_path76 = require("path");
|
|
23842
24057
|
|
|
23843
24058
|
// src/connectors/railway/target-ref.ts
|
|
23844
24059
|
init_cjs_shims();
|
|
@@ -23873,13 +24088,13 @@ function decodeRailwayTargetRef(ref) {
|
|
|
23873
24088
|
var CREDENTIAL_REFRESH_SKEW_MS = 6e4;
|
|
23874
24089
|
var CP_REQUEST_TIMEOUT_MS = 1e4;
|
|
23875
24090
|
var DEFAULT_RELIST_INTERVAL_MS = 6e4;
|
|
23876
|
-
async function cpGet(
|
|
24091
|
+
async function cpGet(path80, deps) {
|
|
23877
24092
|
const f = deps.fetchImpl ?? fetch;
|
|
23878
|
-
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${
|
|
24093
|
+
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${path80}`, {
|
|
23879
24094
|
headers: { authorization: `Bearer ${deps.daemonToken}`, accept: "application/json" },
|
|
23880
24095
|
signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS)
|
|
23881
24096
|
});
|
|
23882
|
-
if (!res.ok) throw new Error(`control plane ${
|
|
24097
|
+
if (!res.ok) throw new Error(`control plane ${path80} \u2192 HTTP ${res.status}`);
|
|
23883
24098
|
return await res.json();
|
|
23884
24099
|
}
|
|
23885
24100
|
function credentialRecord(provider, cred) {
|
|
@@ -23940,7 +24155,7 @@ function parseFirebaseServiceMap(raw) {
|
|
|
23940
24155
|
}
|
|
23941
24156
|
}
|
|
23942
24157
|
function pushHandlesPath(projectDir) {
|
|
23943
|
-
return (0,
|
|
24158
|
+
return (0, import_node_path76.join)(projectDir, "neat-out", "connectors-hosted.json");
|
|
23944
24159
|
}
|
|
23945
24160
|
async function readPushHandles(projectDir) {
|
|
23946
24161
|
try {
|
|
@@ -23951,14 +24166,14 @@ async function readPushHandles(projectDir) {
|
|
|
23951
24166
|
}
|
|
23952
24167
|
}
|
|
23953
24168
|
async function writePushHandle(projectDir, provider, handle) {
|
|
23954
|
-
const
|
|
24169
|
+
const path80 = pushHandlesPath(projectDir);
|
|
23955
24170
|
const handles = await readPushHandles(projectDir);
|
|
23956
24171
|
handles[provider] = handle;
|
|
23957
|
-
await (0, import_promises.mkdir)((0,
|
|
23958
|
-
const tmp = `${
|
|
24172
|
+
await (0, import_promises.mkdir)((0, import_node_path76.dirname)(path80), { recursive: true });
|
|
24173
|
+
const tmp = `${path80}.${process.pid}.tmp`;
|
|
23959
24174
|
await (0, import_promises.writeFile)(tmp, `${JSON.stringify(handles, null, 2)}
|
|
23960
24175
|
`, "utf8");
|
|
23961
|
-
await (0, import_promises.rename)(tmp,
|
|
24176
|
+
await (0, import_promises.rename)(tmp, path80);
|
|
23962
24177
|
}
|
|
23963
24178
|
function pushCredentialRecord(provider, cred, deps) {
|
|
23964
24179
|
switch (provider) {
|
|
@@ -24179,7 +24394,7 @@ async function maybeStartHostedConnectors(input) {
|
|
|
24179
24394
|
// src/connectors/hosted-repos.ts
|
|
24180
24395
|
init_cjs_shims();
|
|
24181
24396
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
24182
|
-
var
|
|
24397
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
24183
24398
|
var import_promises2 = require("fs/promises");
|
|
24184
24399
|
var CP_REQUEST_TIMEOUT_MS2 = 1e4;
|
|
24185
24400
|
var DEFAULT_SYNC_INTERVAL_MS = 5 * 6e4;
|
|
@@ -24208,7 +24423,7 @@ async function cpPostStatus(deps, owner, name, body) {
|
|
|
24208
24423
|
if (!res.ok && res.status !== 404) throw new Error(`control plane status POST \u2192 HTTP ${res.status}`);
|
|
24209
24424
|
}
|
|
24210
24425
|
var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
24211
|
-
const [{ default: git }, httpMod,
|
|
24426
|
+
const [{ default: git }, httpMod, fs41] = await Promise.all([
|
|
24212
24427
|
import("isomorphic-git"),
|
|
24213
24428
|
import("isomorphic-git/http/node"),
|
|
24214
24429
|
import("fs")
|
|
@@ -24219,7 +24434,7 @@ var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
|
24219
24434
|
const username = parsed.password ? parsed.username : "x-access-token";
|
|
24220
24435
|
const cleanUrl = `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
|
|
24221
24436
|
const clone = git.clone({
|
|
24222
|
-
fs:
|
|
24437
|
+
fs: fs41,
|
|
24223
24438
|
http,
|
|
24224
24439
|
dir: destDir,
|
|
24225
24440
|
url: cleanUrl,
|
|
@@ -24250,7 +24465,7 @@ async function syncOneRepo(r, input) {
|
|
|
24250
24465
|
const tmpRoot = input.tmpRoot ?? import_node_os5.default.tmpdir();
|
|
24251
24466
|
let dir;
|
|
24252
24467
|
try {
|
|
24253
|
-
dir = await (0, import_promises2.mkdtemp)(
|
|
24468
|
+
dir = await (0, import_promises2.mkdtemp)(import_node_path77.default.join(tmpRoot, "neat-repo-"));
|
|
24254
24469
|
await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
|
|
24255
24470
|
});
|
|
24256
24471
|
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
@@ -24387,9 +24602,9 @@ function makeK8sFetchImpl(transport) {
|
|
|
24387
24602
|
req.end();
|
|
24388
24603
|
}));
|
|
24389
24604
|
}
|
|
24390
|
-
async function listResource(transport, namespace,
|
|
24605
|
+
async function listResource(transport, namespace, path80, opts = {}) {
|
|
24391
24606
|
const base = opts.apiUrl ?? transport.server;
|
|
24392
|
-
const url = `${base.replace(/\/$/, "")}${
|
|
24607
|
+
const url = `${base.replace(/\/$/, "")}${path80}`;
|
|
24393
24608
|
const fetchImpl = opts.fetchImpl ?? makeK8sFetchImpl(transport);
|
|
24394
24609
|
const res = await junctionFetch(
|
|
24395
24610
|
url,
|
|
@@ -24399,7 +24614,7 @@ async function listResource(transport, namespace, path79, opts = {}) {
|
|
|
24399
24614
|
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, fetchImpl }
|
|
24400
24615
|
);
|
|
24401
24616
|
if (!res.ok) {
|
|
24402
|
-
throw new Error(`kubernetes ${
|
|
24617
|
+
throw new Error(`kubernetes ${path80} failed: ${res.status} ${res.statusText}`);
|
|
24403
24618
|
}
|
|
24404
24619
|
const json = await res.json();
|
|
24405
24620
|
return Array.isArray(json.items) ? json.items : [];
|
|
@@ -24420,14 +24635,14 @@ async function fetchPods(transport, namespace, opts = {}) {
|
|
|
24420
24635
|
|
|
24421
24636
|
// src/connectors/kubernetes/kubeconfig.ts
|
|
24422
24637
|
init_cjs_shims();
|
|
24423
|
-
var
|
|
24638
|
+
var import_node_fs40 = require("fs");
|
|
24424
24639
|
var import_yaml4 = require("yaml");
|
|
24425
24640
|
function pemFrom(dataField, pathField) {
|
|
24426
24641
|
if (typeof dataField === "string" && dataField.length > 0) {
|
|
24427
24642
|
return Buffer.from(dataField, "base64").toString("utf8");
|
|
24428
24643
|
}
|
|
24429
24644
|
if (typeof pathField === "string" && pathField.length > 0) {
|
|
24430
|
-
return (0,
|
|
24645
|
+
return (0, import_node_fs40.readFileSync)(pathField, "utf8");
|
|
24431
24646
|
}
|
|
24432
24647
|
return void 0;
|
|
24433
24648
|
}
|
|
@@ -24438,7 +24653,7 @@ function named(list, name) {
|
|
|
24438
24653
|
}
|
|
24439
24654
|
function parseKubeconfig(kubeconfig) {
|
|
24440
24655
|
const looksInline = /\n/.test(kubeconfig) || /(^|\s)clusters\s*:/.test(kubeconfig);
|
|
24441
|
-
const text = looksInline ? kubeconfig : (0,
|
|
24656
|
+
const text = looksInline ? kubeconfig : (0, import_node_fs40.readFileSync)(kubeconfig, "utf8");
|
|
24442
24657
|
let doc;
|
|
24443
24658
|
try {
|
|
24444
24659
|
doc = (0, import_yaml4.parse)(text);
|
|
@@ -24703,14 +24918,14 @@ function createK8sResolveTarget(graph) {
|
|
|
24703
24918
|
init_cjs_shims();
|
|
24704
24919
|
var import_promises3 = require("fs/promises");
|
|
24705
24920
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
24706
|
-
var
|
|
24921
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
24707
24922
|
function defaultHome() {
|
|
24708
24923
|
const override = process.env.NEAT_HOME;
|
|
24709
|
-
if (override && override.length > 0) return
|
|
24710
|
-
return
|
|
24924
|
+
if (override && override.length > 0) return import_node_path78.default.resolve(override);
|
|
24925
|
+
return import_node_path78.default.join(import_node_os6.default.homedir(), ".neat");
|
|
24711
24926
|
}
|
|
24712
24927
|
function k8sSubstrateConfigPath(home = defaultHome()) {
|
|
24713
|
-
return
|
|
24928
|
+
return import_node_path78.default.join(home, "k8s.json");
|
|
24714
24929
|
}
|
|
24715
24930
|
async function readK8sSubstrateConfig(home = defaultHome()) {
|
|
24716
24931
|
let raw;
|
|
@@ -24809,8 +25024,8 @@ init_auth();
|
|
|
24809
25024
|
|
|
24810
25025
|
// src/unrouted.ts
|
|
24811
25026
|
init_cjs_shims();
|
|
24812
|
-
var
|
|
24813
|
-
var
|
|
25027
|
+
var import_node_fs41 = require("fs");
|
|
25028
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
24814
25029
|
function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new Date()) {
|
|
24815
25030
|
return {
|
|
24816
25031
|
timestamp: now.toISOString(),
|
|
@@ -24820,34 +25035,34 @@ function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new
|
|
|
24820
25035
|
};
|
|
24821
25036
|
}
|
|
24822
25037
|
async function appendUnroutedSpan(neatHome3, record) {
|
|
24823
|
-
const target =
|
|
24824
|
-
await
|
|
24825
|
-
await
|
|
25038
|
+
const target = import_node_path79.default.join(neatHome3, "errors.ndjson");
|
|
25039
|
+
await import_node_fs41.promises.mkdir(neatHome3, { recursive: true });
|
|
25040
|
+
await import_node_fs41.promises.appendFile(target, JSON.stringify(record) + "\n", "utf8");
|
|
24826
25041
|
}
|
|
24827
25042
|
function unroutedErrorsPath(neatHome3) {
|
|
24828
|
-
return
|
|
25043
|
+
return import_node_path79.default.join(neatHome3, "errors.ndjson");
|
|
24829
25044
|
}
|
|
24830
25045
|
|
|
24831
25046
|
// src/daemon.ts
|
|
24832
25047
|
var import_types107 = require("@neat.is/types");
|
|
24833
25048
|
function daemonJsonPath(scanPath) {
|
|
24834
|
-
return
|
|
25049
|
+
return import_node_path80.default.join(scanPath, "neat-out", "daemon.json");
|
|
24835
25050
|
}
|
|
24836
25051
|
function daemonsDiscoveryDir(home) {
|
|
24837
25052
|
const base = home && home.length > 0 ? home : neatHomeFromEnv();
|
|
24838
|
-
return
|
|
25053
|
+
return import_node_path80.default.join(base, "daemons");
|
|
24839
25054
|
}
|
|
24840
25055
|
function daemonDiscoveryPath(project, home) {
|
|
24841
|
-
return
|
|
25056
|
+
return import_node_path80.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
|
|
24842
25057
|
}
|
|
24843
25058
|
function sanitizeDiscoveryName(project) {
|
|
24844
25059
|
return project.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
24845
25060
|
}
|
|
24846
25061
|
function neatHomeFromEnv() {
|
|
24847
25062
|
const env = process.env.NEAT_HOME;
|
|
24848
|
-
if (env && env.length > 0) return
|
|
25063
|
+
if (env && env.length > 0) return import_node_path80.default.resolve(env);
|
|
24849
25064
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24850
|
-
return
|
|
25065
|
+
return import_node_path80.default.join(home, ".neat");
|
|
24851
25066
|
}
|
|
24852
25067
|
function resolveNeatVersion() {
|
|
24853
25068
|
if (process.env.NEAT_LOCAL_VERSION && process.env.NEAT_LOCAL_VERSION.length > 0) {
|
|
@@ -24879,7 +25094,7 @@ async function clearDaemonRecord(record, home) {
|
|
|
24879
25094
|
} catch {
|
|
24880
25095
|
}
|
|
24881
25096
|
try {
|
|
24882
|
-
await
|
|
25097
|
+
await import_node_fs42.promises.unlink(daemonDiscoveryPath(record.project, home));
|
|
24883
25098
|
} catch {
|
|
24884
25099
|
}
|
|
24885
25100
|
}
|
|
@@ -24914,11 +25129,11 @@ function teardownSlot(slot) {
|
|
|
24914
25129
|
}
|
|
24915
25130
|
}
|
|
24916
25131
|
function neatHomeFor(opts) {
|
|
24917
|
-
if (opts.neatHome && opts.neatHome.length > 0) return
|
|
25132
|
+
if (opts.neatHome && opts.neatHome.length > 0) return import_node_path80.default.resolve(opts.neatHome);
|
|
24918
25133
|
const env = process.env.NEAT_HOME;
|
|
24919
|
-
if (env && env.length > 0) return
|
|
25134
|
+
if (env && env.length > 0) return import_node_path80.default.resolve(env);
|
|
24920
25135
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24921
|
-
return
|
|
25136
|
+
return import_node_path80.default.join(home, ".neat");
|
|
24922
25137
|
}
|
|
24923
25138
|
function routeSpanToProject(serviceName, projects) {
|
|
24924
25139
|
if (!serviceName) return DEFAULT_PROJECT;
|
|
@@ -24970,9 +25185,9 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
24970
25185
|
);
|
|
24971
25186
|
}
|
|
24972
25187
|
async function bootstrapProject(entry, connectors = [], neatHome3) {
|
|
24973
|
-
const paths = pathsForProject(entry.name,
|
|
25188
|
+
const paths = pathsForProject(entry.name, import_node_path80.default.join(entry.path, "neat-out"));
|
|
24974
25189
|
try {
|
|
24975
|
-
const stat = await
|
|
25190
|
+
const stat = await import_node_fs42.promises.stat(entry.path);
|
|
24976
25191
|
if (!stat.isDirectory()) {
|
|
24977
25192
|
throw new Error(`registered path ${entry.path} is not a directory`);
|
|
24978
25193
|
}
|
|
@@ -25124,7 +25339,7 @@ async function startDaemon(opts = {}) {
|
|
|
25124
25339
|
const projectArg = typeof opts.project === "string" && opts.project.length > 0 ? opts.project : process.env.NEAT_PROJECT && process.env.NEAT_PROJECT.length > 0 ? process.env.NEAT_PROJECT : null;
|
|
25125
25340
|
const projectPathArg = opts.projectPath && opts.projectPath.length > 0 ? opts.projectPath : process.env.NEAT_PROJECT_PATH && process.env.NEAT_PROJECT_PATH.length > 0 ? process.env.NEAT_PROJECT_PATH : null;
|
|
25126
25341
|
const singleProject = projectArg;
|
|
25127
|
-
const singleProjectPath = singleProject && projectPathArg ?
|
|
25342
|
+
const singleProjectPath = singleProject && projectPathArg ? import_node_path80.default.resolve(projectPathArg) : null;
|
|
25128
25343
|
if (singleProject && !singleProjectPath) {
|
|
25129
25344
|
throw new Error(
|
|
25130
25345
|
`neatd: project "${singleProject}" given without a projectPath; pass NEAT_PROJECT_PATH alongside NEAT_PROJECT.`
|
|
@@ -25132,14 +25347,14 @@ async function startDaemon(opts = {}) {
|
|
|
25132
25347
|
}
|
|
25133
25348
|
if (!singleProject) {
|
|
25134
25349
|
try {
|
|
25135
|
-
await
|
|
25350
|
+
await import_node_fs42.promises.access(regPath);
|
|
25136
25351
|
} catch {
|
|
25137
25352
|
throw new Error(
|
|
25138
25353
|
`neatd: registry not found at ${regPath}. Run \`neat init <path>\` to register a project before starting the daemon.`
|
|
25139
25354
|
);
|
|
25140
25355
|
}
|
|
25141
25356
|
}
|
|
25142
|
-
const pidPath =
|
|
25357
|
+
const pidPath = import_node_path80.default.join(home, "neatd.pid");
|
|
25143
25358
|
await writeAtomically(pidPath, `${process.pid}
|
|
25144
25359
|
`);
|
|
25145
25360
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -25351,7 +25566,7 @@ async function startDaemon(opts = {}) {
|
|
|
25351
25566
|
}
|
|
25352
25567
|
if (restApp) await restApp.close().catch(() => {
|
|
25353
25568
|
});
|
|
25354
|
-
await
|
|
25569
|
+
await import_node_fs42.promises.unlink(pidPath).catch(() => {
|
|
25355
25570
|
});
|
|
25356
25571
|
throw new Error(
|
|
25357
25572
|
`neatd: failed to bind REST on port ${restPort} \u2014 ${err.message}`
|
|
@@ -25529,7 +25744,7 @@ async function startDaemon(opts = {}) {
|
|
|
25529
25744
|
});
|
|
25530
25745
|
if (otlpApp) await otlpApp.close().catch(() => {
|
|
25531
25746
|
});
|
|
25532
|
-
await
|
|
25747
|
+
await import_node_fs42.promises.unlink(pidPath).catch(() => {
|
|
25533
25748
|
});
|
|
25534
25749
|
throw new Error(
|
|
25535
25750
|
`neatd: failed to bind OTLP on port ${otlpPort} \u2014 ${err.message}`
|
|
@@ -25564,7 +25779,7 @@ async function startDaemon(opts = {}) {
|
|
|
25564
25779
|
});
|
|
25565
25780
|
if (otlpApp) await otlpApp.close().catch(() => {
|
|
25566
25781
|
});
|
|
25567
|
-
await
|
|
25782
|
+
await import_node_fs42.promises.unlink(pidPath).catch(() => {
|
|
25568
25783
|
});
|
|
25569
25784
|
throw new Error(
|
|
25570
25785
|
`neatd: failed to write daemon.json for "${singleProject}" \u2014 ${err.message}`
|
|
@@ -25611,9 +25826,9 @@ async function startDaemon(opts = {}) {
|
|
|
25611
25826
|
let registryWatcher = null;
|
|
25612
25827
|
let reloadTimer = null;
|
|
25613
25828
|
if (!singleProject) try {
|
|
25614
|
-
const regDir =
|
|
25615
|
-
const regBase =
|
|
25616
|
-
registryWatcher = (0,
|
|
25829
|
+
const regDir = import_node_path80.default.dirname(regPath);
|
|
25830
|
+
const regBase = import_node_path80.default.basename(regPath);
|
|
25831
|
+
registryWatcher = (0, import_node_fs42.watch)(regDir, (_eventType, filename) => {
|
|
25617
25832
|
if (filename !== null && filename !== regBase) return;
|
|
25618
25833
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
25619
25834
|
reloadTimer = setTimeout(() => {
|
|
@@ -25662,7 +25877,7 @@ async function startDaemon(opts = {}) {
|
|
|
25662
25877
|
if (daemonRecord) {
|
|
25663
25878
|
await clearDaemonRecord(daemonRecord, home);
|
|
25664
25879
|
}
|
|
25665
|
-
await
|
|
25880
|
+
await import_node_fs42.promises.unlink(pidPath).catch(() => {
|
|
25666
25881
|
});
|
|
25667
25882
|
};
|
|
25668
25883
|
return {
|