@neat.is/core 0.9.18 → 0.9.19
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/neatd.cjs
CHANGED
|
@@ -61,8 +61,8 @@ function mountBearerAuth(app, opts) {
|
|
|
61
61
|
]);
|
|
62
62
|
const publicRead = opts.publicRead === true;
|
|
63
63
|
app.addHook("preHandler", (req2, reply, done) => {
|
|
64
|
-
const
|
|
65
|
-
if (exactUnauthPaths.has(
|
|
64
|
+
const path81 = (req2.url.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
65
|
+
if (exactUnauthPaths.has(path81) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path81)) {
|
|
66
66
|
done();
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
@@ -415,8 +415,8 @@ function websocketChannelPathOf(attrs) {
|
|
|
415
415
|
const v = attrs[key];
|
|
416
416
|
if (typeof v === "string" && v.length > 0) {
|
|
417
417
|
const q = v.indexOf("?");
|
|
418
|
-
const
|
|
419
|
-
if (
|
|
418
|
+
const path81 = q === -1 ? v : v.slice(0, q);
|
|
419
|
+
if (path81.length > 0) return path81;
|
|
420
420
|
}
|
|
421
421
|
}
|
|
422
422
|
return void 0;
|
|
@@ -789,13 +789,13 @@ __export(neatd_exports, {
|
|
|
789
789
|
module.exports = __toCommonJS(neatd_exports);
|
|
790
790
|
init_cjs_shims();
|
|
791
791
|
var import_node_fs43 = require("fs");
|
|
792
|
-
var
|
|
792
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
793
793
|
var import_node_module2 = require("module");
|
|
794
794
|
|
|
795
795
|
// src/daemon.ts
|
|
796
796
|
init_cjs_shims();
|
|
797
797
|
var import_node_fs41 = require("fs");
|
|
798
|
-
var
|
|
798
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
799
799
|
var import_node_module = require("module");
|
|
800
800
|
|
|
801
801
|
// src/graph.ts
|
|
@@ -1337,19 +1337,19 @@ function confidenceFromMix(edges, now = Date.now()) {
|
|
|
1337
1337
|
function longestIncomingWalk(graph, start, maxDepth) {
|
|
1338
1338
|
let best = { path: [start], edges: [] };
|
|
1339
1339
|
const visited = /* @__PURE__ */ new Set([start]);
|
|
1340
|
-
function step(node,
|
|
1341
|
-
if (
|
|
1342
|
-
best = { path: [...
|
|
1340
|
+
function step(node, path81, edges) {
|
|
1341
|
+
if (path81.length > best.path.length) {
|
|
1342
|
+
best = { path: [...path81], edges: [...edges] };
|
|
1343
1343
|
}
|
|
1344
|
-
if (
|
|
1344
|
+
if (path81.length - 1 >= maxDepth) return;
|
|
1345
1345
|
const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
|
|
1346
1346
|
for (const [srcId, edge] of incoming) {
|
|
1347
1347
|
if (visited.has(srcId)) continue;
|
|
1348
1348
|
visited.add(srcId);
|
|
1349
|
-
|
|
1349
|
+
path81.push(srcId);
|
|
1350
1350
|
edges.push(edge);
|
|
1351
|
-
step(srcId,
|
|
1352
|
-
|
|
1351
|
+
step(srcId, path81, edges);
|
|
1352
|
+
path81.pop();
|
|
1353
1353
|
edges.pop();
|
|
1354
1354
|
visited.delete(srcId);
|
|
1355
1355
|
}
|
|
@@ -1564,20 +1564,20 @@ function dominantFailingCall(graph, serviceId17, visited) {
|
|
|
1564
1564
|
return best;
|
|
1565
1565
|
}
|
|
1566
1566
|
function followFailingCallChain(graph, originServiceId, maxDepth) {
|
|
1567
|
-
const
|
|
1567
|
+
const path81 = [originServiceId];
|
|
1568
1568
|
const edges = [];
|
|
1569
1569
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
1570
1570
|
let current = originServiceId;
|
|
1571
1571
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
1572
1572
|
const hop = dominantFailingCall(graph, current, visited);
|
|
1573
1573
|
if (!hop) break;
|
|
1574
|
-
|
|
1574
|
+
path81.push(hop.nextService);
|
|
1575
1575
|
edges.push(hop.edge);
|
|
1576
1576
|
visited.add(hop.nextService);
|
|
1577
1577
|
current = hop.nextService;
|
|
1578
1578
|
}
|
|
1579
1579
|
if (edges.length === 0) return null;
|
|
1580
|
-
return { path:
|
|
1580
|
+
return { path: path81, edges, culprit: current };
|
|
1581
1581
|
}
|
|
1582
1582
|
function isStaleCallEdge(e) {
|
|
1583
1583
|
return e.type === import_types.EdgeType.CALLS && e.provenance === import_types.Provenance.STALE;
|
|
@@ -1613,26 +1613,26 @@ function dominantStaleCall(graph, serviceId17, visited) {
|
|
|
1613
1613
|
return best;
|
|
1614
1614
|
}
|
|
1615
1615
|
function followStaleCallChain(graph, originServiceId, maxDepth) {
|
|
1616
|
-
const
|
|
1616
|
+
const path81 = [originServiceId];
|
|
1617
1617
|
const edges = [];
|
|
1618
1618
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
1619
1619
|
let current = originServiceId;
|
|
1620
1620
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
1621
1621
|
const hop = dominantStaleCall(graph, current, visited);
|
|
1622
1622
|
if (!hop) break;
|
|
1623
|
-
|
|
1623
|
+
path81.push(hop.nextService);
|
|
1624
1624
|
edges.push(hop.edge);
|
|
1625
1625
|
visited.add(hop.nextService);
|
|
1626
1626
|
current = hop.nextService;
|
|
1627
1627
|
}
|
|
1628
1628
|
if (edges.length === 0) return null;
|
|
1629
|
-
return { path:
|
|
1629
|
+
return { path: path81, edges, culprit: current };
|
|
1630
1630
|
}
|
|
1631
1631
|
function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
1632
1632
|
const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
|
|
1633
1633
|
if (!chain) return null;
|
|
1634
1634
|
const culprit = chain.culprit;
|
|
1635
|
-
const
|
|
1635
|
+
const path81 = [...chain.path];
|
|
1636
1636
|
const edgeProvenances = chain.edges.map((e) => e.provenance);
|
|
1637
1637
|
const baseConfidence = confidenceFromMix(chain.edges);
|
|
1638
1638
|
const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
|
|
@@ -1640,14 +1640,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
1640
1640
|
if (loc) {
|
|
1641
1641
|
let rootCauseNode = culprit;
|
|
1642
1642
|
if (loc.fileNode) {
|
|
1643
|
-
|
|
1643
|
+
path81.push(loc.fileNode);
|
|
1644
1644
|
edgeProvenances.push(import_types.Provenance.OBSERVED);
|
|
1645
1645
|
rootCauseNode = loc.fileNode;
|
|
1646
1646
|
}
|
|
1647
1647
|
return import_types.RootCauseResultSchema.parse({
|
|
1648
1648
|
rootCauseNode,
|
|
1649
1649
|
rootCauseReason: loc.rootCauseReason,
|
|
1650
|
-
traversalPath:
|
|
1650
|
+
traversalPath: path81,
|
|
1651
1651
|
edgeProvenances,
|
|
1652
1652
|
confidence,
|
|
1653
1653
|
...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
|
|
@@ -1659,7 +1659,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
1659
1659
|
return import_types.RootCauseResultSchema.parse({
|
|
1660
1660
|
rootCauseNode: culprit,
|
|
1661
1661
|
rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
|
|
1662
|
-
traversalPath:
|
|
1662
|
+
traversalPath: path81,
|
|
1663
1663
|
edgeProvenances,
|
|
1664
1664
|
confidence,
|
|
1665
1665
|
fixRecommendation: `Inspect ${culpritName}'s failing handler`
|
|
@@ -2312,10 +2312,10 @@ function enrichWithNavigation(graph, errorNodeId, tagged, incidents, now) {
|
|
|
2312
2312
|
traversalPath = staleChain.path;
|
|
2313
2313
|
edgeProvenances = staleChain.edges.map((e) => e.provenance);
|
|
2314
2314
|
} else if (top.node !== seedNode) {
|
|
2315
|
-
const
|
|
2316
|
-
if (
|
|
2317
|
-
traversalPath =
|
|
2318
|
-
edgeProvenances =
|
|
2315
|
+
const path81 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
|
|
2316
|
+
if (path81) {
|
|
2317
|
+
traversalPath = path81.nodes;
|
|
2318
|
+
edgeProvenances = path81.edges.map((e) => e.provenance);
|
|
2319
2319
|
} else {
|
|
2320
2320
|
traversalPath = [errorNodeId, top.node];
|
|
2321
2321
|
edgeProvenances = [top.provenance ?? import_types.Provenance.OBSERVED];
|
|
@@ -3754,8 +3754,8 @@ function chiRoutesFromSource(source, parser) {
|
|
|
3754
3754
|
chiWalk(tree.rootNode, "", out);
|
|
3755
3755
|
return out;
|
|
3756
3756
|
}
|
|
3757
|
-
function stripChiRegex(
|
|
3758
|
-
return
|
|
3757
|
+
function stripChiRegex(path81) {
|
|
3758
|
+
return path81.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
|
|
3759
3759
|
}
|
|
3760
3760
|
function chiWalk(node, prefix, out) {
|
|
3761
3761
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
@@ -4427,9 +4427,9 @@ function rubyRocketRoute(args) {
|
|
|
4427
4427
|
if (!pair || pair.type !== "pair") continue;
|
|
4428
4428
|
const k = pair.childForFieldName("key");
|
|
4429
4429
|
if (k?.type !== "string") continue;
|
|
4430
|
-
const
|
|
4431
|
-
if (
|
|
4432
|
-
return { path:
|
|
4430
|
+
const path81 = rubyLiteral(k);
|
|
4431
|
+
if (path81 === null) continue;
|
|
4432
|
+
return { path: path81, target: rubyLiteral(pair.childForFieldName("value")) };
|
|
4433
4433
|
}
|
|
4434
4434
|
return null;
|
|
4435
4435
|
}
|
|
@@ -10648,10 +10648,10 @@ function grpcMethodsFromProto(content, fqPackage) {
|
|
|
10648
10648
|
}
|
|
10649
10649
|
const body = content.slice(bodyStart, i - 1);
|
|
10650
10650
|
const rpcRe = /\brpc\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(/g;
|
|
10651
|
-
let
|
|
10652
|
-
while ((
|
|
10653
|
-
const rpcMethod =
|
|
10654
|
-
const line = lineAt(content, bodyStart +
|
|
10651
|
+
let rm2;
|
|
10652
|
+
while ((rm2 = rpcRe.exec(body)) !== null) {
|
|
10653
|
+
const rpcMethod = rm2[1];
|
|
10654
|
+
const line = lineAt(content, bodyStart + rm2.index);
|
|
10655
10655
|
out.push({ rpcService, rpcMethod, line });
|
|
10656
10656
|
}
|
|
10657
10657
|
serviceRe.lastIndex = i;
|
|
@@ -19475,10 +19475,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
|
|
|
19475
19475
|
// src/connectors/supabase/map.ts
|
|
19476
19476
|
var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
|
|
19477
19477
|
var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
|
|
19478
|
-
function targetFromRestPath(
|
|
19479
|
-
const rpcMatch = REST_RPC_PATH_RE.exec(
|
|
19478
|
+
function targetFromRestPath(path81) {
|
|
19479
|
+
const rpcMatch = REST_RPC_PATH_RE.exec(path81);
|
|
19480
19480
|
if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
|
|
19481
|
-
const tableMatch = REST_TABLE_PATH_RE.exec(
|
|
19481
|
+
const tableMatch = REST_TABLE_PATH_RE.exec(path81);
|
|
19482
19482
|
if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
|
|
19483
19483
|
return null;
|
|
19484
19484
|
}
|
|
@@ -20082,9 +20082,9 @@ function parseFirebaseTargetName(targetName) {
|
|
|
20082
20082
|
const secondSep = rest.indexOf(FIELD_SEP);
|
|
20083
20083
|
if (secondSep === -1) return null;
|
|
20084
20084
|
const method = rest.slice(0, secondSep);
|
|
20085
|
-
const
|
|
20086
|
-
if (!resourceName || !method || !
|
|
20087
|
-
return { resourceName, method, path:
|
|
20085
|
+
const path81 = rest.slice(secondSep + 1);
|
|
20086
|
+
if (!resourceName || !method || !path81) return null;
|
|
20087
|
+
return { resourceName, method, path: path81 };
|
|
20088
20088
|
}
|
|
20089
20089
|
function resourceNameFor(type, labels) {
|
|
20090
20090
|
if (!labels) return null;
|
|
@@ -20122,14 +20122,14 @@ function mapLogEntryToSignal(entry2) {
|
|
|
20122
20122
|
if (!req2) return null;
|
|
20123
20123
|
if (typeof req2.requestMethod !== "string" || req2.requestMethod.length === 0) return null;
|
|
20124
20124
|
const method = req2.requestMethod.toUpperCase();
|
|
20125
|
-
const
|
|
20126
|
-
if (
|
|
20125
|
+
const path81 = pathFromRequestUrl(req2.requestUrl);
|
|
20126
|
+
if (path81 === null) return null;
|
|
20127
20127
|
const timestamp = entry2.timestamp;
|
|
20128
20128
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
20129
20129
|
const isError = typeof req2.status === "number" && req2.status >= ERROR_STATUS_THRESHOLD2;
|
|
20130
20130
|
return {
|
|
20131
20131
|
targetKind: resourceType,
|
|
20132
|
-
targetName: packFirebaseTargetName({ resourceName, method, path:
|
|
20132
|
+
targetName: packFirebaseTargetName({ resourceName, method, path: path81 }),
|
|
20133
20133
|
callCount: 1,
|
|
20134
20134
|
errorCount: isError ? 1 : 0,
|
|
20135
20135
|
lastObservedIso: timestamp
|
|
@@ -20336,7 +20336,7 @@ function mapEventToSignal(event) {
|
|
|
20336
20336
|
if (Number.isNaN(observedAt.getTime())) return null;
|
|
20337
20337
|
const statusCode = metadata?.statusCode;
|
|
20338
20338
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
20339
|
-
const
|
|
20339
|
+
const path81 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
20340
20340
|
return {
|
|
20341
20341
|
targetKind: CLOUDFLARE_TARGET_KIND,
|
|
20342
20342
|
targetName: scriptName,
|
|
@@ -20344,7 +20344,7 @@ function mapEventToSignal(event) {
|
|
|
20344
20344
|
errorCount: isError ? 1 : 0,
|
|
20345
20345
|
lastObservedIso: observedAt.toISOString(),
|
|
20346
20346
|
method,
|
|
20347
|
-
...
|
|
20347
|
+
...path81 ? { path: path81 } : {},
|
|
20348
20348
|
...typeof statusCode === "number" ? { statusCode } : {},
|
|
20349
20349
|
...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
|
|
20350
20350
|
};
|
|
@@ -20390,8 +20390,8 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
20390
20390
|
});
|
|
20391
20391
|
return found;
|
|
20392
20392
|
}
|
|
20393
|
-
function findMatchingRouteNode(graph, serviceName, method,
|
|
20394
|
-
const normalizedPath = normalizePathTemplate(
|
|
20393
|
+
function findMatchingRouteNode(graph, serviceName, method, path81) {
|
|
20394
|
+
const normalizedPath = normalizePathTemplate(path81);
|
|
20395
20395
|
let found = null;
|
|
20396
20396
|
graph.forEachNode((id, attrs) => {
|
|
20397
20397
|
if (found) return;
|
|
@@ -20408,10 +20408,10 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
20408
20408
|
return (signal) => {
|
|
20409
20409
|
if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
|
|
20410
20410
|
const scriptName = signal.targetName;
|
|
20411
|
-
const { method, path:
|
|
20411
|
+
const { method, path: path81 } = signal;
|
|
20412
20412
|
const resolveRouteGrain = (serviceName, wholeFileId) => {
|
|
20413
|
-
if (!method || !
|
|
20414
|
-
return findMatchingRouteNode(graph, serviceName, method,
|
|
20413
|
+
if (!method || !path81) return wholeFileId;
|
|
20414
|
+
return findMatchingRouteNode(graph, serviceName, method, path81) ?? wholeFileId;
|
|
20415
20415
|
};
|
|
20416
20416
|
const mapping = config.workers?.[scriptName];
|
|
20417
20417
|
if (mapping) {
|
|
@@ -20763,9 +20763,9 @@ function parseCloudRunTargetName(targetName) {
|
|
|
20763
20763
|
const secondSep = rest.indexOf(FIELD_SEP2);
|
|
20764
20764
|
if (secondSep === -1) return null;
|
|
20765
20765
|
const method = rest.slice(0, secondSep);
|
|
20766
|
-
const
|
|
20767
|
-
if (!serviceName || !method || !
|
|
20768
|
-
return { serviceName, method, path:
|
|
20766
|
+
const path81 = rest.slice(secondSep + 1);
|
|
20767
|
+
if (!serviceName || !method || !path81) return null;
|
|
20768
|
+
return { serviceName, method, path: path81 };
|
|
20769
20769
|
}
|
|
20770
20770
|
|
|
20771
20771
|
// src/connectors/cloud-run/map.ts
|
|
@@ -20794,14 +20794,14 @@ function mapLogEntryToSignal2(entry2) {
|
|
|
20794
20794
|
if (!req2) return null;
|
|
20795
20795
|
if (typeof req2.requestMethod !== "string" || req2.requestMethod.length === 0) return null;
|
|
20796
20796
|
const method = req2.requestMethod.toUpperCase();
|
|
20797
|
-
const
|
|
20798
|
-
if (
|
|
20797
|
+
const path81 = pathFromRequestUrl2(req2.requestUrl);
|
|
20798
|
+
if (path81 === null) return null;
|
|
20799
20799
|
const timestamp = entry2.timestamp;
|
|
20800
20800
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
20801
20801
|
const isError = typeof req2.status === "number" && req2.status >= ERROR_STATUS_THRESHOLD4;
|
|
20802
20802
|
return {
|
|
20803
20803
|
targetKind: CLOUD_RUN_TARGET_KIND,
|
|
20804
|
-
targetName: packCloudRunTargetName({ serviceName, method, path:
|
|
20804
|
+
targetName: packCloudRunTargetName({ serviceName, method, path: path81 }),
|
|
20805
20805
|
callCount: 1,
|
|
20806
20806
|
errorCount: isError ? 1 : 0,
|
|
20807
20807
|
lastObservedIso: timestamp
|
|
@@ -20840,14 +20840,14 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
20840
20840
|
if (signal.targetKind !== CLOUD_RUN_TARGET_KIND) return null;
|
|
20841
20841
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
20842
20842
|
if (!identity) return null;
|
|
20843
|
-
const { serviceName: gcpServiceName, method, path:
|
|
20843
|
+
const { serviceName: gcpServiceName, method, path: path81 } = identity;
|
|
20844
20844
|
const mappedService = config.serviceMap?.[gcpServiceName];
|
|
20845
20845
|
if (mappedService) {
|
|
20846
20846
|
const routeNodeId = findMatchingRouteNode2(
|
|
20847
20847
|
graph,
|
|
20848
20848
|
mappedService,
|
|
20849
20849
|
method,
|
|
20850
|
-
normalizePathTemplate(
|
|
20850
|
+
normalizePathTemplate(path81)
|
|
20851
20851
|
);
|
|
20852
20852
|
if (routeNodeId) {
|
|
20853
20853
|
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types81.EdgeType.CALLS };
|
|
@@ -20983,9 +20983,9 @@ function parseGcpLbTargetName(targetName) {
|
|
|
20983
20983
|
const secondSep = rest.indexOf(FIELD_SEP3);
|
|
20984
20984
|
if (secondSep === -1) return null;
|
|
20985
20985
|
const method = rest.slice(0, secondSep);
|
|
20986
|
-
const
|
|
20987
|
-
if (!backendServiceName || !method || !
|
|
20988
|
-
return { backendServiceName, method, path:
|
|
20986
|
+
const path81 = rest.slice(secondSep + 1);
|
|
20987
|
+
if (!backendServiceName || !method || !path81) return null;
|
|
20988
|
+
return { backendServiceName, method, path: path81 };
|
|
20989
20989
|
}
|
|
20990
20990
|
|
|
20991
20991
|
// src/connectors/gcp-lb/map.ts
|
|
@@ -21014,14 +21014,14 @@ function mapLogEntryToSignal3(entry2) {
|
|
|
21014
21014
|
if (!req2) return null;
|
|
21015
21015
|
if (typeof req2.requestMethod !== "string" || req2.requestMethod.length === 0) return null;
|
|
21016
21016
|
const method = req2.requestMethod.toUpperCase();
|
|
21017
|
-
const
|
|
21018
|
-
if (
|
|
21017
|
+
const path81 = pathFromRequestUrl3(req2.requestUrl);
|
|
21018
|
+
if (path81 === null) return null;
|
|
21019
21019
|
const timestamp = entry2.timestamp;
|
|
21020
21020
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
21021
21021
|
const isError = typeof req2.status === "number" && req2.status >= ERROR_STATUS_THRESHOLD5;
|
|
21022
21022
|
return {
|
|
21023
21023
|
targetKind: GCP_LB_TARGET_KIND,
|
|
21024
|
-
targetName: packGcpLbTargetName({ backendServiceName, method, path:
|
|
21024
|
+
targetName: packGcpLbTargetName({ backendServiceName, method, path: path81 }),
|
|
21025
21025
|
callCount: 1,
|
|
21026
21026
|
errorCount: isError ? 1 : 0,
|
|
21027
21027
|
lastObservedIso: timestamp
|
|
@@ -21060,14 +21060,14 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21060
21060
|
if (signal.targetKind !== GCP_LB_TARGET_KIND) return null;
|
|
21061
21061
|
const identity = parseGcpLbTargetName(signal.targetName);
|
|
21062
21062
|
if (!identity) return null;
|
|
21063
|
-
const { backendServiceName, method, path:
|
|
21063
|
+
const { backendServiceName, method, path: path81 } = identity;
|
|
21064
21064
|
const mappedService = config.backendServiceMap?.[backendServiceName];
|
|
21065
21065
|
if (mappedService) {
|
|
21066
21066
|
const routeNodeId = findMatchingRouteNode3(
|
|
21067
21067
|
graph,
|
|
21068
21068
|
mappedService,
|
|
21069
21069
|
method,
|
|
21070
|
-
normalizePathTemplate(
|
|
21070
|
+
normalizePathTemplate(path81)
|
|
21071
21071
|
);
|
|
21072
21072
|
if (routeNodeId) {
|
|
21073
21073
|
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
|
|
@@ -23301,13 +23301,13 @@ async function reconcileFrontierSurfaces(graph, errorsPath) {
|
|
|
23301
23301
|
init_cjs_shims();
|
|
23302
23302
|
var CREDENTIAL_REFRESH_SKEW_MS = 6e4;
|
|
23303
23303
|
var CP_REQUEST_TIMEOUT_MS = 1e4;
|
|
23304
|
-
async function cpGet(
|
|
23304
|
+
async function cpGet(path81, deps) {
|
|
23305
23305
|
const f = deps.fetchImpl ?? fetch;
|
|
23306
|
-
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${
|
|
23306
|
+
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${path81}`, {
|
|
23307
23307
|
headers: { authorization: `Bearer ${deps.daemonToken}`, accept: "application/json" },
|
|
23308
23308
|
signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS)
|
|
23309
23309
|
});
|
|
23310
|
-
if (!res.ok) throw new Error(`control plane ${
|
|
23310
|
+
if (!res.ok) throw new Error(`control plane ${path81} \u2192 HTTP ${res.status}`);
|
|
23311
23311
|
return await res.json();
|
|
23312
23312
|
}
|
|
23313
23313
|
function credentialRecord(provider, cred) {
|
|
@@ -23413,6 +23413,156 @@ async function maybeStartHostedConnectors(input) {
|
|
|
23413
23413
|
});
|
|
23414
23414
|
}
|
|
23415
23415
|
|
|
23416
|
+
// src/connectors/hosted-repos.ts
|
|
23417
|
+
init_cjs_shims();
|
|
23418
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
23419
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
23420
|
+
var import_promises = require("fs/promises");
|
|
23421
|
+
var CP_REQUEST_TIMEOUT_MS2 = 1e4;
|
|
23422
|
+
var DEFAULT_SYNC_INTERVAL_MS = 5 * 6e4;
|
|
23423
|
+
var CLONE_TIMEOUT_MS = 5 * 6e4;
|
|
23424
|
+
function scrubToken(s) {
|
|
23425
|
+
return s.replace(/x-access-token:[^@\s]+@/g, "x-access-token:***@");
|
|
23426
|
+
}
|
|
23427
|
+
async function cpGet2(pathname, deps) {
|
|
23428
|
+
const f = deps.fetchImpl ?? fetch;
|
|
23429
|
+
const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${pathname}`, {
|
|
23430
|
+
headers: { authorization: `Bearer ${deps.daemonToken}`, accept: "application/json" },
|
|
23431
|
+
signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS2)
|
|
23432
|
+
});
|
|
23433
|
+
if (!res.ok) throw new Error(`control plane ${pathname} \u2192 HTTP ${res.status}`);
|
|
23434
|
+
return await res.json();
|
|
23435
|
+
}
|
|
23436
|
+
async function cpPostStatus(deps, owner, name, body) {
|
|
23437
|
+
const f = deps.fetchImpl ?? fetch;
|
|
23438
|
+
const url = `${deps.cpUrl.replace(/\/+$/, "")}/internal/projects/${deps.projectId}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/status`;
|
|
23439
|
+
const res = await f(url, {
|
|
23440
|
+
method: "POST",
|
|
23441
|
+
headers: { authorization: `Bearer ${deps.daemonToken}`, "content-type": "application/json" },
|
|
23442
|
+
body: JSON.stringify(body),
|
|
23443
|
+
signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS2)
|
|
23444
|
+
});
|
|
23445
|
+
if (!res.ok && res.status !== 404) throw new Error(`control plane status POST \u2192 HTTP ${res.status}`);
|
|
23446
|
+
}
|
|
23447
|
+
var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
23448
|
+
const [{ default: git }, httpMod, fs41] = await Promise.all([
|
|
23449
|
+
import("isomorphic-git"),
|
|
23450
|
+
import("isomorphic-git/http/node"),
|
|
23451
|
+
import("fs")
|
|
23452
|
+
]);
|
|
23453
|
+
const http = httpMod.default ?? httpMod;
|
|
23454
|
+
const parsed = new URL(cloneUrl);
|
|
23455
|
+
const password = parsed.password || parsed.username;
|
|
23456
|
+
const username = parsed.password ? parsed.username : "x-access-token";
|
|
23457
|
+
const cleanUrl = `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
|
|
23458
|
+
const clone = git.clone({
|
|
23459
|
+
fs: fs41,
|
|
23460
|
+
http,
|
|
23461
|
+
dir: destDir,
|
|
23462
|
+
url: cleanUrl,
|
|
23463
|
+
// Absent ref → isomorphic-git clones the remote's default branch.
|
|
23464
|
+
...ref ? { ref } : {},
|
|
23465
|
+
singleBranch: true,
|
|
23466
|
+
depth: 1,
|
|
23467
|
+
onAuth: () => ({ username, password })
|
|
23468
|
+
});
|
|
23469
|
+
let timer;
|
|
23470
|
+
const timeout = new Promise((_, reject) => {
|
|
23471
|
+
timer = setTimeout(() => reject(new Error(`clone timed out after ${CLONE_TIMEOUT_MS}ms`)), CLONE_TIMEOUT_MS);
|
|
23472
|
+
});
|
|
23473
|
+
try {
|
|
23474
|
+
await Promise.race([clone, timeout]);
|
|
23475
|
+
} finally {
|
|
23476
|
+
if (timer) clearTimeout(timer);
|
|
23477
|
+
}
|
|
23478
|
+
};
|
|
23479
|
+
function needsSync(r) {
|
|
23480
|
+
return r.syncStatus === void 0 || r.syncStatus === "syncing";
|
|
23481
|
+
}
|
|
23482
|
+
async function syncOneRepo(r, input) {
|
|
23483
|
+
const { deps, graph } = input;
|
|
23484
|
+
const cloneRepo = input.cloneRepo ?? defaultCloneRepo;
|
|
23485
|
+
const extract = input.extract ?? extractFromDirectory;
|
|
23486
|
+
const label = `${r.owner}/${r.name}`;
|
|
23487
|
+
const tmpRoot = input.tmpRoot ?? import_node_os5.default.tmpdir();
|
|
23488
|
+
let dir;
|
|
23489
|
+
try {
|
|
23490
|
+
dir = await (0, import_promises.mkdtemp)(import_node_path75.default.join(tmpRoot, "neat-repo-"));
|
|
23491
|
+
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
23492
|
+
await extract(graph, dir);
|
|
23493
|
+
await cpPostStatus(deps, r.owner, r.name, {
|
|
23494
|
+
syncStatus: "synced",
|
|
23495
|
+
lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
|
|
23496
|
+
});
|
|
23497
|
+
} catch (err) {
|
|
23498
|
+
input.onError?.(label, err);
|
|
23499
|
+
await cpPostStatus(deps, r.owner, r.name, {
|
|
23500
|
+
syncStatus: "failed",
|
|
23501
|
+
detail: scrubToken(err.message).slice(0, 300)
|
|
23502
|
+
}).catch(() => {
|
|
23503
|
+
});
|
|
23504
|
+
} finally {
|
|
23505
|
+
if (dir) await (0, import_promises.rm)(dir, { recursive: true, force: true }).catch(() => {
|
|
23506
|
+
});
|
|
23507
|
+
}
|
|
23508
|
+
}
|
|
23509
|
+
async function runRepoSyncPass(input) {
|
|
23510
|
+
let repos;
|
|
23511
|
+
try {
|
|
23512
|
+
repos = await cpGet2(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
23513
|
+
} catch (err) {
|
|
23514
|
+
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
23515
|
+
return;
|
|
23516
|
+
}
|
|
23517
|
+
if (!Array.isArray(repos)) return;
|
|
23518
|
+
for (const r of repos) {
|
|
23519
|
+
if (!needsSync(r)) continue;
|
|
23520
|
+
await syncOneRepo(r, input);
|
|
23521
|
+
}
|
|
23522
|
+
}
|
|
23523
|
+
async function startRepoSync(input) {
|
|
23524
|
+
const intervalMs = input.intervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
|
|
23525
|
+
let stopped = false;
|
|
23526
|
+
let running = false;
|
|
23527
|
+
const tick = async () => {
|
|
23528
|
+
if (stopped || running) return;
|
|
23529
|
+
running = true;
|
|
23530
|
+
try {
|
|
23531
|
+
await runRepoSyncPass(input);
|
|
23532
|
+
} finally {
|
|
23533
|
+
running = false;
|
|
23534
|
+
}
|
|
23535
|
+
};
|
|
23536
|
+
void tick();
|
|
23537
|
+
const timer = setInterval(() => {
|
|
23538
|
+
void tick();
|
|
23539
|
+
}, intervalMs);
|
|
23540
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
23541
|
+
return () => {
|
|
23542
|
+
stopped = true;
|
|
23543
|
+
clearInterval(timer);
|
|
23544
|
+
};
|
|
23545
|
+
}
|
|
23546
|
+
async function maybeStartRepoSync(input) {
|
|
23547
|
+
const env = input.env ?? process.env;
|
|
23548
|
+
const cpUrl = env.NEAT_CP_URL;
|
|
23549
|
+
const projectId = env.NEAT_CP_PROJECT_ID;
|
|
23550
|
+
const daemonToken = env.NEAT_AUTH_TOKEN;
|
|
23551
|
+
if (!cpUrl || !projectId || !daemonToken) return () => {
|
|
23552
|
+
};
|
|
23553
|
+
return startRepoSync({
|
|
23554
|
+
deps: { cpUrl, projectId, daemonToken, ...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {} },
|
|
23555
|
+
graph: input.graph,
|
|
23556
|
+
project: input.project,
|
|
23557
|
+
...input.cloneRepo ? { cloneRepo: input.cloneRepo } : {},
|
|
23558
|
+
...input.extract ? { extract: input.extract } : {},
|
|
23559
|
+
...input.intervalMs !== void 0 ? { intervalMs: input.intervalMs } : {},
|
|
23560
|
+
...input.tmpRoot ? { tmpRoot: input.tmpRoot } : {},
|
|
23561
|
+
...input.onSkip ? { onSkip: input.onSkip } : {},
|
|
23562
|
+
...input.onError ? { onError: input.onError } : {}
|
|
23563
|
+
});
|
|
23564
|
+
}
|
|
23565
|
+
|
|
23416
23566
|
// src/connectors/kubernetes/index.ts
|
|
23417
23567
|
init_cjs_shims();
|
|
23418
23568
|
|
|
@@ -23466,9 +23616,9 @@ function makeK8sFetchImpl(transport) {
|
|
|
23466
23616
|
req2.end();
|
|
23467
23617
|
}));
|
|
23468
23618
|
}
|
|
23469
|
-
async function listResource(transport, namespace,
|
|
23619
|
+
async function listResource(transport, namespace, path81, opts = {}) {
|
|
23470
23620
|
const base = opts.apiUrl ?? transport.server;
|
|
23471
|
-
const url = `${base.replace(/\/$/, "")}${
|
|
23621
|
+
const url = `${base.replace(/\/$/, "")}${path81}`;
|
|
23472
23622
|
const fetchImpl = opts.fetchImpl ?? makeK8sFetchImpl(transport);
|
|
23473
23623
|
const res = await junctionFetch(
|
|
23474
23624
|
url,
|
|
@@ -23478,7 +23628,7 @@ async function listResource(transport, namespace, path80, opts = {}) {
|
|
|
23478
23628
|
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, fetchImpl }
|
|
23479
23629
|
);
|
|
23480
23630
|
if (!res.ok) {
|
|
23481
|
-
throw new Error(`kubernetes ${
|
|
23631
|
+
throw new Error(`kubernetes ${path81} failed: ${res.status} ${res.statusText}`);
|
|
23482
23632
|
}
|
|
23483
23633
|
const json = await res.json();
|
|
23484
23634
|
return Array.isArray(json.items) ? json.items : [];
|
|
@@ -23780,21 +23930,21 @@ function createK8sResolveTarget(graph) {
|
|
|
23780
23930
|
|
|
23781
23931
|
// src/connectors/kubernetes/substrate.ts
|
|
23782
23932
|
init_cjs_shims();
|
|
23783
|
-
var
|
|
23784
|
-
var
|
|
23785
|
-
var
|
|
23933
|
+
var import_promises2 = require("fs/promises");
|
|
23934
|
+
var import_node_os6 = __toESM(require("os"), 1);
|
|
23935
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
23786
23936
|
function defaultHome() {
|
|
23787
23937
|
const override = process.env.NEAT_HOME;
|
|
23788
|
-
if (override && override.length > 0) return
|
|
23789
|
-
return
|
|
23938
|
+
if (override && override.length > 0) return import_node_path76.default.resolve(override);
|
|
23939
|
+
return import_node_path76.default.join(import_node_os6.default.homedir(), ".neat");
|
|
23790
23940
|
}
|
|
23791
23941
|
function k8sSubstrateConfigPath(home = defaultHome()) {
|
|
23792
|
-
return
|
|
23942
|
+
return import_node_path76.default.join(home, "k8s.json");
|
|
23793
23943
|
}
|
|
23794
23944
|
async function readK8sSubstrateConfig(home = defaultHome()) {
|
|
23795
23945
|
let raw;
|
|
23796
23946
|
try {
|
|
23797
|
-
raw = await (0,
|
|
23947
|
+
raw = await (0, import_promises2.readFile)(k8sSubstrateConfigPath(home), "utf8");
|
|
23798
23948
|
} catch {
|
|
23799
23949
|
return { version: 1, deployments: [] };
|
|
23800
23950
|
}
|
|
@@ -23889,7 +24039,7 @@ init_auth();
|
|
|
23889
24039
|
// src/unrouted.ts
|
|
23890
24040
|
init_cjs_shims();
|
|
23891
24041
|
var import_node_fs40 = require("fs");
|
|
23892
|
-
var
|
|
24042
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
23893
24043
|
function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new Date()) {
|
|
23894
24044
|
return {
|
|
23895
24045
|
timestamp: now.toISOString(),
|
|
@@ -23899,34 +24049,34 @@ function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new
|
|
|
23899
24049
|
};
|
|
23900
24050
|
}
|
|
23901
24051
|
async function appendUnroutedSpan(neatHome4, record) {
|
|
23902
|
-
const target =
|
|
24052
|
+
const target = import_node_path77.default.join(neatHome4, "errors.ndjson");
|
|
23903
24053
|
await import_node_fs40.promises.mkdir(neatHome4, { recursive: true });
|
|
23904
24054
|
await import_node_fs40.promises.appendFile(target, JSON.stringify(record) + "\n", "utf8");
|
|
23905
24055
|
}
|
|
23906
24056
|
function unroutedErrorsPath(neatHome4) {
|
|
23907
|
-
return
|
|
24057
|
+
return import_node_path77.default.join(neatHome4, "errors.ndjson");
|
|
23908
24058
|
}
|
|
23909
24059
|
|
|
23910
24060
|
// src/daemon.ts
|
|
23911
24061
|
var import_types106 = require("@neat.is/types");
|
|
23912
24062
|
function daemonJsonPath(scanPath) {
|
|
23913
|
-
return
|
|
24063
|
+
return import_node_path78.default.join(scanPath, "neat-out", "daemon.json");
|
|
23914
24064
|
}
|
|
23915
24065
|
function daemonsDiscoveryDir(home) {
|
|
23916
24066
|
const base = home && home.length > 0 ? home : neatHomeFromEnv();
|
|
23917
|
-
return
|
|
24067
|
+
return import_node_path78.default.join(base, "daemons");
|
|
23918
24068
|
}
|
|
23919
24069
|
function daemonDiscoveryPath(project, home) {
|
|
23920
|
-
return
|
|
24070
|
+
return import_node_path78.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
|
|
23921
24071
|
}
|
|
23922
24072
|
function sanitizeDiscoveryName(project) {
|
|
23923
24073
|
return project.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
23924
24074
|
}
|
|
23925
24075
|
function neatHomeFromEnv() {
|
|
23926
24076
|
const env = process.env.NEAT_HOME;
|
|
23927
|
-
if (env && env.length > 0) return
|
|
24077
|
+
if (env && env.length > 0) return import_node_path78.default.resolve(env);
|
|
23928
24078
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
23929
|
-
return
|
|
24079
|
+
return import_node_path78.default.join(home, ".neat");
|
|
23930
24080
|
}
|
|
23931
24081
|
function resolveNeatVersion() {
|
|
23932
24082
|
if (process.env.NEAT_LOCAL_VERSION && process.env.NEAT_LOCAL_VERSION.length > 0) {
|
|
@@ -23997,17 +24147,21 @@ function teardownSlot(slot) {
|
|
|
23997
24147
|
slot.stopK8sSubstrate();
|
|
23998
24148
|
} catch {
|
|
23999
24149
|
}
|
|
24150
|
+
try {
|
|
24151
|
+
slot.stopRepoSync();
|
|
24152
|
+
} catch {
|
|
24153
|
+
}
|
|
24000
24154
|
try {
|
|
24001
24155
|
slot.detachEvents();
|
|
24002
24156
|
} catch {
|
|
24003
24157
|
}
|
|
24004
24158
|
}
|
|
24005
24159
|
function neatHomeFor(opts) {
|
|
24006
|
-
if (opts.neatHome && opts.neatHome.length > 0) return
|
|
24160
|
+
if (opts.neatHome && opts.neatHome.length > 0) return import_node_path78.default.resolve(opts.neatHome);
|
|
24007
24161
|
const env = process.env.NEAT_HOME;
|
|
24008
|
-
if (env && env.length > 0) return
|
|
24162
|
+
if (env && env.length > 0) return import_node_path78.default.resolve(env);
|
|
24009
24163
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24010
|
-
return
|
|
24164
|
+
return import_node_path78.default.join(home, ".neat");
|
|
24011
24165
|
}
|
|
24012
24166
|
function routeSpanToProject(serviceName, projects) {
|
|
24013
24167
|
if (!serviceName) return DEFAULT_PROJECT;
|
|
@@ -24059,7 +24213,7 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
24059
24213
|
);
|
|
24060
24214
|
}
|
|
24061
24215
|
async function bootstrapProject(entry2, connectors = [], neatHome4) {
|
|
24062
|
-
const paths = pathsForProject(entry2.name,
|
|
24216
|
+
const paths = pathsForProject(entry2.name, import_node_path78.default.join(entry2.path, "neat-out"));
|
|
24063
24217
|
try {
|
|
24064
24218
|
const stat = await import_node_fs41.promises.stat(entry2.path);
|
|
24065
24219
|
if (!stat.isDirectory()) {
|
|
@@ -24085,6 +24239,8 @@ async function bootstrapProject(entry2, connectors = [], neatHome4) {
|
|
|
24085
24239
|
},
|
|
24086
24240
|
stopK8sSubstrate: () => {
|
|
24087
24241
|
},
|
|
24242
|
+
stopRepoSync: () => {
|
|
24243
|
+
},
|
|
24088
24244
|
detachEvents: () => {
|
|
24089
24245
|
},
|
|
24090
24246
|
status: "broken",
|
|
@@ -24136,6 +24292,12 @@ async function bootstrapProject(entry2, connectors = [], neatHome4) {
|
|
|
24136
24292
|
...neatHome4 ? { home: neatHome4 } : {},
|
|
24137
24293
|
onSkip: (skipped, reason) => console.warn(`neatd: k8s substrate "${skipped.id}" skipped for project "${entry2.name}" \u2014 ${reason}`)
|
|
24138
24294
|
});
|
|
24295
|
+
const stopRepoSync = await maybeStartRepoSync({
|
|
24296
|
+
project: entry2.name,
|
|
24297
|
+
graph,
|
|
24298
|
+
onSkip: (repo, reason) => console.warn(`neatd: repo-sync "${repo}" skipped for project "${entry2.name}" \u2014 ${reason}`),
|
|
24299
|
+
onError: (repo, err) => console.warn(`neatd: repo-sync "${repo}" failed for project "${entry2.name}" \u2014 ${err.message}`)
|
|
24300
|
+
});
|
|
24139
24301
|
await touchLastSeen(entry2.name).catch(() => {
|
|
24140
24302
|
});
|
|
24141
24303
|
return {
|
|
@@ -24148,6 +24310,7 @@ async function bootstrapProject(entry2, connectors = [], neatHome4) {
|
|
|
24148
24310
|
stopConnectors,
|
|
24149
24311
|
stopHostedConnectors,
|
|
24150
24312
|
stopK8sSubstrate,
|
|
24313
|
+
stopRepoSync,
|
|
24151
24314
|
detachEvents,
|
|
24152
24315
|
status: "active"
|
|
24153
24316
|
};
|
|
@@ -24204,7 +24367,7 @@ async function startDaemon(opts = {}) {
|
|
|
24204
24367
|
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;
|
|
24205
24368
|
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;
|
|
24206
24369
|
const singleProject = projectArg;
|
|
24207
|
-
const singleProjectPath = singleProject && projectPathArg ?
|
|
24370
|
+
const singleProjectPath = singleProject && projectPathArg ? import_node_path78.default.resolve(projectPathArg) : null;
|
|
24208
24371
|
if (singleProject && !singleProjectPath) {
|
|
24209
24372
|
throw new Error(
|
|
24210
24373
|
`neatd: project "${singleProject}" given without a projectPath; pass NEAT_PROJECT_PATH alongside NEAT_PROJECT.`
|
|
@@ -24219,7 +24382,7 @@ async function startDaemon(opts = {}) {
|
|
|
24219
24382
|
);
|
|
24220
24383
|
}
|
|
24221
24384
|
}
|
|
24222
|
-
const pidPath =
|
|
24385
|
+
const pidPath = import_node_path78.default.join(home, "neatd.pid");
|
|
24223
24386
|
await writeAtomically(pidPath, `${process.pid}
|
|
24224
24387
|
`);
|
|
24225
24388
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -24691,8 +24854,8 @@ async function startDaemon(opts = {}) {
|
|
|
24691
24854
|
let registryWatcher = null;
|
|
24692
24855
|
let reloadTimer = null;
|
|
24693
24856
|
if (!singleProject) try {
|
|
24694
|
-
const regDir =
|
|
24695
|
-
const regBase =
|
|
24857
|
+
const regDir = import_node_path78.default.dirname(regPath);
|
|
24858
|
+
const regBase = import_node_path78.default.basename(regPath);
|
|
24696
24859
|
registryWatcher = (0, import_node_fs41.watch)(regDir, (_eventType, filename) => {
|
|
24697
24860
|
if (filename !== null && filename !== regBase) return;
|
|
24698
24861
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
@@ -24767,7 +24930,7 @@ init_cjs_shims();
|
|
|
24767
24930
|
var import_node_child_process2 = require("child_process");
|
|
24768
24931
|
var import_node_fs42 = require("fs");
|
|
24769
24932
|
var import_node_net = __toESM(require("net"), 1);
|
|
24770
|
-
var
|
|
24933
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
24771
24934
|
var DEFAULT_WEB_PORT = 6328;
|
|
24772
24935
|
var DEFAULT_REST_PORT = 8080;
|
|
24773
24936
|
function asValidPort(value) {
|
|
@@ -24776,11 +24939,11 @@ function asValidPort(value) {
|
|
|
24776
24939
|
}
|
|
24777
24940
|
function projectRoot() {
|
|
24778
24941
|
const fromEnv = process.env.NEAT_SCAN_PATH;
|
|
24779
|
-
return
|
|
24942
|
+
return import_node_path79.default.resolve(fromEnv && fromEnv.length > 0 ? fromEnv : process.cwd());
|
|
24780
24943
|
}
|
|
24781
24944
|
async function readDaemonPorts(root) {
|
|
24782
24945
|
try {
|
|
24783
|
-
const raw = await import_node_fs42.promises.readFile(
|
|
24946
|
+
const raw = await import_node_fs42.promises.readFile(import_node_path79.default.join(root, "neat-out", "daemon.json"), "utf8");
|
|
24784
24947
|
const parsed = JSON.parse(raw);
|
|
24785
24948
|
const ports = parsed?.ports ?? {};
|
|
24786
24949
|
return { web: asValidPort(ports.web), rest: asValidPort(ports.rest) };
|
|
@@ -24825,10 +24988,10 @@ function resolveWebPackageDir() {
|
|
|
24825
24988
|
eval("require")
|
|
24826
24989
|
);
|
|
24827
24990
|
const pkgJsonPath = req.resolve("@neat.is/web/package.json");
|
|
24828
|
-
return
|
|
24991
|
+
return import_node_path79.default.dirname(pkgJsonPath);
|
|
24829
24992
|
}
|
|
24830
24993
|
function resolveStandaloneServerEntry(webDir) {
|
|
24831
|
-
return
|
|
24994
|
+
return import_node_path79.default.join(webDir, ".next/standalone/packages/web/server.js");
|
|
24832
24995
|
}
|
|
24833
24996
|
async function pickInternalPort() {
|
|
24834
24997
|
return new Promise((resolve, reject) => {
|
|
@@ -24881,7 +25044,7 @@ async function spawnWebUI(restPort, opts = {}) {
|
|
|
24881
25044
|
NEAT_API_URL: apiUrl
|
|
24882
25045
|
};
|
|
24883
25046
|
child = (0, import_node_child_process2.spawn)(process.execPath, [serverEntry], {
|
|
24884
|
-
cwd:
|
|
25047
|
+
cwd: import_node_path79.default.dirname(serverEntry),
|
|
24885
25048
|
env,
|
|
24886
25049
|
stdio: ["ignore", "inherit", "inherit"],
|
|
24887
25050
|
detached: false
|
|
@@ -24980,13 +25143,13 @@ async function waitForListening(port, timeoutMs = 15e3) {
|
|
|
24980
25143
|
|
|
24981
25144
|
// src/version-skew.ts
|
|
24982
25145
|
init_cjs_shims();
|
|
24983
|
-
var
|
|
25146
|
+
var import_promises3 = require("timers/promises");
|
|
24984
25147
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org/neat.is/latest";
|
|
24985
25148
|
var DEFAULT_TIMEOUT_MS = 2e3;
|
|
24986
25149
|
async function fetchRegistryVersion(url, timeoutMs, fetchImpl) {
|
|
24987
25150
|
const controller = new AbortController();
|
|
24988
25151
|
let timedOut = false;
|
|
24989
|
-
const timer = (0,
|
|
25152
|
+
const timer = (0, import_promises3.setTimeout)(timeoutMs).then(() => {
|
|
24990
25153
|
timedOut = true;
|
|
24991
25154
|
controller.abort();
|
|
24992
25155
|
});
|
|
@@ -25057,14 +25220,14 @@ function localVersion() {
|
|
|
25057
25220
|
}
|
|
25058
25221
|
function neatHome3() {
|
|
25059
25222
|
if (process.env.NEAT_HOME && process.env.NEAT_HOME.length > 0) {
|
|
25060
|
-
return
|
|
25223
|
+
return import_node_path80.default.resolve(process.env.NEAT_HOME);
|
|
25061
25224
|
}
|
|
25062
25225
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
25063
|
-
return
|
|
25226
|
+
return import_node_path80.default.join(home, ".neat");
|
|
25064
25227
|
}
|
|
25065
25228
|
async function readPid() {
|
|
25066
25229
|
try {
|
|
25067
|
-
const raw = await import_node_fs43.promises.readFile(
|
|
25230
|
+
const raw = await import_node_fs43.promises.readFile(import_node_path80.default.join(neatHome3(), "neatd.pid"), "utf8");
|
|
25068
25231
|
const n = Number.parseInt(raw.trim(), 10);
|
|
25069
25232
|
return Number.isFinite(n) ? n : null;
|
|
25070
25233
|
} catch {
|