@neat.is/core 0.7.8 → 0.7.9
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-BIY46Q6U.js → chunk-BC53SCT7.js} +36 -2
- package/dist/chunk-BC53SCT7.js.map +1 -0
- package/dist/{chunk-4GCV46AP.js → chunk-FCO5Z3RW.js} +2 -2
- package/dist/{chunk-OVRVDSUO.js → chunk-ILG3SMD5.js} +54 -4
- package/dist/{chunk-OVRVDSUO.js.map → chunk-ILG3SMD5.js.map} +1 -1
- package/dist/{chunk-LN75Z624.js → chunk-N5TPODCX.js} +69 -48
- package/dist/chunk-N5TPODCX.js.map +1 -0
- package/dist/{chunk-Y43UCVZS.js → chunk-UUYCTH2E.js} +24 -8
- package/dist/chunk-UUYCTH2E.js.map +1 -0
- package/dist/cli.cjs +136 -62
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +17 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +140 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -4
- package/dist/neatd.cjs +140 -53
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +3 -3
- package/dist/{otel-grpc-DPSAGRUU.js → otel-grpc-CO47JRIN.js} +3 -3
- package/dist/server.cjs +124 -53
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +4 -4
- package/package.json +2 -2
- package/dist/chunk-BIY46Q6U.js.map +0 -1
- package/dist/chunk-LN75Z624.js.map +0 -1
- package/dist/chunk-Y43UCVZS.js.map +0 -1
- /package/dist/{chunk-4GCV46AP.js.map → chunk-FCO5Z3RW.js.map} +0 -0
- /package/dist/{otel-grpc-DPSAGRUU.js.map → otel-grpc-CO47JRIN.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -503,13 +503,18 @@ function loadProtobufResponseEncoder() {
|
|
|
503
503
|
);
|
|
504
504
|
return exportTraceServiceResponseType;
|
|
505
505
|
}
|
|
506
|
-
function encodeProtobufResponseBody() {
|
|
507
|
-
if (cachedProtobufResponseBody) return cachedProtobufResponseBody;
|
|
506
|
+
function encodeProtobufResponseBody(rejected, message) {
|
|
508
507
|
const Type = loadProtobufResponseEncoder();
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
508
|
+
if (!rejected) {
|
|
509
|
+
if (cachedProtobufResponseBody) return cachedProtobufResponseBody;
|
|
510
|
+
const msg2 = Type.create({});
|
|
511
|
+
cachedProtobufResponseBody = Buffer.from(Type.encode(msg2).finish());
|
|
512
|
+
return cachedProtobufResponseBody;
|
|
513
|
+
}
|
|
514
|
+
const msg = Type.fromObject({
|
|
515
|
+
partial_success: { rejected_spans: rejected, error_message: message ?? "" }
|
|
516
|
+
});
|
|
517
|
+
return Buffer.from(Type.encode(msg).finish());
|
|
513
518
|
}
|
|
514
519
|
async function decodeProtobufBody(buf) {
|
|
515
520
|
const Type = loadProtobufDecoder();
|
|
@@ -624,6 +629,13 @@ async function buildOtelReceiver(opts) {
|
|
|
624
629
|
}
|
|
625
630
|
return reply.code(200).header("content-type", "application/json").send({ partialSuccess: {} });
|
|
626
631
|
}
|
|
632
|
+
function sendOtlpPartial(reply, flavor, rejected, message) {
|
|
633
|
+
if (flavor === "protobuf") {
|
|
634
|
+
const buf = encodeProtobufResponseBody(rejected, message);
|
|
635
|
+
return reply.code(200).header("content-type", "application/x-protobuf").send(buf);
|
|
636
|
+
}
|
|
637
|
+
return reply.code(200).header("content-type", "application/json").send({ partialSuccess: { rejectedSpans: rejected, errorMessage: message } });
|
|
638
|
+
}
|
|
627
639
|
app.addContentTypeParser(
|
|
628
640
|
"application/x-protobuf",
|
|
629
641
|
{ parseAs: "buffer", bodyLimit: opts.bodyLimit ?? 16 * 1024 * 1024 },
|
|
@@ -651,6 +663,10 @@ async function buildOtelReceiver(opts) {
|
|
|
651
663
|
}
|
|
652
664
|
}
|
|
653
665
|
enqueue(spans);
|
|
666
|
+
if (opts.classifyBareRoutability) {
|
|
667
|
+
const { rejected, message } = opts.classifyBareRoutability(spans);
|
|
668
|
+
if (rejected > 0) return sendOtlpPartial(reply, result.flavor, rejected, message);
|
|
669
|
+
}
|
|
654
670
|
return sendOtlpSuccess(reply, result.flavor);
|
|
655
671
|
});
|
|
656
672
|
app.post("/projects/:project/v1/traces", async (req, reply) => {
|
|
@@ -4865,10 +4881,15 @@ function resolveDistToSrc(absFilepath, line) {
|
|
|
4865
4881
|
}
|
|
4866
4882
|
if (!entry) return null;
|
|
4867
4883
|
try {
|
|
4868
|
-
const
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4884
|
+
const queryLine = line !== void 0 && Number.isFinite(line) ? line : 1;
|
|
4885
|
+
let pos = entry.consumer.originalPositionFor({ line: queryLine, column: 0 });
|
|
4886
|
+
if (!pos || !pos.source) {
|
|
4887
|
+
pos = entry.consumer.originalPositionFor({
|
|
4888
|
+
line: queryLine,
|
|
4889
|
+
column: 0,
|
|
4890
|
+
bias: sourceMapJs.SourceMapConsumer.LEAST_UPPER_BOUND
|
|
4891
|
+
});
|
|
4892
|
+
}
|
|
4872
4893
|
if (!pos || !pos.source) return null;
|
|
4873
4894
|
const root = entry.consumer.sourceRoot ?? "";
|
|
4874
4895
|
const resolved = import_node_path8.default.resolve(entry.dir, root, pos.source);
|
|
@@ -4877,6 +4898,9 @@ function resolveDistToSrc(absFilepath, line) {
|
|
|
4877
4898
|
return null;
|
|
4878
4899
|
}
|
|
4879
4900
|
}
|
|
4901
|
+
function hasAdjacentSourceMap(absFilepath) {
|
|
4902
|
+
return sourceMapCache.get(absFilepath) != null;
|
|
4903
|
+
}
|
|
4880
4904
|
function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
4881
4905
|
const filepath = codeFilepathOf(span.attributes);
|
|
4882
4906
|
if (filepath === void 0) return null;
|
|
@@ -4892,7 +4916,7 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
|
4892
4916
|
}
|
|
4893
4917
|
const relPath = relPathForRuntimeFile(effectivePath, serviceNode, scanPath);
|
|
4894
4918
|
if (!relPath) return null;
|
|
4895
|
-
if (!resolved && abs.endsWith(".js") && relPath.startsWith("dist/") && serviceNode?.name) {
|
|
4919
|
+
if (!resolved && abs.endsWith(".js") && relPath.startsWith("dist/") && !hasAdjacentSourceMap(abs) && serviceNode?.name) {
|
|
4896
4920
|
warnNoSourceMaps(serviceNode.name);
|
|
4897
4921
|
}
|
|
4898
4922
|
const fn = codeFunctionOf(span.attributes);
|
|
@@ -5168,7 +5192,7 @@ function resolveServiceId(graph, host, env) {
|
|
|
5168
5192
|
function frontierIdFor(host) {
|
|
5169
5193
|
return (0, import_types8.frontierId)(host);
|
|
5170
5194
|
}
|
|
5171
|
-
function
|
|
5195
|
+
function resolveFusedServiceId(graph, serviceName, env) {
|
|
5172
5196
|
const id = (0, import_types8.serviceId)(serviceName, env);
|
|
5173
5197
|
if (graph.hasNode(id)) return id;
|
|
5174
5198
|
const wanted = serviceName.toLowerCase();
|
|
@@ -5178,17 +5202,21 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
5178
5202
|
if (svc.discoveredVia === "otel") return false;
|
|
5179
5203
|
return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
|
|
5180
5204
|
});
|
|
5181
|
-
|
|
5205
|
+
return extractedId ?? id;
|
|
5206
|
+
}
|
|
5207
|
+
function ensureServiceNode(graph, serviceName, env) {
|
|
5208
|
+
const resolved = resolveFusedServiceId(graph, serviceName, env);
|
|
5209
|
+
if (graph.hasNode(resolved)) return resolved;
|
|
5182
5210
|
const node = {
|
|
5183
|
-
id,
|
|
5211
|
+
id: resolved,
|
|
5184
5212
|
type: import_types8.NodeType.ServiceNode,
|
|
5185
5213
|
name: serviceName,
|
|
5186
5214
|
language: "unknown",
|
|
5187
5215
|
discoveredVia: "otel",
|
|
5188
5216
|
...env !== "unknown" ? { env } : {}
|
|
5189
5217
|
};
|
|
5190
|
-
graph.addNode(
|
|
5191
|
-
return
|
|
5218
|
+
graph.addNode(resolved, node);
|
|
5219
|
+
return resolved;
|
|
5192
5220
|
}
|
|
5193
5221
|
function ensureInfraNode(graph, kind, name, provider) {
|
|
5194
5222
|
const id = (0, import_types8.infraId)(kind, name);
|
|
@@ -5382,7 +5410,7 @@ async function appendErrorEvent(ctx, ev) {
|
|
|
5382
5410
|
await import_node_fs7.promises.appendFile(ctx.errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
5383
5411
|
}
|
|
5384
5412
|
function incidentAffectedNode(span, graph, scanPath) {
|
|
5385
|
-
const sid = (0, import_types8.serviceId)(span.service, span.env);
|
|
5413
|
+
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types8.serviceId)(span.service, span.env);
|
|
5386
5414
|
const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
|
|
5387
5415
|
const callSite = callSiteFromSpan(span, serviceNode, scanPath);
|
|
5388
5416
|
if (callSite) {
|
|
@@ -6784,7 +6812,7 @@ function disambiguate(defs) {
|
|
|
6784
6812
|
}
|
|
6785
6813
|
async function addSymbols(graph, services) {
|
|
6786
6814
|
const parsers = /* @__PURE__ */ new Map();
|
|
6787
|
-
const
|
|
6815
|
+
const parserForExt5 = (ext) => {
|
|
6788
6816
|
const grammar = GRAMMAR_BY_EXT[ext];
|
|
6789
6817
|
if (!grammar) return null;
|
|
6790
6818
|
let parser = parsers.get(ext);
|
|
@@ -6800,7 +6828,7 @@ async function addSymbols(graph, services) {
|
|
|
6800
6828
|
for (const service of services) {
|
|
6801
6829
|
const files = await loadSourceFiles(service.dir);
|
|
6802
6830
|
for (const file of files) {
|
|
6803
|
-
const parser =
|
|
6831
|
+
const parser = parserForExt5(import_node_path17.default.extname(file.path));
|
|
6804
6832
|
if (!parser) continue;
|
|
6805
6833
|
const relPath = toPosix(import_node_path17.default.relative(service.dir, file.path));
|
|
6806
6834
|
let defs;
|
|
@@ -6952,7 +6980,7 @@ function stringInner(node) {
|
|
|
6952
6980
|
}
|
|
6953
6981
|
async function addSymbolEdges(graph, services) {
|
|
6954
6982
|
const parsers = /* @__PURE__ */ new Map();
|
|
6955
|
-
const
|
|
6983
|
+
const parserForExt5 = (ext) => {
|
|
6956
6984
|
const grammar = GRAMMAR_BY_EXT[ext];
|
|
6957
6985
|
if (!grammar) return null;
|
|
6958
6986
|
let parser = parsers.get(ext);
|
|
@@ -6969,7 +6997,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
6969
6997
|
const tsPaths = await loadTsPathConfig(service.dir);
|
|
6970
6998
|
const files = await loadSourceFiles(service.dir);
|
|
6971
6999
|
for (const file of files) {
|
|
6972
|
-
const parser =
|
|
7000
|
+
const parser = parserForExt5(import_node_path18.default.extname(file.path));
|
|
6973
7001
|
if (!parser) continue;
|
|
6974
7002
|
const relPath = toPosix(import_node_path18.default.relative(service.dir, file.path));
|
|
6975
7003
|
const fileDir = import_node_path18.default.dirname(file.path);
|
|
@@ -7231,7 +7259,7 @@ function firstReferenceLines(root, wanted) {
|
|
|
7231
7259
|
}
|
|
7232
7260
|
async function addServerActions(graph, services) {
|
|
7233
7261
|
const parsers = /* @__PURE__ */ new Map();
|
|
7234
|
-
const
|
|
7262
|
+
const parserForExt5 = (ext) => {
|
|
7235
7263
|
const grammar = GRAMMAR_BY_EXT[ext];
|
|
7236
7264
|
if (!grammar) return null;
|
|
7237
7265
|
let parser = parsers.get(ext);
|
|
@@ -7254,7 +7282,7 @@ async function addServerActions(graph, services) {
|
|
|
7254
7282
|
const files = await loadSourceFiles(service.dir);
|
|
7255
7283
|
for (const file of files) {
|
|
7256
7284
|
if (isTestPath(file.path)) continue;
|
|
7257
|
-
const parser =
|
|
7285
|
+
const parser = parserForExt5(import_node_path19.default.extname(file.path));
|
|
7258
7286
|
if (!parser) continue;
|
|
7259
7287
|
const relPath = toPosix(import_node_path19.default.relative(service.dir, file.path));
|
|
7260
7288
|
let root;
|
|
@@ -7317,7 +7345,7 @@ async function addServerActions(graph, services) {
|
|
|
7317
7345
|
}
|
|
7318
7346
|
for (const file of files) {
|
|
7319
7347
|
if (isTestPath(file.path)) continue;
|
|
7320
|
-
const parser =
|
|
7348
|
+
const parser = parserForExt5(import_node_path19.default.extname(file.path));
|
|
7321
7349
|
if (!parser) continue;
|
|
7322
7350
|
const relPath = toPosix(import_node_path19.default.relative(service.dir, file.path));
|
|
7323
7351
|
const fileDir = import_node_path19.default.dirname(file.path);
|
|
@@ -8281,6 +8309,7 @@ init_cjs_shims();
|
|
|
8281
8309
|
var import_node_path30 = __toESM(require("path"), 1);
|
|
8282
8310
|
var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
8283
8311
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
8312
|
+
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
8284
8313
|
var import_tree_sitter_python3 = __toESM(require("tree-sitter-python"), 1);
|
|
8285
8314
|
var import_types20 = require("@neat.is/types");
|
|
8286
8315
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
@@ -8331,19 +8360,27 @@ function callsFromSource(source, parser, knownHosts) {
|
|
|
8331
8360
|
}
|
|
8332
8361
|
return out;
|
|
8333
8362
|
}
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8363
|
+
var GRAMMAR_BY_EXT2 = {
|
|
8364
|
+
".ts": import_tree_sitter_typescript2.default.typescript,
|
|
8365
|
+
".tsx": import_tree_sitter_typescript2.default.tsx,
|
|
8366
|
+
".js": import_tree_sitter_javascript4.default,
|
|
8367
|
+
".jsx": import_tree_sitter_javascript4.default,
|
|
8368
|
+
".mjs": import_tree_sitter_javascript4.default,
|
|
8369
|
+
".cjs": import_tree_sitter_javascript4.default,
|
|
8370
|
+
".py": import_tree_sitter_python3.default
|
|
8371
|
+
};
|
|
8372
|
+
function parserForExt(ext, cache) {
|
|
8373
|
+
const grammar = GRAMMAR_BY_EXT2[ext] ?? import_tree_sitter_javascript4.default;
|
|
8374
|
+
let parser = cache.get(grammar);
|
|
8375
|
+
if (!parser) {
|
|
8376
|
+
parser = new import_tree_sitter6.default();
|
|
8377
|
+
parser.setLanguage(grammar);
|
|
8378
|
+
cache.set(grammar, parser);
|
|
8379
|
+
}
|
|
8380
|
+
return parser;
|
|
8343
8381
|
}
|
|
8344
8382
|
async function addHttpCallEdges(graph, services) {
|
|
8345
|
-
const
|
|
8346
|
-
const pyParser = makePyParser3();
|
|
8383
|
+
const parserCache = /* @__PURE__ */ new Map();
|
|
8347
8384
|
const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
|
|
8348
8385
|
let nodesAdded = 0;
|
|
8349
8386
|
let edgesAdded = 0;
|
|
@@ -8352,7 +8389,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
8352
8389
|
const seen = /* @__PURE__ */ new Set();
|
|
8353
8390
|
for (const file of files) {
|
|
8354
8391
|
if (isTestPath(file.path)) continue;
|
|
8355
|
-
const parser = import_node_path30.default.extname(file.path)
|
|
8392
|
+
const parser = parserForExt(import_node_path30.default.extname(file.path), parserCache);
|
|
8356
8393
|
let sites;
|
|
8357
8394
|
try {
|
|
8358
8395
|
sites = callsFromSource(file.content, parser, knownHosts);
|
|
@@ -8425,7 +8462,7 @@ function parseSource5(parser, source) {
|
|
|
8425
8462
|
(index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK5)
|
|
8426
8463
|
);
|
|
8427
8464
|
}
|
|
8428
|
-
function
|
|
8465
|
+
function makeJsParser3() {
|
|
8429
8466
|
const p = new import_tree_sitter7.default();
|
|
8430
8467
|
p.setLanguage(import_tree_sitter_javascript5.default);
|
|
8431
8468
|
return p;
|
|
@@ -8603,7 +8640,7 @@ function findRoute(entries, method, normalizedPath) {
|
|
|
8603
8640
|
);
|
|
8604
8641
|
}
|
|
8605
8642
|
async function addRouteCallEdges(graph, services) {
|
|
8606
|
-
const jsParser =
|
|
8643
|
+
const jsParser = makeJsParser3();
|
|
8607
8644
|
const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
|
|
8608
8645
|
const routeIndex = buildRouteIndex(graph);
|
|
8609
8646
|
if (routeIndex.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
@@ -8995,7 +9032,7 @@ var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"),
|
|
|
8995
9032
|
var import_types27 = require("@neat.is/types");
|
|
8996
9033
|
var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
|
|
8997
9034
|
var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
|
|
8998
|
-
function
|
|
9035
|
+
function parserForExt2(ext) {
|
|
8999
9036
|
const p = new import_tree_sitter8.default();
|
|
9000
9037
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript6.default);
|
|
9001
9038
|
return p;
|
|
@@ -9160,7 +9197,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
|
|
|
9160
9197
|
const hasAdmin = FIRESTORE_ADMIN_IMPORT_RE.test(file.content);
|
|
9161
9198
|
if (!hasClient && !hasAdmin) return [];
|
|
9162
9199
|
const fileSdk = hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
|
|
9163
|
-
const tree = parseSource3(
|
|
9200
|
+
const tree = parseSource3(parserForExt2(import_node_path37.default.extname(file.path)), file.content);
|
|
9164
9201
|
const clientVars = firestoreClientVars(tree.rootNode);
|
|
9165
9202
|
const collLine = /* @__PURE__ */ new Map();
|
|
9166
9203
|
const writes = /* @__PURE__ */ new Map();
|
|
@@ -9577,7 +9614,7 @@ var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
|
|
|
9577
9614
|
var import_types29 = require("@neat.is/types");
|
|
9578
9615
|
var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
|
|
9579
9616
|
var PARSE_CHUNK6 = 16384;
|
|
9580
|
-
function
|
|
9617
|
+
function makePyParser3() {
|
|
9581
9618
|
const p = new import_tree_sitter9.default();
|
|
9582
9619
|
p.setLanguage(import_tree_sitter_python4.default);
|
|
9583
9620
|
return p;
|
|
@@ -9684,7 +9721,7 @@ function foreignKeyParentTable(call) {
|
|
|
9684
9721
|
}
|
|
9685
9722
|
function sqlalchemyForeignKeys(file, serviceDir) {
|
|
9686
9723
|
if (!SQLALCHEMY_IMPORT_RE.test(file.content)) return [];
|
|
9687
|
-
const tree = parseSource6(
|
|
9724
|
+
const tree = parseSource6(makePyParser3(), file.content);
|
|
9688
9725
|
const out = [];
|
|
9689
9726
|
const seen = /* @__PURE__ */ new Set();
|
|
9690
9727
|
walk3(tree.rootNode, (node) => {
|
|
@@ -9721,7 +9758,7 @@ function sqlalchemyForeignKeys(file, serviceDir) {
|
|
|
9721
9758
|
}
|
|
9722
9759
|
function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
9723
9760
|
if (!SQLALCHEMY_IMPORT_RE.test(file.content)) return [];
|
|
9724
|
-
const tree = parseSource6(
|
|
9761
|
+
const tree = parseSource6(makePyParser3(), file.content);
|
|
9725
9762
|
const out = [];
|
|
9726
9763
|
const seen = /* @__PURE__ */ new Set();
|
|
9727
9764
|
const push = (name, line, columns) => {
|
|
@@ -9773,7 +9810,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
9773
9810
|
function buildSqlalchemyModelRegistry(files) {
|
|
9774
9811
|
const table = /* @__PURE__ */ new Map();
|
|
9775
9812
|
const ambiguous = /* @__PURE__ */ new Set();
|
|
9776
|
-
const parser =
|
|
9813
|
+
const parser = makePyParser3();
|
|
9777
9814
|
for (const file of files) {
|
|
9778
9815
|
if (!SQLALCHEMY_IMPORT_RE.test(file.content)) continue;
|
|
9779
9816
|
const tree = parseSource6(parser, file.content);
|
|
@@ -9822,7 +9859,7 @@ function importsModelName(content, name) {
|
|
|
9822
9859
|
function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
9823
9860
|
const registry = buildSqlalchemyModelRegistry(files);
|
|
9824
9861
|
if (registry.size === 0) return [];
|
|
9825
|
-
const parser =
|
|
9862
|
+
const parser = makePyParser3();
|
|
9826
9863
|
const out = [];
|
|
9827
9864
|
const seen = /* @__PURE__ */ new Set();
|
|
9828
9865
|
for (const file of files) {
|
|
@@ -9860,7 +9897,7 @@ var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
|
9860
9897
|
var import_types30 = require("@neat.is/types");
|
|
9861
9898
|
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
9862
9899
|
var PARSE_CHUNK7 = 16384;
|
|
9863
|
-
function
|
|
9900
|
+
function makePyParser4() {
|
|
9864
9901
|
const p = new import_tree_sitter10.default();
|
|
9865
9902
|
p.setLanguage(import_tree_sitter_python5.default);
|
|
9866
9903
|
return p;
|
|
@@ -9921,7 +9958,7 @@ function readMeta(body) {
|
|
|
9921
9958
|
}
|
|
9922
9959
|
function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
9923
9960
|
if (!DJANGO_IMPORT_RE.test(file.content)) return [];
|
|
9924
|
-
const tree = parseSource7(
|
|
9961
|
+
const tree = parseSource7(makePyParser4(), file.content);
|
|
9925
9962
|
const out = [];
|
|
9926
9963
|
const seen = /* @__PURE__ */ new Set();
|
|
9927
9964
|
const defaultAppLabel = import_node_path40.default.basename(import_node_path40.default.dirname(file.path));
|
|
@@ -9956,7 +9993,7 @@ var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"),
|
|
|
9956
9993
|
var import_types31 = require("@neat.is/types");
|
|
9957
9994
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
9958
9995
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
9959
|
-
function
|
|
9996
|
+
function parserForExt3(ext) {
|
|
9960
9997
|
const p = new import_tree_sitter11.default();
|
|
9961
9998
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript7.default);
|
|
9962
9999
|
return p;
|
|
@@ -10028,7 +10065,7 @@ function columnsFromObject(obj) {
|
|
|
10028
10065
|
}
|
|
10029
10066
|
function drizzleEndpointsFromFile(file, serviceDir) {
|
|
10030
10067
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
10031
|
-
const tree = parseSource3(
|
|
10068
|
+
const tree = parseSource3(parserForExt3(import_node_path41.default.extname(file.path)), file.content);
|
|
10032
10069
|
const out = [];
|
|
10033
10070
|
const seen = /* @__PURE__ */ new Set();
|
|
10034
10071
|
const walk9 = (node) => {
|
|
@@ -10117,7 +10154,7 @@ function referencesTargetVar(call) {
|
|
|
10117
10154
|
}
|
|
10118
10155
|
function drizzleForeignKeys(file, serviceDir) {
|
|
10119
10156
|
if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
|
|
10120
|
-
const tree = parseSource3(
|
|
10157
|
+
const tree = parseSource3(parserForExt3(import_node_path41.default.extname(file.path)), file.content);
|
|
10121
10158
|
const { tables, varToTable } = collectDrizzleTables(tree.rootNode);
|
|
10122
10159
|
const out = [];
|
|
10123
10160
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -12824,7 +12861,7 @@ var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"),
|
|
|
12824
12861
|
var import_types47 = require("@neat.is/types");
|
|
12825
12862
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
12826
12863
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
12827
|
-
function
|
|
12864
|
+
function parserForExt4(ext) {
|
|
12828
12865
|
const p = new import_tree_sitter16.default();
|
|
12829
12866
|
p.setLanguage(GRAMMAR_BY_EXT[ext] ?? import_tree_sitter_javascript8.default);
|
|
12830
12867
|
return p;
|
|
@@ -12913,7 +12950,7 @@ function topLevelSchemas(root) {
|
|
|
12913
12950
|
}
|
|
12914
12951
|
function zodShapesFromFile(file, serviceDir) {
|
|
12915
12952
|
if (!ZOD_IMPORT_RE.test(file.content)) return [];
|
|
12916
|
-
const tree = parseSource3(
|
|
12953
|
+
const tree = parseSource3(parserForExt4(import_node_path57.default.extname(file.path)), file.content);
|
|
12917
12954
|
const out = [];
|
|
12918
12955
|
const seen = /* @__PURE__ */ new Set();
|
|
12919
12956
|
for (const { name, call } of topLevelSchemas(tree.rootNode)) {
|
|
@@ -18931,6 +18968,19 @@ async function startDaemon(opts = {}) {
|
|
|
18931
18968
|
let otlpAddress = "";
|
|
18932
18969
|
let daemonRecord = null;
|
|
18933
18970
|
if (bind) {
|
|
18971
|
+
let bareSpanIsRoutable2 = function(serviceName) {
|
|
18972
|
+
if (singleProject) {
|
|
18973
|
+
const slot = slots.get(singleProject);
|
|
18974
|
+
if (!slot) {
|
|
18975
|
+
return !serviceName || serviceNameMatchesProject(serviceName, singleProject);
|
|
18976
|
+
}
|
|
18977
|
+
return spanBelongsToSingleProject(slot.graph, singleProject, serviceName);
|
|
18978
|
+
}
|
|
18979
|
+
const entries = [...slots.values()].map((s) => s.entry);
|
|
18980
|
+
const target = routeSpanToProject(serviceName, entries);
|
|
18981
|
+
return slots.has(target) || slots.has(DEFAULT_PROJECT);
|
|
18982
|
+
};
|
|
18983
|
+
var bareSpanIsRoutable = bareSpanIsRoutable2;
|
|
18934
18984
|
const auth = readAuthEnv();
|
|
18935
18985
|
const host = resolveHost(opts, Boolean(auth.authToken));
|
|
18936
18986
|
const restPort = resolveRestPort(opts);
|
|
@@ -19028,6 +19078,20 @@ async function startDaemon(opts = {}) {
|
|
|
19028
19078
|
const liveEntries = await listProjects().catch(() => []);
|
|
19029
19079
|
let slot = slots.get(project);
|
|
19030
19080
|
if (!slot) {
|
|
19081
|
+
if (singleProject && project === singleProject) {
|
|
19082
|
+
slot = await tryRecoverSlot({
|
|
19083
|
+
name: singleProject,
|
|
19084
|
+
path: singleProjectPath,
|
|
19085
|
+
registeredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19086
|
+
languages: [],
|
|
19087
|
+
status: "active"
|
|
19088
|
+
});
|
|
19089
|
+
if (!slot || slot.status !== "active") {
|
|
19090
|
+
warnDroppedSpan(singleProject, slot?.errorReason ?? "unknown");
|
|
19091
|
+
return null;
|
|
19092
|
+
}
|
|
19093
|
+
return slot;
|
|
19094
|
+
}
|
|
19031
19095
|
await recordUnroutedSpan(serviceName, traceId);
|
|
19032
19096
|
return null;
|
|
19033
19097
|
}
|
|
@@ -19094,7 +19158,30 @@ async function startDaemon(opts = {}) {
|
|
|
19094
19158
|
// host, rather than accepting it and dropping the batch. `slots` covers
|
|
19095
19159
|
// active/recovering projects, `bootstrapStatus` the ones still
|
|
19096
19160
|
// extracting; a foreign or wrong-cased project name matches neither.
|
|
19097
|
-
|
|
19161
|
+
// A single-project daemon owns exactly one project by definition, so its
|
|
19162
|
+
// own name always counts as registered even before loadAll populates the
|
|
19163
|
+
// slot — otherwise a scoped span arriving during cold-start would 404 and
|
|
19164
|
+
// be lost (OTLP does not retry 4xx). resolveSlotByName then builds it (#879).
|
|
19165
|
+
isProjectRegistered: (project) => slots.has(project) || bootstrapStatus.has(project) || singleProject !== void 0 && project === singleProject,
|
|
19166
|
+
// #881 — the bare `/v1/traces` route replies before the span is routed
|
|
19167
|
+
// (off the queue), so tell the receiver, per batch, how many spans will
|
|
19168
|
+
// land on no project. It keeps the 200 but reports those as
|
|
19169
|
+
// partialSuccess.rejectedSpans instead of an empty partialSuccess that an
|
|
19170
|
+
// exporter reads as full acceptance. Pure — the drop + unrouted-ledger
|
|
19171
|
+
// write still happen on the async onSpan path.
|
|
19172
|
+
classifyBareRoutability: (spans) => {
|
|
19173
|
+
let rejected = 0;
|
|
19174
|
+
for (const span of spans) {
|
|
19175
|
+
if (!bareSpanIsRoutable2(span.service)) rejected++;
|
|
19176
|
+
}
|
|
19177
|
+
if (rejected === 0) return { rejected: 0 };
|
|
19178
|
+
const noun = rejected === 1 ? "span" : "spans";
|
|
19179
|
+
const verb = rejected === 1 ? "was" : "were";
|
|
19180
|
+
return {
|
|
19181
|
+
rejected,
|
|
19182
|
+
message: `${rejected} ${noun} matched no project on this daemon and ${verb} dropped. Export to /projects/<project>/v1/traces, or check the exporter's service.name.`
|
|
19183
|
+
};
|
|
19184
|
+
}
|
|
19098
19185
|
});
|
|
19099
19186
|
otlpAddress = await listenSteppingOtlp(otlpApp, otlpPort, host);
|
|
19100
19187
|
console.log(`neatd: OTLP listening on ${otlpAddress}/v1/traces`);
|