@neat.is/core 0.9.18 → 0.9.20-dev.20260919
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-MGQSR6QZ.js → chunk-NTVHVZYC.js} +191 -29
- package/dist/chunk-NTVHVZYC.js.map +1 -0
- package/dist/cli.cjs +1133 -1013
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +158 -47
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +259 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/neatd.cjs +271 -108
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +1 -1
- package/package.json +3 -2
- package/dist/chunk-MGQSR6QZ.js.map +0 -1
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 path79 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
64
|
+
if (exactUnauthPaths.has(path79) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path79)) {
|
|
65
65
|
done();
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
@@ -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 path79 = q === -1 ? v : v.slice(0, q);
|
|
418
|
+
if (path79.length > 0) return path79;
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
421
|
return void 0;
|
|
@@ -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, path79, edges) {
|
|
1378
|
+
if (path79.length > best.path.length) {
|
|
1379
|
+
best = { path: [...path79], edges: [...edges] };
|
|
1380
1380
|
}
|
|
1381
|
-
if (
|
|
1381
|
+
if (path79.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
|
+
path79.push(srcId);
|
|
1387
1387
|
edges.push(edge);
|
|
1388
|
-
step(srcId,
|
|
1389
|
-
|
|
1388
|
+
step(srcId, path79, edges);
|
|
1389
|
+
path79.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 path79 = [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
|
+
path79.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: path79, 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 path79 = [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
|
+
path79.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: path79, 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 path79 = [...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
|
+
path79.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: path79,
|
|
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: path79,
|
|
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 path79 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
|
|
2353
|
+
if (path79) {
|
|
2354
|
+
traversalPath = path79.nodes;
|
|
2355
|
+
edgeProvenances = path79.edges.map((e) => e.provenance);
|
|
2356
2356
|
} else {
|
|
2357
2357
|
traversalPath = [errorNodeId, top.node];
|
|
2358
2358
|
edgeProvenances = [top.provenance ?? import_types.Provenance.OBSERVED];
|
|
@@ -3791,8 +3791,8 @@ function chiRoutesFromSource(source, parser) {
|
|
|
3791
3791
|
chiWalk(tree.rootNode, "", out);
|
|
3792
3792
|
return out;
|
|
3793
3793
|
}
|
|
3794
|
-
function stripChiRegex(
|
|
3795
|
-
return
|
|
3794
|
+
function stripChiRegex(path79) {
|
|
3795
|
+
return path79.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
|
|
3796
3796
|
}
|
|
3797
3797
|
function chiWalk(node, prefix, out) {
|
|
3798
3798
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
@@ -4464,9 +4464,9 @@ function rubyRocketRoute(args) {
|
|
|
4464
4464
|
if (!pair || pair.type !== "pair") continue;
|
|
4465
4465
|
const k = pair.childForFieldName("key");
|
|
4466
4466
|
if (k?.type !== "string") continue;
|
|
4467
|
-
const
|
|
4468
|
-
if (
|
|
4469
|
-
return { path:
|
|
4467
|
+
const path79 = rubyLiteral(k);
|
|
4468
|
+
if (path79 === null) continue;
|
|
4469
|
+
return { path: path79, target: rubyLiteral(pair.childForFieldName("value")) };
|
|
4470
4470
|
}
|
|
4471
4471
|
return null;
|
|
4472
4472
|
}
|
|
@@ -10688,10 +10688,10 @@ function grpcMethodsFromProto(content, fqPackage) {
|
|
|
10688
10688
|
}
|
|
10689
10689
|
const body = content.slice(bodyStart, i - 1);
|
|
10690
10690
|
const rpcRe = /\brpc\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(/g;
|
|
10691
|
-
let
|
|
10692
|
-
while ((
|
|
10693
|
-
const rpcMethod =
|
|
10694
|
-
const line = lineAt(content, bodyStart +
|
|
10691
|
+
let rm2;
|
|
10692
|
+
while ((rm2 = rpcRe.exec(body)) !== null) {
|
|
10693
|
+
const rpcMethod = rm2[1];
|
|
10694
|
+
const line = lineAt(content, bodyStart + rm2.index);
|
|
10695
10695
|
out.push({ rpcService, rpcMethod, line });
|
|
10696
10696
|
}
|
|
10697
10697
|
serviceRe.lastIndex = i;
|
|
@@ -19573,10 +19573,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
|
|
|
19573
19573
|
// src/connectors/supabase/map.ts
|
|
19574
19574
|
var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
|
|
19575
19575
|
var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
|
|
19576
|
-
function targetFromRestPath(
|
|
19577
|
-
const rpcMatch = REST_RPC_PATH_RE.exec(
|
|
19576
|
+
function targetFromRestPath(path79) {
|
|
19577
|
+
const rpcMatch = REST_RPC_PATH_RE.exec(path79);
|
|
19578
19578
|
if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
|
|
19579
|
-
const tableMatch = REST_TABLE_PATH_RE.exec(
|
|
19579
|
+
const tableMatch = REST_TABLE_PATH_RE.exec(path79);
|
|
19580
19580
|
if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
|
|
19581
19581
|
return null;
|
|
19582
19582
|
}
|
|
@@ -20180,9 +20180,9 @@ function parseFirebaseTargetName(targetName) {
|
|
|
20180
20180
|
const secondSep = rest.indexOf(FIELD_SEP);
|
|
20181
20181
|
if (secondSep === -1) return null;
|
|
20182
20182
|
const method = rest.slice(0, secondSep);
|
|
20183
|
-
const
|
|
20184
|
-
if (!resourceName || !method || !
|
|
20185
|
-
return { resourceName, method, path:
|
|
20183
|
+
const path79 = rest.slice(secondSep + 1);
|
|
20184
|
+
if (!resourceName || !method || !path79) return null;
|
|
20185
|
+
return { resourceName, method, path: path79 };
|
|
20186
20186
|
}
|
|
20187
20187
|
function resourceNameFor(type, labels) {
|
|
20188
20188
|
if (!labels) return null;
|
|
@@ -20220,14 +20220,14 @@ function mapLogEntryToSignal(entry) {
|
|
|
20220
20220
|
if (!req) return null;
|
|
20221
20221
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
20222
20222
|
const method = req.requestMethod.toUpperCase();
|
|
20223
|
-
const
|
|
20224
|
-
if (
|
|
20223
|
+
const path79 = pathFromRequestUrl(req.requestUrl);
|
|
20224
|
+
if (path79 === null) return null;
|
|
20225
20225
|
const timestamp = entry.timestamp;
|
|
20226
20226
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
20227
20227
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
|
|
20228
20228
|
return {
|
|
20229
20229
|
targetKind: resourceType,
|
|
20230
|
-
targetName: packFirebaseTargetName({ resourceName, method, path:
|
|
20230
|
+
targetName: packFirebaseTargetName({ resourceName, method, path: path79 }),
|
|
20231
20231
|
callCount: 1,
|
|
20232
20232
|
errorCount: isError ? 1 : 0,
|
|
20233
20233
|
lastObservedIso: timestamp
|
|
@@ -20434,7 +20434,7 @@ function mapEventToSignal(event) {
|
|
|
20434
20434
|
if (Number.isNaN(observedAt.getTime())) return null;
|
|
20435
20435
|
const statusCode = metadata?.statusCode;
|
|
20436
20436
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
20437
|
-
const
|
|
20437
|
+
const path79 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
20438
20438
|
return {
|
|
20439
20439
|
targetKind: CLOUDFLARE_TARGET_KIND,
|
|
20440
20440
|
targetName: scriptName,
|
|
@@ -20442,7 +20442,7 @@ function mapEventToSignal(event) {
|
|
|
20442
20442
|
errorCount: isError ? 1 : 0,
|
|
20443
20443
|
lastObservedIso: observedAt.toISOString(),
|
|
20444
20444
|
method,
|
|
20445
|
-
...
|
|
20445
|
+
...path79 ? { path: path79 } : {},
|
|
20446
20446
|
...typeof statusCode === "number" ? { statusCode } : {},
|
|
20447
20447
|
...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
|
|
20448
20448
|
};
|
|
@@ -20488,8 +20488,8 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
20488
20488
|
});
|
|
20489
20489
|
return found;
|
|
20490
20490
|
}
|
|
20491
|
-
function findMatchingRouteNode(graph, serviceName, method,
|
|
20492
|
-
const normalizedPath = normalizePathTemplate(
|
|
20491
|
+
function findMatchingRouteNode(graph, serviceName, method, path79) {
|
|
20492
|
+
const normalizedPath = normalizePathTemplate(path79);
|
|
20493
20493
|
let found = null;
|
|
20494
20494
|
graph.forEachNode((id, attrs) => {
|
|
20495
20495
|
if (found) return;
|
|
@@ -20506,10 +20506,10 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
20506
20506
|
return (signal) => {
|
|
20507
20507
|
if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
|
|
20508
20508
|
const scriptName = signal.targetName;
|
|
20509
|
-
const { method, path:
|
|
20509
|
+
const { method, path: path79 } = signal;
|
|
20510
20510
|
const resolveRouteGrain = (serviceName, wholeFileId) => {
|
|
20511
|
-
if (!method || !
|
|
20512
|
-
return findMatchingRouteNode(graph, serviceName, method,
|
|
20511
|
+
if (!method || !path79) return wholeFileId;
|
|
20512
|
+
return findMatchingRouteNode(graph, serviceName, method, path79) ?? wholeFileId;
|
|
20513
20513
|
};
|
|
20514
20514
|
const mapping = config.workers?.[scriptName];
|
|
20515
20515
|
if (mapping) {
|
|
@@ -20861,9 +20861,9 @@ function parseCloudRunTargetName(targetName) {
|
|
|
20861
20861
|
const secondSep = rest.indexOf(FIELD_SEP2);
|
|
20862
20862
|
if (secondSep === -1) return null;
|
|
20863
20863
|
const method = rest.slice(0, secondSep);
|
|
20864
|
-
const
|
|
20865
|
-
if (!serviceName || !method || !
|
|
20866
|
-
return { serviceName, method, path:
|
|
20864
|
+
const path79 = rest.slice(secondSep + 1);
|
|
20865
|
+
if (!serviceName || !method || !path79) return null;
|
|
20866
|
+
return { serviceName, method, path: path79 };
|
|
20867
20867
|
}
|
|
20868
20868
|
|
|
20869
20869
|
// src/connectors/cloud-run/map.ts
|
|
@@ -20892,14 +20892,14 @@ function mapLogEntryToSignal2(entry) {
|
|
|
20892
20892
|
if (!req) return null;
|
|
20893
20893
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
20894
20894
|
const method = req.requestMethod.toUpperCase();
|
|
20895
|
-
const
|
|
20896
|
-
if (
|
|
20895
|
+
const path79 = pathFromRequestUrl2(req.requestUrl);
|
|
20896
|
+
if (path79 === null) return null;
|
|
20897
20897
|
const timestamp = entry.timestamp;
|
|
20898
20898
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
20899
20899
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD4;
|
|
20900
20900
|
return {
|
|
20901
20901
|
targetKind: CLOUD_RUN_TARGET_KIND,
|
|
20902
|
-
targetName: packCloudRunTargetName({ serviceName, method, path:
|
|
20902
|
+
targetName: packCloudRunTargetName({ serviceName, method, path: path79 }),
|
|
20903
20903
|
callCount: 1,
|
|
20904
20904
|
errorCount: isError ? 1 : 0,
|
|
20905
20905
|
lastObservedIso: timestamp
|
|
@@ -20938,14 +20938,14 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
20938
20938
|
if (signal.targetKind !== CLOUD_RUN_TARGET_KIND) return null;
|
|
20939
20939
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
20940
20940
|
if (!identity) return null;
|
|
20941
|
-
const { serviceName: gcpServiceName, method, path:
|
|
20941
|
+
const { serviceName: gcpServiceName, method, path: path79 } = identity;
|
|
20942
20942
|
const mappedService = config.serviceMap?.[gcpServiceName];
|
|
20943
20943
|
if (mappedService) {
|
|
20944
20944
|
const routeNodeId = findMatchingRouteNode2(
|
|
20945
20945
|
graph,
|
|
20946
20946
|
mappedService,
|
|
20947
20947
|
method,
|
|
20948
|
-
normalizePathTemplate(
|
|
20948
|
+
normalizePathTemplate(path79)
|
|
20949
20949
|
);
|
|
20950
20950
|
if (routeNodeId) {
|
|
20951
20951
|
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types81.EdgeType.CALLS };
|
|
@@ -21081,9 +21081,9 @@ function parseGcpLbTargetName(targetName) {
|
|
|
21081
21081
|
const secondSep = rest.indexOf(FIELD_SEP3);
|
|
21082
21082
|
if (secondSep === -1) return null;
|
|
21083
21083
|
const method = rest.slice(0, secondSep);
|
|
21084
|
-
const
|
|
21085
|
-
if (!backendServiceName || !method || !
|
|
21086
|
-
return { backendServiceName, method, path:
|
|
21084
|
+
const path79 = rest.slice(secondSep + 1);
|
|
21085
|
+
if (!backendServiceName || !method || !path79) return null;
|
|
21086
|
+
return { backendServiceName, method, path: path79 };
|
|
21087
21087
|
}
|
|
21088
21088
|
|
|
21089
21089
|
// src/connectors/gcp-lb/map.ts
|
|
@@ -21112,14 +21112,14 @@ function mapLogEntryToSignal3(entry) {
|
|
|
21112
21112
|
if (!req) return null;
|
|
21113
21113
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
21114
21114
|
const method = req.requestMethod.toUpperCase();
|
|
21115
|
-
const
|
|
21116
|
-
if (
|
|
21115
|
+
const path79 = pathFromRequestUrl3(req.requestUrl);
|
|
21116
|
+
if (path79 === null) return null;
|
|
21117
21117
|
const timestamp = entry.timestamp;
|
|
21118
21118
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
21119
21119
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD5;
|
|
21120
21120
|
return {
|
|
21121
21121
|
targetKind: GCP_LB_TARGET_KIND,
|
|
21122
|
-
targetName: packGcpLbTargetName({ backendServiceName, method, path:
|
|
21122
|
+
targetName: packGcpLbTargetName({ backendServiceName, method, path: path79 }),
|
|
21123
21123
|
callCount: 1,
|
|
21124
21124
|
errorCount: isError ? 1 : 0,
|
|
21125
21125
|
lastObservedIso: timestamp
|
|
@@ -21158,14 +21158,14 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21158
21158
|
if (signal.targetKind !== GCP_LB_TARGET_KIND) return null;
|
|
21159
21159
|
const identity = parseGcpLbTargetName(signal.targetName);
|
|
21160
21160
|
if (!identity) return null;
|
|
21161
|
-
const { backendServiceName, method, path:
|
|
21161
|
+
const { backendServiceName, method, path: path79 } = identity;
|
|
21162
21162
|
const mappedService = config.backendServiceMap?.[backendServiceName];
|
|
21163
21163
|
if (mappedService) {
|
|
21164
21164
|
const routeNodeId = findMatchingRouteNode3(
|
|
21165
21165
|
graph,
|
|
21166
21166
|
mappedService,
|
|
21167
21167
|
method,
|
|
21168
|
-
normalizePathTemplate(
|
|
21168
|
+
normalizePathTemplate(path79)
|
|
21169
21169
|
);
|
|
21170
21170
|
if (routeNodeId) {
|
|
21171
21171
|
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
|
|
@@ -23369,7 +23369,7 @@ init_otel_grpc();
|
|
|
23369
23369
|
// src/daemon.ts
|
|
23370
23370
|
init_cjs_shims();
|
|
23371
23371
|
var import_node_fs41 = require("fs");
|
|
23372
|
-
var
|
|
23372
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
23373
23373
|
var import_node_module = require("module");
|
|
23374
23374
|
init_otel();
|
|
23375
23375
|
|
|
@@ -23407,13 +23407,13 @@ async function reconcileFrontierSurfaces(graph, errorsPath) {
|
|
|
23407
23407
|
init_cjs_shims();
|
|
23408
23408
|
var CREDENTIAL_REFRESH_SKEW_MS = 6e4;
|
|
23409
23409
|
var CP_REQUEST_TIMEOUT_MS = 1e4;
|
|
23410
|
-
async function cpGet(
|
|
23410
|
+
async function cpGet(path79, deps) {
|
|
23411
23411
|
const f = deps.fetchImpl ?? fetch;
|
|
23412
|
-
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${
|
|
23412
|
+
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${path79}`, {
|
|
23413
23413
|
headers: { authorization: `Bearer ${deps.daemonToken}`, accept: "application/json" },
|
|
23414
23414
|
signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS)
|
|
23415
23415
|
});
|
|
23416
|
-
if (!res.ok) throw new Error(`control plane ${
|
|
23416
|
+
if (!res.ok) throw new Error(`control plane ${path79} \u2192 HTTP ${res.status}`);
|
|
23417
23417
|
return await res.json();
|
|
23418
23418
|
}
|
|
23419
23419
|
function credentialRecord(provider, cred) {
|
|
@@ -23519,6 +23519,156 @@ async function maybeStartHostedConnectors(input) {
|
|
|
23519
23519
|
});
|
|
23520
23520
|
}
|
|
23521
23521
|
|
|
23522
|
+
// src/connectors/hosted-repos.ts
|
|
23523
|
+
init_cjs_shims();
|
|
23524
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
23525
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
23526
|
+
var import_promises = require("fs/promises");
|
|
23527
|
+
var CP_REQUEST_TIMEOUT_MS2 = 1e4;
|
|
23528
|
+
var DEFAULT_SYNC_INTERVAL_MS = 5 * 6e4;
|
|
23529
|
+
var CLONE_TIMEOUT_MS = 5 * 6e4;
|
|
23530
|
+
function scrubToken(s) {
|
|
23531
|
+
return s.replace(/x-access-token:[^@\s]+@/g, "x-access-token:***@");
|
|
23532
|
+
}
|
|
23533
|
+
async function cpGet2(pathname, deps) {
|
|
23534
|
+
const f = deps.fetchImpl ?? fetch;
|
|
23535
|
+
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${pathname}`, {
|
|
23536
|
+
headers: { authorization: `Bearer ${deps.daemonToken}`, accept: "application/json" },
|
|
23537
|
+
signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS2)
|
|
23538
|
+
});
|
|
23539
|
+
if (!res.ok) throw new Error(`control plane ${pathname} \u2192 HTTP ${res.status}`);
|
|
23540
|
+
return await res.json();
|
|
23541
|
+
}
|
|
23542
|
+
async function cpPostStatus(deps, owner, name, body) {
|
|
23543
|
+
const f = deps.fetchImpl ?? fetch;
|
|
23544
|
+
const url = `${deps.cpUrl.replace(/\/+$/, "")}/internal/projects/${deps.projectId}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/status`;
|
|
23545
|
+
const res = await f(url, {
|
|
23546
|
+
method: "POST",
|
|
23547
|
+
headers: { authorization: `Bearer ${deps.daemonToken}`, "content-type": "application/json" },
|
|
23548
|
+
body: JSON.stringify(body),
|
|
23549
|
+
signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS2)
|
|
23550
|
+
});
|
|
23551
|
+
if (!res.ok && res.status !== 404) throw new Error(`control plane status POST \u2192 HTTP ${res.status}`);
|
|
23552
|
+
}
|
|
23553
|
+
var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
23554
|
+
const [{ default: git }, httpMod, fs40] = await Promise.all([
|
|
23555
|
+
import("isomorphic-git"),
|
|
23556
|
+
import("isomorphic-git/http/node"),
|
|
23557
|
+
import("fs")
|
|
23558
|
+
]);
|
|
23559
|
+
const http = httpMod.default ?? httpMod;
|
|
23560
|
+
const parsed = new URL(cloneUrl);
|
|
23561
|
+
const password = parsed.password || parsed.username;
|
|
23562
|
+
const username = parsed.password ? parsed.username : "x-access-token";
|
|
23563
|
+
const cleanUrl = `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
|
|
23564
|
+
const clone = git.clone({
|
|
23565
|
+
fs: fs40,
|
|
23566
|
+
http,
|
|
23567
|
+
dir: destDir,
|
|
23568
|
+
url: cleanUrl,
|
|
23569
|
+
// Absent ref → isomorphic-git clones the remote's default branch.
|
|
23570
|
+
...ref ? { ref } : {},
|
|
23571
|
+
singleBranch: true,
|
|
23572
|
+
depth: 1,
|
|
23573
|
+
onAuth: () => ({ username, password })
|
|
23574
|
+
});
|
|
23575
|
+
let timer;
|
|
23576
|
+
const timeout = new Promise((_, reject) => {
|
|
23577
|
+
timer = setTimeout(() => reject(new Error(`clone timed out after ${CLONE_TIMEOUT_MS}ms`)), CLONE_TIMEOUT_MS);
|
|
23578
|
+
});
|
|
23579
|
+
try {
|
|
23580
|
+
await Promise.race([clone, timeout]);
|
|
23581
|
+
} finally {
|
|
23582
|
+
if (timer) clearTimeout(timer);
|
|
23583
|
+
}
|
|
23584
|
+
};
|
|
23585
|
+
function needsSync(r) {
|
|
23586
|
+
return r.syncStatus === void 0 || r.syncStatus === "syncing";
|
|
23587
|
+
}
|
|
23588
|
+
async function syncOneRepo(r, input) {
|
|
23589
|
+
const { deps, graph } = input;
|
|
23590
|
+
const cloneRepo = input.cloneRepo ?? defaultCloneRepo;
|
|
23591
|
+
const extract = input.extract ?? extractFromDirectory;
|
|
23592
|
+
const label = `${r.owner}/${r.name}`;
|
|
23593
|
+
const tmpRoot = input.tmpRoot ?? import_node_os5.default.tmpdir();
|
|
23594
|
+
let dir;
|
|
23595
|
+
try {
|
|
23596
|
+
dir = await (0, import_promises.mkdtemp)(import_node_path75.default.join(tmpRoot, "neat-repo-"));
|
|
23597
|
+
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
23598
|
+
await extract(graph, dir);
|
|
23599
|
+
await cpPostStatus(deps, r.owner, r.name, {
|
|
23600
|
+
syncStatus: "synced",
|
|
23601
|
+
lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
|
|
23602
|
+
});
|
|
23603
|
+
} catch (err) {
|
|
23604
|
+
input.onError?.(label, err);
|
|
23605
|
+
await cpPostStatus(deps, r.owner, r.name, {
|
|
23606
|
+
syncStatus: "failed",
|
|
23607
|
+
detail: scrubToken(err.message).slice(0, 300)
|
|
23608
|
+
}).catch(() => {
|
|
23609
|
+
});
|
|
23610
|
+
} finally {
|
|
23611
|
+
if (dir) await (0, import_promises.rm)(dir, { recursive: true, force: true }).catch(() => {
|
|
23612
|
+
});
|
|
23613
|
+
}
|
|
23614
|
+
}
|
|
23615
|
+
async function runRepoSyncPass(input) {
|
|
23616
|
+
let repos;
|
|
23617
|
+
try {
|
|
23618
|
+
repos = await cpGet2(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
23619
|
+
} catch (err) {
|
|
23620
|
+
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
23621
|
+
return;
|
|
23622
|
+
}
|
|
23623
|
+
if (!Array.isArray(repos)) return;
|
|
23624
|
+
for (const r of repos) {
|
|
23625
|
+
if (!needsSync(r)) continue;
|
|
23626
|
+
await syncOneRepo(r, input);
|
|
23627
|
+
}
|
|
23628
|
+
}
|
|
23629
|
+
async function startRepoSync(input) {
|
|
23630
|
+
const intervalMs = input.intervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
|
|
23631
|
+
let stopped = false;
|
|
23632
|
+
let running = false;
|
|
23633
|
+
const tick = async () => {
|
|
23634
|
+
if (stopped || running) return;
|
|
23635
|
+
running = true;
|
|
23636
|
+
try {
|
|
23637
|
+
await runRepoSyncPass(input);
|
|
23638
|
+
} finally {
|
|
23639
|
+
running = false;
|
|
23640
|
+
}
|
|
23641
|
+
};
|
|
23642
|
+
void tick();
|
|
23643
|
+
const timer = setInterval(() => {
|
|
23644
|
+
void tick();
|
|
23645
|
+
}, intervalMs);
|
|
23646
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
23647
|
+
return () => {
|
|
23648
|
+
stopped = true;
|
|
23649
|
+
clearInterval(timer);
|
|
23650
|
+
};
|
|
23651
|
+
}
|
|
23652
|
+
async function maybeStartRepoSync(input) {
|
|
23653
|
+
const env = input.env ?? process.env;
|
|
23654
|
+
const cpUrl = env.NEAT_CP_URL;
|
|
23655
|
+
const projectId = env.NEAT_CP_PROJECT_ID;
|
|
23656
|
+
const daemonToken = env.NEAT_AUTH_TOKEN;
|
|
23657
|
+
if (!cpUrl || !projectId || !daemonToken) return () => {
|
|
23658
|
+
};
|
|
23659
|
+
return startRepoSync({
|
|
23660
|
+
deps: { cpUrl, projectId, daemonToken, ...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {} },
|
|
23661
|
+
graph: input.graph,
|
|
23662
|
+
project: input.project,
|
|
23663
|
+
...input.cloneRepo ? { cloneRepo: input.cloneRepo } : {},
|
|
23664
|
+
...input.extract ? { extract: input.extract } : {},
|
|
23665
|
+
...input.intervalMs !== void 0 ? { intervalMs: input.intervalMs } : {},
|
|
23666
|
+
...input.tmpRoot ? { tmpRoot: input.tmpRoot } : {},
|
|
23667
|
+
...input.onSkip ? { onSkip: input.onSkip } : {},
|
|
23668
|
+
...input.onError ? { onError: input.onError } : {}
|
|
23669
|
+
});
|
|
23670
|
+
}
|
|
23671
|
+
|
|
23522
23672
|
// src/connectors/kubernetes/index.ts
|
|
23523
23673
|
init_cjs_shims();
|
|
23524
23674
|
|
|
@@ -23572,9 +23722,9 @@ function makeK8sFetchImpl(transport) {
|
|
|
23572
23722
|
req.end();
|
|
23573
23723
|
}));
|
|
23574
23724
|
}
|
|
23575
|
-
async function listResource(transport, namespace,
|
|
23725
|
+
async function listResource(transport, namespace, path79, opts = {}) {
|
|
23576
23726
|
const base = opts.apiUrl ?? transport.server;
|
|
23577
|
-
const url = `${base.replace(/\/$/, "")}${
|
|
23727
|
+
const url = `${base.replace(/\/$/, "")}${path79}`;
|
|
23578
23728
|
const fetchImpl = opts.fetchImpl ?? makeK8sFetchImpl(transport);
|
|
23579
23729
|
const res = await junctionFetch(
|
|
23580
23730
|
url,
|
|
@@ -23584,7 +23734,7 @@ async function listResource(transport, namespace, path78, opts = {}) {
|
|
|
23584
23734
|
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, fetchImpl }
|
|
23585
23735
|
);
|
|
23586
23736
|
if (!res.ok) {
|
|
23587
|
-
throw new Error(`kubernetes ${
|
|
23737
|
+
throw new Error(`kubernetes ${path79} failed: ${res.status} ${res.statusText}`);
|
|
23588
23738
|
}
|
|
23589
23739
|
const json = await res.json();
|
|
23590
23740
|
return Array.isArray(json.items) ? json.items : [];
|
|
@@ -23886,21 +24036,21 @@ function createK8sResolveTarget(graph) {
|
|
|
23886
24036
|
|
|
23887
24037
|
// src/connectors/kubernetes/substrate.ts
|
|
23888
24038
|
init_cjs_shims();
|
|
23889
|
-
var
|
|
23890
|
-
var
|
|
23891
|
-
var
|
|
24039
|
+
var import_promises2 = require("fs/promises");
|
|
24040
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
24041
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
23892
24042
|
function defaultHome() {
|
|
23893
24043
|
const override = process.env.NEAT_HOME;
|
|
23894
|
-
if (override && override.length > 0) return
|
|
23895
|
-
return
|
|
24044
|
+
if (override && override.length > 0) return import_node_path76.default.resolve(override);
|
|
24045
|
+
return import_node_path76.default.join(import_node_os6.default.homedir(), ".neat");
|
|
23896
24046
|
}
|
|
23897
24047
|
function k8sSubstrateConfigPath(home = defaultHome()) {
|
|
23898
|
-
return
|
|
24048
|
+
return import_node_path76.default.join(home, "k8s.json");
|
|
23899
24049
|
}
|
|
23900
24050
|
async function readK8sSubstrateConfig(home = defaultHome()) {
|
|
23901
24051
|
let raw;
|
|
23902
24052
|
try {
|
|
23903
|
-
raw = await (0,
|
|
24053
|
+
raw = await (0, import_promises2.readFile)(k8sSubstrateConfigPath(home), "utf8");
|
|
23904
24054
|
} catch {
|
|
23905
24055
|
return { version: 1, deployments: [] };
|
|
23906
24056
|
}
|
|
@@ -23995,7 +24145,7 @@ init_auth();
|
|
|
23995
24145
|
// src/unrouted.ts
|
|
23996
24146
|
init_cjs_shims();
|
|
23997
24147
|
var import_node_fs40 = require("fs");
|
|
23998
|
-
var
|
|
24148
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
23999
24149
|
function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new Date()) {
|
|
24000
24150
|
return {
|
|
24001
24151
|
timestamp: now.toISOString(),
|
|
@@ -24005,34 +24155,34 @@ function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new
|
|
|
24005
24155
|
};
|
|
24006
24156
|
}
|
|
24007
24157
|
async function appendUnroutedSpan(neatHome3, record) {
|
|
24008
|
-
const target =
|
|
24158
|
+
const target = import_node_path77.default.join(neatHome3, "errors.ndjson");
|
|
24009
24159
|
await import_node_fs40.promises.mkdir(neatHome3, { recursive: true });
|
|
24010
24160
|
await import_node_fs40.promises.appendFile(target, JSON.stringify(record) + "\n", "utf8");
|
|
24011
24161
|
}
|
|
24012
24162
|
function unroutedErrorsPath(neatHome3) {
|
|
24013
|
-
return
|
|
24163
|
+
return import_node_path77.default.join(neatHome3, "errors.ndjson");
|
|
24014
24164
|
}
|
|
24015
24165
|
|
|
24016
24166
|
// src/daemon.ts
|
|
24017
24167
|
var import_types106 = require("@neat.is/types");
|
|
24018
24168
|
function daemonJsonPath(scanPath) {
|
|
24019
|
-
return
|
|
24169
|
+
return import_node_path78.default.join(scanPath, "neat-out", "daemon.json");
|
|
24020
24170
|
}
|
|
24021
24171
|
function daemonsDiscoveryDir(home) {
|
|
24022
24172
|
const base = home && home.length > 0 ? home : neatHomeFromEnv();
|
|
24023
|
-
return
|
|
24173
|
+
return import_node_path78.default.join(base, "daemons");
|
|
24024
24174
|
}
|
|
24025
24175
|
function daemonDiscoveryPath(project, home) {
|
|
24026
|
-
return
|
|
24176
|
+
return import_node_path78.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
|
|
24027
24177
|
}
|
|
24028
24178
|
function sanitizeDiscoveryName(project) {
|
|
24029
24179
|
return project.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
24030
24180
|
}
|
|
24031
24181
|
function neatHomeFromEnv() {
|
|
24032
24182
|
const env = process.env.NEAT_HOME;
|
|
24033
|
-
if (env && env.length > 0) return
|
|
24183
|
+
if (env && env.length > 0) return import_node_path78.default.resolve(env);
|
|
24034
24184
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24035
|
-
return
|
|
24185
|
+
return import_node_path78.default.join(home, ".neat");
|
|
24036
24186
|
}
|
|
24037
24187
|
function resolveNeatVersion() {
|
|
24038
24188
|
if (process.env.NEAT_LOCAL_VERSION && process.env.NEAT_LOCAL_VERSION.length > 0) {
|
|
@@ -24089,17 +24239,21 @@ function teardownSlot(slot) {
|
|
|
24089
24239
|
slot.stopK8sSubstrate();
|
|
24090
24240
|
} catch {
|
|
24091
24241
|
}
|
|
24242
|
+
try {
|
|
24243
|
+
slot.stopRepoSync();
|
|
24244
|
+
} catch {
|
|
24245
|
+
}
|
|
24092
24246
|
try {
|
|
24093
24247
|
slot.detachEvents();
|
|
24094
24248
|
} catch {
|
|
24095
24249
|
}
|
|
24096
24250
|
}
|
|
24097
24251
|
function neatHomeFor(opts) {
|
|
24098
|
-
if (opts.neatHome && opts.neatHome.length > 0) return
|
|
24252
|
+
if (opts.neatHome && opts.neatHome.length > 0) return import_node_path78.default.resolve(opts.neatHome);
|
|
24099
24253
|
const env = process.env.NEAT_HOME;
|
|
24100
|
-
if (env && env.length > 0) return
|
|
24254
|
+
if (env && env.length > 0) return import_node_path78.default.resolve(env);
|
|
24101
24255
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24102
|
-
return
|
|
24256
|
+
return import_node_path78.default.join(home, ".neat");
|
|
24103
24257
|
}
|
|
24104
24258
|
function routeSpanToProject(serviceName, projects) {
|
|
24105
24259
|
if (!serviceName) return DEFAULT_PROJECT;
|
|
@@ -24151,7 +24305,7 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
24151
24305
|
);
|
|
24152
24306
|
}
|
|
24153
24307
|
async function bootstrapProject(entry, connectors = [], neatHome3) {
|
|
24154
|
-
const paths = pathsForProject(entry.name,
|
|
24308
|
+
const paths = pathsForProject(entry.name, import_node_path78.default.join(entry.path, "neat-out"));
|
|
24155
24309
|
try {
|
|
24156
24310
|
const stat = await import_node_fs41.promises.stat(entry.path);
|
|
24157
24311
|
if (!stat.isDirectory()) {
|
|
@@ -24177,6 +24331,8 @@ async function bootstrapProject(entry, connectors = [], neatHome3) {
|
|
|
24177
24331
|
},
|
|
24178
24332
|
stopK8sSubstrate: () => {
|
|
24179
24333
|
},
|
|
24334
|
+
stopRepoSync: () => {
|
|
24335
|
+
},
|
|
24180
24336
|
detachEvents: () => {
|
|
24181
24337
|
},
|
|
24182
24338
|
status: "broken",
|
|
@@ -24228,6 +24384,12 @@ async function bootstrapProject(entry, connectors = [], neatHome3) {
|
|
|
24228
24384
|
...neatHome3 ? { home: neatHome3 } : {},
|
|
24229
24385
|
onSkip: (skipped, reason) => console.warn(`neatd: k8s substrate "${skipped.id}" skipped for project "${entry.name}" \u2014 ${reason}`)
|
|
24230
24386
|
});
|
|
24387
|
+
const stopRepoSync = await maybeStartRepoSync({
|
|
24388
|
+
project: entry.name,
|
|
24389
|
+
graph,
|
|
24390
|
+
onSkip: (repo, reason) => console.warn(`neatd: repo-sync "${repo}" skipped for project "${entry.name}" \u2014 ${reason}`),
|
|
24391
|
+
onError: (repo, err) => console.warn(`neatd: repo-sync "${repo}" failed for project "${entry.name}" \u2014 ${err.message}`)
|
|
24392
|
+
});
|
|
24231
24393
|
await touchLastSeen(entry.name).catch(() => {
|
|
24232
24394
|
});
|
|
24233
24395
|
return {
|
|
@@ -24240,6 +24402,7 @@ async function bootstrapProject(entry, connectors = [], neatHome3) {
|
|
|
24240
24402
|
stopConnectors,
|
|
24241
24403
|
stopHostedConnectors,
|
|
24242
24404
|
stopK8sSubstrate,
|
|
24405
|
+
stopRepoSync,
|
|
24243
24406
|
detachEvents,
|
|
24244
24407
|
status: "active"
|
|
24245
24408
|
};
|
|
@@ -24296,7 +24459,7 @@ async function startDaemon(opts = {}) {
|
|
|
24296
24459
|
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;
|
|
24297
24460
|
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;
|
|
24298
24461
|
const singleProject = projectArg;
|
|
24299
|
-
const singleProjectPath = singleProject && projectPathArg ?
|
|
24462
|
+
const singleProjectPath = singleProject && projectPathArg ? import_node_path78.default.resolve(projectPathArg) : null;
|
|
24300
24463
|
if (singleProject && !singleProjectPath) {
|
|
24301
24464
|
throw new Error(
|
|
24302
24465
|
`neatd: project "${singleProject}" given without a projectPath; pass NEAT_PROJECT_PATH alongside NEAT_PROJECT.`
|
|
@@ -24311,7 +24474,7 @@ async function startDaemon(opts = {}) {
|
|
|
24311
24474
|
);
|
|
24312
24475
|
}
|
|
24313
24476
|
}
|
|
24314
|
-
const pidPath =
|
|
24477
|
+
const pidPath = import_node_path78.default.join(home, "neatd.pid");
|
|
24315
24478
|
await writeAtomically(pidPath, `${process.pid}
|
|
24316
24479
|
`);
|
|
24317
24480
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -24783,8 +24946,8 @@ async function startDaemon(opts = {}) {
|
|
|
24783
24946
|
let registryWatcher = null;
|
|
24784
24947
|
let reloadTimer = null;
|
|
24785
24948
|
if (!singleProject) try {
|
|
24786
|
-
const regDir =
|
|
24787
|
-
const regBase =
|
|
24949
|
+
const regDir = import_node_path78.default.dirname(regPath);
|
|
24950
|
+
const regBase = import_node_path78.default.basename(regPath);
|
|
24788
24951
|
registryWatcher = (0, import_node_fs41.watch)(regDir, (_eventType, filename) => {
|
|
24789
24952
|
if (filename !== null && filename !== regBase) return;
|
|
24790
24953
|
if (reloadTimer) clearTimeout(reloadTimer);
|