@neat.is/core 0.5.2 → 0.5.3
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-BI3XKGVG.js → chunk-GJHEZC5K.js} +56 -21
- package/dist/chunk-GJHEZC5K.js.map +1 -0
- package/dist/{chunk-DPEPI2N6.js → chunk-X2AMX3QZ.js} +32 -14
- package/dist/chunk-X2AMX3QZ.js.map +1 -0
- package/dist/cli.cjs +366 -120
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +250 -58
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +85 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +85 -32
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +55 -20
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-BI3XKGVG.js.map +0 -1
- package/dist/chunk-DPEPI2N6.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
routeSpanToProject,
|
|
3
3
|
startDaemon
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-X2AMX3QZ.js";
|
|
5
5
|
import {
|
|
6
6
|
ProjectNameCollisionError,
|
|
7
7
|
addProject,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
thresholdForEdgeType,
|
|
38
38
|
touchLastSeen,
|
|
39
39
|
writeAtomically
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-GJHEZC5K.js";
|
|
41
41
|
import {
|
|
42
42
|
startOtelGrpcReceiver
|
|
43
43
|
} from "./chunk-I72HTUOG.js";
|
package/dist/neatd.cjs
CHANGED
|
@@ -4633,14 +4633,21 @@ function engineFromImage(image) {
|
|
|
4633
4633
|
// src/extract/databases/dotenv.ts
|
|
4634
4634
|
var CONNECTION_KEYS = /* @__PURE__ */ new Set([
|
|
4635
4635
|
"DATABASE_URL",
|
|
4636
|
+
"DATABASE_URI",
|
|
4636
4637
|
"DB_URL",
|
|
4638
|
+
"DB_URI",
|
|
4637
4639
|
"POSTGRES_URL",
|
|
4640
|
+
"POSTGRES_URI",
|
|
4638
4641
|
"POSTGRESQL_URL",
|
|
4642
|
+
"POSTGRESQL_URI",
|
|
4639
4643
|
"MYSQL_URL",
|
|
4644
|
+
"MYSQL_URI",
|
|
4645
|
+
"MONGODB_URL",
|
|
4640
4646
|
"MONGODB_URI",
|
|
4641
4647
|
"MONGO_URL",
|
|
4642
4648
|
"MONGO_URI",
|
|
4643
|
-
"REDIS_URL"
|
|
4649
|
+
"REDIS_URL",
|
|
4650
|
+
"REDIS_URI"
|
|
4644
4651
|
]);
|
|
4645
4652
|
function parseDotenvLine(line) {
|
|
4646
4653
|
const trimmed = line.trim();
|
|
@@ -7778,11 +7785,42 @@ async function readPackageJson(scanPath) {
|
|
|
7778
7785
|
const raw = await import_node_fs26.promises.readFile(pkgPath, "utf8");
|
|
7779
7786
|
return JSON.parse(raw);
|
|
7780
7787
|
}
|
|
7788
|
+
var HOOK_WALK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
7789
|
+
"node_modules",
|
|
7790
|
+
"dist",
|
|
7791
|
+
"build",
|
|
7792
|
+
"out",
|
|
7793
|
+
"coverage",
|
|
7794
|
+
"neat-out"
|
|
7795
|
+
]);
|
|
7781
7796
|
async function findHookFiles(scanPath) {
|
|
7782
|
-
const
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7797
|
+
const found = [];
|
|
7798
|
+
const walk3 = async (dir) => {
|
|
7799
|
+
const entries = await import_node_fs26.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
7800
|
+
for (const entry2 of entries) {
|
|
7801
|
+
if (entry2.isDirectory()) {
|
|
7802
|
+
if (entry2.name.startsWith(".") || HOOK_WALK_SKIP_DIRS.has(entry2.name)) continue;
|
|
7803
|
+
await walk3(import_node_path44.default.join(dir, entry2.name));
|
|
7804
|
+
} else if (entry2.isFile()) {
|
|
7805
|
+
if ((entry2.name.startsWith("instrumentation") || entry2.name.startsWith("otel-init")) && /\.(ts|js|cjs|mjs)$/.test(entry2.name)) {
|
|
7806
|
+
const rel = import_node_path44.default.relative(scanPath, import_node_path44.default.join(dir, entry2.name));
|
|
7807
|
+
found.push(rel.split(import_node_path44.default.sep).join("/"));
|
|
7808
|
+
}
|
|
7809
|
+
}
|
|
7810
|
+
}
|
|
7811
|
+
};
|
|
7812
|
+
await walk3(scanPath);
|
|
7813
|
+
return found.sort();
|
|
7814
|
+
}
|
|
7815
|
+
async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
|
|
7816
|
+
let fallback = null;
|
|
7817
|
+
for (const file of hookFiles) {
|
|
7818
|
+
const content = await import_node_fs26.promises.readFile(import_node_path44.default.join(scanPath, file), "utf8");
|
|
7819
|
+
const patched = splicedContent(content, snippet2);
|
|
7820
|
+
if (patched !== null) return { file, content, patched };
|
|
7821
|
+
if (fallback === null) fallback = { file, content };
|
|
7822
|
+
}
|
|
7823
|
+
return { file: fallback.file, content: fallback.content, patched: null };
|
|
7786
7824
|
}
|
|
7787
7825
|
function extendLogPath() {
|
|
7788
7826
|
return process.env.NEAT_EXTEND_LOG ?? import_node_path44.default.join(import_node_os2.default.homedir(), ".neat", "extend-log.ndjson");
|
|
@@ -7875,7 +7913,13 @@ async function applyExtension(ctx, args, options) {
|
|
|
7875
7913
|
return { library: args.library, filesTouched: [], depsAdded: [], installOutput: "", alreadyApplied: true };
|
|
7876
7914
|
}
|
|
7877
7915
|
}
|
|
7878
|
-
const
|
|
7916
|
+
const primary = await pickPrimaryHookFile(ctx.scanPath, hookFiles, args.registration_snippet);
|
|
7917
|
+
if (primary.patched === null) {
|
|
7918
|
+
throw new Error(
|
|
7919
|
+
`Could not find instrumentation insertion point in ${hookFiles.join(", ")}. Expected __INSTRUMENTATION_BLOCK__, instrumentations.push(, or new NodeSDK(.`
|
|
7920
|
+
);
|
|
7921
|
+
}
|
|
7922
|
+
const primaryFile = primary.file;
|
|
7879
7923
|
const primaryPath = import_node_path44.default.join(ctx.scanPath, primaryFile);
|
|
7880
7924
|
const filesTouched = [];
|
|
7881
7925
|
const depsAdded = [];
|
|
@@ -7887,14 +7931,7 @@ async function applyExtension(ctx, args, options) {
|
|
|
7887
7931
|
filesTouched.push("package.json");
|
|
7888
7932
|
depsAdded.push(`${args.instrumentation_package}@${args.version}`);
|
|
7889
7933
|
}
|
|
7890
|
-
|
|
7891
|
-
const patched = splicedContent(hookContent, args.registration_snippet);
|
|
7892
|
-
if (!patched) {
|
|
7893
|
-
throw new Error(
|
|
7894
|
-
`Could not find instrumentation insertion point in ${primaryFile}. Expected __INSTRUMENTATION_BLOCK__, instrumentations.push(, or new NodeSDK(.`
|
|
7895
|
-
);
|
|
7896
|
-
}
|
|
7897
|
-
await import_node_fs26.promises.writeFile(primaryPath, patched, "utf8");
|
|
7934
|
+
await import_node_fs26.promises.writeFile(primaryPath, primary.patched, "utf8");
|
|
7898
7935
|
filesTouched.push(primaryFile);
|
|
7899
7936
|
const cmd = await detectPackageManager(ctx.scanPath);
|
|
7900
7937
|
const installer = options?.runInstall ?? runPackageManagerInstall;
|
|
@@ -7936,7 +7973,7 @@ async function dryRunExtension(ctx, args) {
|
|
|
7936
7973
|
};
|
|
7937
7974
|
}
|
|
7938
7975
|
}
|
|
7939
|
-
const
|
|
7976
|
+
const primary = await pickPrimaryHookFile(ctx.scanPath, hookFiles, args.registration_snippet);
|
|
7940
7977
|
const filesTouched = [];
|
|
7941
7978
|
const depsToAdd = [];
|
|
7942
7979
|
let packageJsonPatch = {};
|
|
@@ -7947,10 +7984,8 @@ async function dryRunExtension(ctx, args) {
|
|
|
7947
7984
|
depsToAdd.push(`${args.instrumentation_package}@${args.version}`);
|
|
7948
7985
|
filesTouched.push("package.json");
|
|
7949
7986
|
}
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
if (patched) {
|
|
7953
|
-
filesTouched.push(primaryFile);
|
|
7987
|
+
if (primary.patched !== null) {
|
|
7988
|
+
filesTouched.push(primary.file);
|
|
7954
7989
|
templatePatch = `+ ${args.registration_snippet}`;
|
|
7955
7990
|
} else {
|
|
7956
7991
|
templatePatch = "Could not find insertion point in hook file.";
|
|
@@ -9488,7 +9523,7 @@ function registerRoutes(scope, ctx) {
|
|
|
9488
9523
|
});
|
|
9489
9524
|
}
|
|
9490
9525
|
async function buildApi(opts) {
|
|
9491
|
-
const app = (0, import_fastify.default)({ logger: false });
|
|
9526
|
+
const app = (0, import_fastify.default)({ logger: false, routerOptions: { maxParamLength: 1024 } });
|
|
9492
9527
|
await app.register(import_cors.default, { origin: true });
|
|
9493
9528
|
const env = readAuthEnv();
|
|
9494
9529
|
const authToken = opts.authToken ?? env.authToken;
|
|
@@ -9665,8 +9700,8 @@ async function runConnectorPoll(connector, ctx, graph, resolveTarget) {
|
|
|
9665
9700
|
line: callSite.line
|
|
9666
9701
|
} : void 0;
|
|
9667
9702
|
const calls = Math.trunc(signal.callCount);
|
|
9668
|
-
if (calls < 1) continue;
|
|
9669
|
-
const errors = Math.min(Math.max(Math.trunc(signal.errorCount), 0), calls);
|
|
9703
|
+
if (!Number.isFinite(calls) || calls < 1) continue;
|
|
9704
|
+
const errors = Number.isFinite(signal.errorCount) ? Math.min(Math.max(Math.trunc(signal.errorCount), 0), calls) : 0;
|
|
9670
9705
|
let created = false;
|
|
9671
9706
|
let ok = true;
|
|
9672
9707
|
for (let i = 0; i < calls; i++) {
|
|
@@ -10113,7 +10148,10 @@ function targetFromRestPath(path53) {
|
|
|
10113
10148
|
var ERROR_STATUS_THRESHOLD = 500;
|
|
10114
10149
|
function mapEdgeLogRowsToSignals(rows) {
|
|
10115
10150
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
10151
|
+
if (!Array.isArray(rows)) return [];
|
|
10116
10152
|
for (const row of rows) {
|
|
10153
|
+
if (!row || typeof row !== "object") continue;
|
|
10154
|
+
if (typeof row.path !== "string" || typeof row.timestamp !== "string") continue;
|
|
10117
10155
|
const target = targetFromRestPath(row.path);
|
|
10118
10156
|
if (!target) continue;
|
|
10119
10157
|
const key = `${target.targetKind}:${target.name}`;
|
|
@@ -10154,9 +10192,12 @@ function tableNameFromQueryText(query) {
|
|
|
10154
10192
|
function diffPgStatStatementsToSignals(rows, previous, nowIso2) {
|
|
10155
10193
|
const signals = [];
|
|
10156
10194
|
const seen = /* @__PURE__ */ new Set();
|
|
10195
|
+
if (!Array.isArray(rows)) return signals;
|
|
10157
10196
|
for (const row of rows) {
|
|
10158
|
-
|
|
10197
|
+
if (!row || typeof row !== "object" || typeof row.queryid !== "string") continue;
|
|
10159
10198
|
const calls = Number(row.calls);
|
|
10199
|
+
if (!Number.isFinite(calls)) continue;
|
|
10200
|
+
seen.add(row.queryid);
|
|
10160
10201
|
const prior = previous.get(row.queryid);
|
|
10161
10202
|
previous.set(row.queryid, { calls });
|
|
10162
10203
|
if (!prior || calls < prior.calls) continue;
|
|
@@ -10480,7 +10521,12 @@ function upsertBucket(buckets2, key, isError, timestamp, build) {
|
|
|
10480
10521
|
}
|
|
10481
10522
|
function mapRailwayHttpLogsToSignals(entries, routeIndex) {
|
|
10482
10523
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
10524
|
+
if (!Array.isArray(entries)) return [];
|
|
10483
10525
|
for (const entry2 of entries) {
|
|
10526
|
+
if (!entry2 || typeof entry2 !== "object") continue;
|
|
10527
|
+
if (typeof entry2.method !== "string" || typeof entry2.path !== "string" || typeof entry2.timestamp !== "string") {
|
|
10528
|
+
continue;
|
|
10529
|
+
}
|
|
10484
10530
|
const method = entry2.method.toUpperCase();
|
|
10485
10531
|
const normalizedPath = normalizePathTemplate(entry2.path);
|
|
10486
10532
|
const match = findRailwayRoute(routeIndex, method, normalizedPath);
|
|
@@ -10519,8 +10565,11 @@ function mapRailwayHttpLogsToSignals(entries, routeIndex) {
|
|
|
10519
10565
|
}
|
|
10520
10566
|
function mapRailwayNetworkFlowLogsToSignals(entries) {
|
|
10521
10567
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
10568
|
+
if (!Array.isArray(entries)) return [];
|
|
10522
10569
|
for (const entry2 of entries) {
|
|
10523
|
-
if (!entry2
|
|
10570
|
+
if (!entry2 || typeof entry2 !== "object") continue;
|
|
10571
|
+
if (typeof entry2.peerServiceId !== "string" || entry2.peerServiceId.length === 0) continue;
|
|
10572
|
+
if (typeof entry2.timestamp !== "string") continue;
|
|
10524
10573
|
const isError = entry2.dropCause !== null && entry2.dropCause !== "";
|
|
10525
10574
|
upsertBucket(buckets2, entry2.peerServiceId, isError, entry2.timestamp, () => ({
|
|
10526
10575
|
targetKind: PEER_SERVICE_TARGET_KIND,
|
|
@@ -10648,7 +10697,7 @@ async function fetchHttpRequestLogEntries(creds, sinceIso) {
|
|
|
10648
10697
|
throw new Error(`Cloud Logging entries.list failed: ${res.status} ${res.statusText}`);
|
|
10649
10698
|
}
|
|
10650
10699
|
const json = await res.json();
|
|
10651
|
-
out.push(...json.entries
|
|
10700
|
+
if (Array.isArray(json.entries)) out.push(...json.entries);
|
|
10652
10701
|
if (!json.nextPageToken) break;
|
|
10653
10702
|
pageToken = json.nextPageToken;
|
|
10654
10703
|
}
|
|
@@ -10685,7 +10734,7 @@ function resourceNameFor(type, labels) {
|
|
|
10685
10734
|
}
|
|
10686
10735
|
}
|
|
10687
10736
|
function pathFromRequestUrl(requestUrl) {
|
|
10688
|
-
if (
|
|
10737
|
+
if (typeof requestUrl !== "string" || requestUrl.length === 0) return null;
|
|
10689
10738
|
if (requestUrl.startsWith("/")) {
|
|
10690
10739
|
const withoutQuery = requestUrl.split("?")[0];
|
|
10691
10740
|
return withoutQuery && withoutQuery.length > 0 ? withoutQuery : "/";
|
|
@@ -10700,18 +10749,19 @@ function pathFromRequestUrl(requestUrl) {
|
|
|
10700
10749
|
}
|
|
10701
10750
|
var ERROR_STATUS_THRESHOLD2 = 500;
|
|
10702
10751
|
function mapLogEntryToSignal(entry2) {
|
|
10752
|
+
if (!entry2 || typeof entry2 !== "object") return null;
|
|
10703
10753
|
const resourceType = entry2.resource?.type;
|
|
10704
10754
|
if (!resourceType || !isFirebaseResourceType(resourceType)) return null;
|
|
10705
10755
|
const resourceName = resourceNameFor(resourceType, entry2.resource?.labels);
|
|
10706
10756
|
if (!resourceName) return null;
|
|
10707
10757
|
const req2 = entry2.httpRequest;
|
|
10708
10758
|
if (!req2) return null;
|
|
10709
|
-
if (
|
|
10759
|
+
if (typeof req2.requestMethod !== "string" || req2.requestMethod.length === 0) return null;
|
|
10710
10760
|
const method = req2.requestMethod.toUpperCase();
|
|
10711
10761
|
const path53 = pathFromRequestUrl(req2.requestUrl);
|
|
10712
10762
|
if (path53 === null) return null;
|
|
10713
10763
|
const timestamp = entry2.timestamp;
|
|
10714
|
-
if (
|
|
10764
|
+
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
10715
10765
|
const isError = typeof req2.status === "number" && req2.status >= ERROR_STATUS_THRESHOLD2;
|
|
10716
10766
|
return {
|
|
10717
10767
|
targetKind: resourceType,
|
|
@@ -10863,7 +10913,7 @@ async function queryWorkerInvocations(ctx, config, window, fetchImpl = fetch) {
|
|
|
10863
10913
|
throw new Error(`cloudflare connector: telemetry query returned an error (${message})`);
|
|
10864
10914
|
}
|
|
10865
10915
|
const events = payload.result?.events?.events;
|
|
10866
|
-
if (events
|
|
10916
|
+
if (!Array.isArray(events)) {
|
|
10867
10917
|
console.warn(
|
|
10868
10918
|
"[neat connector] cloudflare: telemetry query returned success:true but no result.events.events array \u2014 the response shape may have changed; treating as zero events this tick"
|
|
10869
10919
|
);
|
|
@@ -10893,7 +10943,7 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
|
10893
10943
|
]);
|
|
10894
10944
|
var LEADING_TOKEN_RE = /^(\S+)\s+\S/;
|
|
10895
10945
|
function parseHttpMethodFromTrigger(trigger) {
|
|
10896
|
-
if (
|
|
10946
|
+
if (typeof trigger !== "string") return null;
|
|
10897
10947
|
const match = LEADING_TOKEN_RE.exec(trigger.trim());
|
|
10898
10948
|
const token = match?.[1];
|
|
10899
10949
|
if (!token) return null;
|
|
@@ -10909,14 +10959,17 @@ function parsePathFromTrigger(trigger) {
|
|
|
10909
10959
|
}
|
|
10910
10960
|
var ERROR_STATUS_THRESHOLD3 = 500;
|
|
10911
10961
|
function mapEventToSignal(event) {
|
|
10962
|
+
if (!event || typeof event !== "object") return null;
|
|
10912
10963
|
const metadata = event.$metadata;
|
|
10913
10964
|
const workers = event.$workers;
|
|
10914
10965
|
const method = parseHttpMethodFromTrigger(metadata?.trigger);
|
|
10915
10966
|
if (!method) return null;
|
|
10916
10967
|
const scriptName = workers?.scriptName ?? metadata?.service;
|
|
10917
|
-
if (
|
|
10968
|
+
if (typeof scriptName !== "string" || scriptName.length === 0) return null;
|
|
10918
10969
|
const timestampMs = event.timestamp ?? metadata?.startTime;
|
|
10919
10970
|
if (typeof timestampMs !== "number" || !Number.isFinite(timestampMs)) return null;
|
|
10971
|
+
const observedAt = new Date(timestampMs);
|
|
10972
|
+
if (Number.isNaN(observedAt.getTime())) return null;
|
|
10920
10973
|
const statusCode = metadata?.statusCode;
|
|
10921
10974
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
10922
10975
|
const path53 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
@@ -10925,7 +10978,7 @@ function mapEventToSignal(event) {
|
|
|
10925
10978
|
targetName: scriptName,
|
|
10926
10979
|
callCount: 1,
|
|
10927
10980
|
errorCount: isError ? 1 : 0,
|
|
10928
|
-
lastObservedIso:
|
|
10981
|
+
lastObservedIso: observedAt.toISOString(),
|
|
10929
10982
|
method,
|
|
10930
10983
|
...path53 ? { path: path53 } : {},
|
|
10931
10984
|
...typeof statusCode === "number" ? { statusCode } : {},
|