@neat.is/core 0.10.3 → 0.10.5-dev.20261001
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-M7CGATVC.js → chunk-EFBWQIKG.js} +12 -2
- package/dist/chunk-EFBWQIKG.js.map +1 -0
- package/dist/{chunk-LNIVRE4L.js → chunk-HHAPD6JD.js} +82 -7
- package/dist/chunk-HHAPD6JD.js.map +1 -0
- package/dist/{chunk-5SJHA5ZH.js → chunk-LXQCL4MP.js} +2 -2
- package/dist/{chunk-DLQNMU3R.js → chunk-TONL5O2E.js} +61 -24
- package/dist/chunk-TONL5O2E.js.map +1 -0
- package/dist/cli.cjs +212 -29
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +127 -27
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +147 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +4 -4
- package/dist/neatd.cjs +147 -27
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +3 -3
- package/dist/{otel-grpc-CU73Y5WT.js → otel-grpc-B7ABHLV7.js} +3 -3
- package/dist/server.cjs +93 -7
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +7 -4
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-DLQNMU3R.js.map +0 -1
- package/dist/chunk-LNIVRE4L.js.map +0 -1
- package/dist/chunk-M7CGATVC.js.map +0 -1
- /package/dist/{chunk-5SJHA5ZH.js.map → chunk-LXQCL4MP.js.map} +0 -0
- /package/dist/{otel-grpc-CU73Y5WT.js.map → otel-grpc-B7ABHLV7.js.map} +0 -0
package/dist/neatd.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
reconcileDaemonRecordSync,
|
|
4
4
|
startDaemon
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-TONL5O2E.js";
|
|
6
6
|
import {
|
|
7
7
|
listProjects,
|
|
8
8
|
registryPath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HHAPD6JD.js";
|
|
10
10
|
import {
|
|
11
11
|
BindAuthorityError,
|
|
12
12
|
__require
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-EFBWQIKG.js";
|
|
14
14
|
|
|
15
15
|
// src/neatd.ts
|
|
16
16
|
import { promises as fs } from "fs";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
reshapeGrpcRequest,
|
|
3
3
|
startOtelGrpcReceiver
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-LXQCL4MP.js";
|
|
5
|
+
import "./chunk-EFBWQIKG.js";
|
|
6
6
|
export {
|
|
7
7
|
reshapeGrpcRequest,
|
|
8
8
|
startOtelGrpcReceiver
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=otel-grpc-
|
|
10
|
+
//# sourceMappingURL=otel-grpc-B7ABHLV7.js.map
|
package/dist/server.cjs
CHANGED
|
@@ -49,6 +49,10 @@ function assertBindAuthority(host, token) {
|
|
|
49
49
|
if (isLoopbackHost2(host)) return;
|
|
50
50
|
throw new BindAuthorityError(host);
|
|
51
51
|
}
|
|
52
|
+
function isBearerDelegated(req) {
|
|
53
|
+
const config = req.routeOptions?.config;
|
|
54
|
+
return config?.bearerDelegated === true;
|
|
55
|
+
}
|
|
52
56
|
function mountBearerAuth(app, opts) {
|
|
53
57
|
if (!opts.token || opts.token.length === 0) return;
|
|
54
58
|
if (opts.trustProxy) return;
|
|
@@ -64,6 +68,10 @@ function mountBearerAuth(app, opts) {
|
|
|
64
68
|
done();
|
|
65
69
|
return;
|
|
66
70
|
}
|
|
71
|
+
if (isBearerDelegated(req)) {
|
|
72
|
+
done();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
67
75
|
if (publicRead && PUBLIC_READ_METHODS.has(req.method)) {
|
|
68
76
|
done();
|
|
69
77
|
return;
|
|
@@ -97,7 +105,7 @@ function readAuthEnv(env = process.env) {
|
|
|
97
105
|
publicRead: parseBoolEnv(env.NEAT_PUBLIC_READ)
|
|
98
106
|
};
|
|
99
107
|
}
|
|
100
|
-
var import_node_crypto, LOOPBACK_HOSTS, BindAuthorityError, PUBLIC_READ_METHODS, DEFAULT_UNAUTH_PATHS, PROJECT_SCOPED_UNAUTH_PATTERN;
|
|
108
|
+
var import_node_crypto, LOOPBACK_HOSTS, BindAuthorityError, PUBLIC_READ_METHODS, DEFAULT_UNAUTH_PATHS, PROJECT_SCOPED_UNAUTH_PATTERN, BEARER_DELEGATED;
|
|
101
109
|
var init_auth = __esm({
|
|
102
110
|
"src/auth.ts"() {
|
|
103
111
|
"use strict";
|
|
@@ -127,6 +135,7 @@ var init_auth = __esm({
|
|
|
127
135
|
PROJECT_SCOPED_UNAUTH_PATTERN = new RegExp(
|
|
128
136
|
`^/projects/[^/]+/(?:${DEFAULT_UNAUTH_PATHS.map((p) => p.slice(1)).join("|")})$`
|
|
129
137
|
);
|
|
138
|
+
BEARER_DELEGATED = { bearerDelegated: true };
|
|
130
139
|
}
|
|
131
140
|
});
|
|
132
141
|
|
|
@@ -2531,6 +2540,10 @@ function languageForPath(relPath) {
|
|
|
2531
2540
|
return void 0;
|
|
2532
2541
|
}
|
|
2533
2542
|
}
|
|
2543
|
+
var currentSource;
|
|
2544
|
+
function setExtractionSource(source) {
|
|
2545
|
+
currentSource = source;
|
|
2546
|
+
}
|
|
2534
2547
|
function ensureFileNode(graph, serviceName, serviceNodeId, relPath) {
|
|
2535
2548
|
let nodesAdded = 0;
|
|
2536
2549
|
let edgesAdded = 0;
|
|
@@ -2543,10 +2556,16 @@ function ensureFileNode(graph, serviceName, serviceNodeId, relPath) {
|
|
|
2543
2556
|
service: serviceName,
|
|
2544
2557
|
path: relPath,
|
|
2545
2558
|
...language ? { language } : {},
|
|
2559
|
+
...currentSource ? { source: currentSource } : {},
|
|
2546
2560
|
discoveredVia: "static"
|
|
2547
2561
|
};
|
|
2548
2562
|
graph.addNode(fileNodeId, node);
|
|
2549
2563
|
nodesAdded++;
|
|
2564
|
+
} else if (currentSource) {
|
|
2565
|
+
const existing = graph.getNodeAttributes(fileNodeId);
|
|
2566
|
+
if (existing.source !== currentSource) {
|
|
2567
|
+
graph.replaceNodeAttributes(fileNodeId, { ...existing, source: currentSource });
|
|
2568
|
+
}
|
|
2550
2569
|
}
|
|
2551
2570
|
const containsId = (0, import_types4.extractedEdgeId)(serviceNodeId, fileNodeId, import_types4.EdgeType.CONTAINS);
|
|
2552
2571
|
if (!graph.hasEdge(containsId)) {
|
|
@@ -17379,10 +17398,12 @@ init_cjs_shims();
|
|
|
17379
17398
|
var import_node_fs35 = require("fs");
|
|
17380
17399
|
var import_node_path70 = __toESM(require("path"), 1);
|
|
17381
17400
|
var import_types59 = require("@neat.is/types");
|
|
17382
|
-
function dropOrphanedFileNodes(graph) {
|
|
17401
|
+
function dropOrphanedFileNodes(graph, source) {
|
|
17383
17402
|
const orphans = [];
|
|
17384
17403
|
graph.forEachNode((id, attrs) => {
|
|
17385
|
-
|
|
17404
|
+
const node = attrs;
|
|
17405
|
+
if (node.type !== import_types59.NodeType.FileNode) return;
|
|
17406
|
+
if (source && node.source !== source) return;
|
|
17386
17407
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
17387
17408
|
orphans.push(id);
|
|
17388
17409
|
}
|
|
@@ -17390,12 +17411,23 @@ function dropOrphanedFileNodes(graph) {
|
|
|
17390
17411
|
for (const id of orphans) graph.dropNode(id);
|
|
17391
17412
|
return orphans.length;
|
|
17392
17413
|
}
|
|
17393
|
-
function
|
|
17414
|
+
function outOfScope(graph, edge, source) {
|
|
17415
|
+
if (!source) return false;
|
|
17416
|
+
for (const endpoint2 of [edge.source, edge.target]) {
|
|
17417
|
+
if (!graph.hasNode(endpoint2)) continue;
|
|
17418
|
+
const node = graph.getNodeAttributes(endpoint2);
|
|
17419
|
+
if (node.type !== import_types59.NodeType.FileNode) continue;
|
|
17420
|
+
return node.source !== source;
|
|
17421
|
+
}
|
|
17422
|
+
return false;
|
|
17423
|
+
}
|
|
17424
|
+
function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], source) {
|
|
17394
17425
|
const toDrop = [];
|
|
17395
17426
|
const bases = [scanPath, ...serviceDirs];
|
|
17396
17427
|
graph.forEachEdge((id, attrs) => {
|
|
17397
17428
|
const edge = attrs;
|
|
17398
17429
|
if (edge.provenance !== import_types59.Provenance.EXTRACTED) return;
|
|
17430
|
+
if (outOfScope(graph, edge, source)) return;
|
|
17399
17431
|
const evidenceFile = edge.evidence?.file;
|
|
17400
17432
|
if (!evidenceFile) return;
|
|
17401
17433
|
if (import_node_path70.default.isAbsolute(evidenceFile)) {
|
|
@@ -17406,7 +17438,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
|
|
|
17406
17438
|
if (!found) toDrop.push(id);
|
|
17407
17439
|
});
|
|
17408
17440
|
for (const id of toDrop) graph.dropEdge(id);
|
|
17409
|
-
dropOrphanedFileNodes(graph);
|
|
17441
|
+
dropOrphanedFileNodes(graph, source);
|
|
17410
17442
|
return toDrop.length;
|
|
17411
17443
|
}
|
|
17412
17444
|
|
|
@@ -17415,6 +17447,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
17415
17447
|
await ensureCompatLoaded();
|
|
17416
17448
|
drainExtractionErrors();
|
|
17417
17449
|
drainSkippedFiles();
|
|
17450
|
+
setExtractionSource(opts.source);
|
|
17418
17451
|
const services = await discoverServices(scanPath);
|
|
17419
17452
|
const phase1Nodes = addServiceNodes(graph, services);
|
|
17420
17453
|
await addServiceAliases(graph, scanPath, services);
|
|
@@ -17435,7 +17468,8 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
17435
17468
|
const ghostsRetired = retireExtractedEdgesByMissingFile(
|
|
17436
17469
|
graph,
|
|
17437
17470
|
scanPath,
|
|
17438
|
-
services.map((s) => s.dir)
|
|
17471
|
+
services.map((s) => s.dir),
|
|
17472
|
+
opts.source
|
|
17439
17473
|
);
|
|
17440
17474
|
const frontiersPromoted = promoteFrontierNodes(graph);
|
|
17441
17475
|
if (opts.onPolicyTrigger) await opts.onPolicyTrigger(graph);
|
|
@@ -17470,6 +17504,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
17470
17504
|
);
|
|
17471
17505
|
}
|
|
17472
17506
|
}
|
|
17507
|
+
setExtractionSource(void 0);
|
|
17473
17508
|
const result = {
|
|
17474
17509
|
nodesAdded: phase1Nodes + fileEnum.nodesAdded + symbolEnum.nodesAdded + importGraph.nodesAdded + symbolEdges.nodesAdded + actionPhase.nodesAdded + phase2.nodesAdded + phase3.nodesAdded + routePhase.nodesAdded + grpcPhase.nodesAdded + phase4.nodesAdded + tableEdges.nodesAdded + phase5.nodesAdded + zodPhase.nodesAdded + firestoreRulesPhase.nodesAdded,
|
|
17475
17510
|
edgesAdded: fileEnum.edgesAdded + symbolEnum.edgesAdded + importGraph.edgesAdded + symbolEdges.edgesAdded + actionPhase.edgesAdded + phase2.edgesAdded + phase3.edgesAdded + routePhase.edgesAdded + grpcPhase.edgesAdded + phase4.edgesAdded + tableEdges.edgesAdded + phase5.edgesAdded + zodPhase.edgesAdded + firestoreRulesPhase.edgesAdded,
|
|
@@ -23093,6 +23128,19 @@ function registerRoutes(scope, ctx) {
|
|
|
23093
23128
|
});
|
|
23094
23129
|
}
|
|
23095
23130
|
});
|
|
23131
|
+
scope.post("/repo-sync", async (req, reply) => {
|
|
23132
|
+
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
23133
|
+
if (!proj) return;
|
|
23134
|
+
const syncNow = ctx.repoSync?.(proj.name);
|
|
23135
|
+
if (!syncNow) {
|
|
23136
|
+
return reply.code(404).send({
|
|
23137
|
+
error: "repo-sync is not running for this project",
|
|
23138
|
+
project: proj.name,
|
|
23139
|
+
hint: "Only a hosted daemon syncs bound repos. On a local daemon, POST /graph/scan re-extracts the project path."
|
|
23140
|
+
});
|
|
23141
|
+
}
|
|
23142
|
+
return reply.code(202).send({ project: proj.name, ...syncNow() });
|
|
23143
|
+
});
|
|
23096
23144
|
scope.post("/graph/scan", async (req, reply) => {
|
|
23097
23145
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
23098
23146
|
if (!proj) return;
|
|
@@ -23340,6 +23388,39 @@ function registerRoutes(scope, ctx) {
|
|
|
23340
23388
|
}
|
|
23341
23389
|
});
|
|
23342
23390
|
}
|
|
23391
|
+
var OTLP_BODY_LIMIT = 16 * 1024 * 1024;
|
|
23392
|
+
function otlpOnRest(getReceiver) {
|
|
23393
|
+
return async function plugin(scope) {
|
|
23394
|
+
scope.removeAllContentTypeParsers();
|
|
23395
|
+
scope.addContentTypeParser(
|
|
23396
|
+
"*",
|
|
23397
|
+
{ parseAs: "buffer", bodyLimit: OTLP_BODY_LIMIT },
|
|
23398
|
+
(_req, body, done) => done(null, body)
|
|
23399
|
+
);
|
|
23400
|
+
const relay = async (req, reply) => {
|
|
23401
|
+
const receiver = getReceiver();
|
|
23402
|
+
if (!receiver) {
|
|
23403
|
+
return reply.code(503).header("retry-after", "1").send({ error: "OTLP receiver is starting" });
|
|
23404
|
+
}
|
|
23405
|
+
const headers = { ...req.headers };
|
|
23406
|
+
delete headers["content-length"];
|
|
23407
|
+
delete headers["transfer-encoding"];
|
|
23408
|
+
delete headers.connection;
|
|
23409
|
+
const res = await receiver.inject({
|
|
23410
|
+
method: "POST",
|
|
23411
|
+
url: req.url,
|
|
23412
|
+
headers,
|
|
23413
|
+
payload: req.body
|
|
23414
|
+
});
|
|
23415
|
+
const contentType = res.headers["content-type"];
|
|
23416
|
+
if (contentType !== void 0) void reply.header("content-type", contentType);
|
|
23417
|
+
return reply.code(res.statusCode).send(res.rawPayload);
|
|
23418
|
+
};
|
|
23419
|
+
const route = { config: BEARER_DELEGATED, bodyLimit: OTLP_BODY_LIMIT };
|
|
23420
|
+
scope.post("/v1/traces", route, relay);
|
|
23421
|
+
scope.post("/projects/:project/v1/traces", route, relay);
|
|
23422
|
+
};
|
|
23423
|
+
}
|
|
23343
23424
|
async function buildApi(opts) {
|
|
23344
23425
|
const app = (0, import_fastify2.default)({ logger: false, routerOptions: { maxParamLength: 1024 } });
|
|
23345
23426
|
await app.register(import_cors.default, { origin: true });
|
|
@@ -23358,6 +23439,7 @@ async function buildApi(opts) {
|
|
|
23358
23439
|
authProxy: trustProxy === true,
|
|
23359
23440
|
requiresAuth
|
|
23360
23441
|
}));
|
|
23442
|
+
if (opts.otlpReceiver) await app.register(otlpOnRest(opts.otlpReceiver));
|
|
23361
23443
|
const startedAt = opts.startedAt ?? Date.now();
|
|
23362
23444
|
const registry = buildLegacyRegistry(opts);
|
|
23363
23445
|
const legacyErrorsExplicit = !opts.projects && opts.errorsPath !== void 0;
|
|
@@ -23388,6 +23470,7 @@ async function buildApi(opts) {
|
|
|
23388
23470
|
bootstrap: opts.bootstrap,
|
|
23389
23471
|
singleProject: opts.singleProject?.name,
|
|
23390
23472
|
connectorsHome: opts.connectorsHome,
|
|
23473
|
+
repoSync: opts.repoSync,
|
|
23391
23474
|
runPoll: opts.runPoll ?? runConnectorPoll
|
|
23392
23475
|
};
|
|
23393
23476
|
app.get("/health", async () => {
|
|
@@ -23885,11 +23968,13 @@ async function main() {
|
|
|
23885
23968
|
const otelPort = Number(process.env.OTEL_PORT ?? 4318);
|
|
23886
23969
|
const auth = readAuthEnv();
|
|
23887
23970
|
assertBindAuthority(host, auth.authToken);
|
|
23971
|
+
let otelReceiver;
|
|
23888
23972
|
const app = await buildApi({
|
|
23889
23973
|
projects: registry,
|
|
23890
23974
|
authToken: auth.authToken,
|
|
23891
23975
|
trustProxy: auth.trustProxy,
|
|
23892
|
-
publicRead: auth.publicRead
|
|
23976
|
+
publicRead: auth.publicRead,
|
|
23977
|
+
otlpReceiver: () => otelReceiver
|
|
23893
23978
|
});
|
|
23894
23979
|
await app.listen({ port, host });
|
|
23895
23980
|
console.log(`neat-core listening on http://${host}:${port}`);
|
|
@@ -23906,6 +23991,7 @@ async function main() {
|
|
|
23906
23991
|
authToken: auth.otelToken,
|
|
23907
23992
|
trustProxy: auth.trustProxy
|
|
23908
23993
|
});
|
|
23994
|
+
otelReceiver = otelApp;
|
|
23909
23995
|
await otelApp.listen({ port: otelPort, host });
|
|
23910
23996
|
console.log(`neat-core OTLP receiver on http://${host}:${otelPort}/v1/traces`);
|
|
23911
23997
|
if (process.env.NEAT_OTLP_GRPC === "true") {
|