@neat.is/core 0.5.1 → 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 +383 -121
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +267 -59
- 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.cjs
CHANGED
|
@@ -4673,14 +4673,21 @@ function engineFromImage(image) {
|
|
|
4673
4673
|
// src/extract/databases/dotenv.ts
|
|
4674
4674
|
var CONNECTION_KEYS = /* @__PURE__ */ new Set([
|
|
4675
4675
|
"DATABASE_URL",
|
|
4676
|
+
"DATABASE_URI",
|
|
4676
4677
|
"DB_URL",
|
|
4678
|
+
"DB_URI",
|
|
4677
4679
|
"POSTGRES_URL",
|
|
4680
|
+
"POSTGRES_URI",
|
|
4678
4681
|
"POSTGRESQL_URL",
|
|
4682
|
+
"POSTGRESQL_URI",
|
|
4679
4683
|
"MYSQL_URL",
|
|
4684
|
+
"MYSQL_URI",
|
|
4685
|
+
"MONGODB_URL",
|
|
4680
4686
|
"MONGODB_URI",
|
|
4681
4687
|
"MONGO_URL",
|
|
4682
4688
|
"MONGO_URI",
|
|
4683
|
-
"REDIS_URL"
|
|
4689
|
+
"REDIS_URL",
|
|
4690
|
+
"REDIS_URI"
|
|
4684
4691
|
]);
|
|
4685
4692
|
function parseDotenvLine(line) {
|
|
4686
4693
|
const trimmed = line.trim();
|
|
@@ -7766,11 +7773,42 @@ async function readPackageJson(scanPath) {
|
|
|
7766
7773
|
const raw = await import_node_fs26.promises.readFile(pkgPath, "utf8");
|
|
7767
7774
|
return JSON.parse(raw);
|
|
7768
7775
|
}
|
|
7776
|
+
var HOOK_WALK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
7777
|
+
"node_modules",
|
|
7778
|
+
"dist",
|
|
7779
|
+
"build",
|
|
7780
|
+
"out",
|
|
7781
|
+
"coverage",
|
|
7782
|
+
"neat-out"
|
|
7783
|
+
]);
|
|
7769
7784
|
async function findHookFiles(scanPath) {
|
|
7770
|
-
const
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7785
|
+
const found = [];
|
|
7786
|
+
const walk3 = async (dir) => {
|
|
7787
|
+
const entries = await import_node_fs26.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
7788
|
+
for (const entry of entries) {
|
|
7789
|
+
if (entry.isDirectory()) {
|
|
7790
|
+
if (entry.name.startsWith(".") || HOOK_WALK_SKIP_DIRS.has(entry.name)) continue;
|
|
7791
|
+
await walk3(import_node_path43.default.join(dir, entry.name));
|
|
7792
|
+
} else if (entry.isFile()) {
|
|
7793
|
+
if ((entry.name.startsWith("instrumentation") || entry.name.startsWith("otel-init")) && /\.(ts|js|cjs|mjs)$/.test(entry.name)) {
|
|
7794
|
+
const rel = import_node_path43.default.relative(scanPath, import_node_path43.default.join(dir, entry.name));
|
|
7795
|
+
found.push(rel.split(import_node_path43.default.sep).join("/"));
|
|
7796
|
+
}
|
|
7797
|
+
}
|
|
7798
|
+
}
|
|
7799
|
+
};
|
|
7800
|
+
await walk3(scanPath);
|
|
7801
|
+
return found.sort();
|
|
7802
|
+
}
|
|
7803
|
+
async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
|
|
7804
|
+
let fallback = null;
|
|
7805
|
+
for (const file of hookFiles) {
|
|
7806
|
+
const content = await import_node_fs26.promises.readFile(import_node_path43.default.join(scanPath, file), "utf8");
|
|
7807
|
+
const patched = splicedContent(content, snippet2);
|
|
7808
|
+
if (patched !== null) return { file, content, patched };
|
|
7809
|
+
if (fallback === null) fallback = { file, content };
|
|
7810
|
+
}
|
|
7811
|
+
return { file: fallback.file, content: fallback.content, patched: null };
|
|
7774
7812
|
}
|
|
7775
7813
|
function extendLogPath() {
|
|
7776
7814
|
return process.env.NEAT_EXTEND_LOG ?? import_node_path43.default.join(import_node_os2.default.homedir(), ".neat", "extend-log.ndjson");
|
|
@@ -7863,7 +7901,13 @@ async function applyExtension(ctx, args, options) {
|
|
|
7863
7901
|
return { library: args.library, filesTouched: [], depsAdded: [], installOutput: "", alreadyApplied: true };
|
|
7864
7902
|
}
|
|
7865
7903
|
}
|
|
7866
|
-
const
|
|
7904
|
+
const primary = await pickPrimaryHookFile(ctx.scanPath, hookFiles, args.registration_snippet);
|
|
7905
|
+
if (primary.patched === null) {
|
|
7906
|
+
throw new Error(
|
|
7907
|
+
`Could not find instrumentation insertion point in ${hookFiles.join(", ")}. Expected __INSTRUMENTATION_BLOCK__, instrumentations.push(, or new NodeSDK(.`
|
|
7908
|
+
);
|
|
7909
|
+
}
|
|
7910
|
+
const primaryFile = primary.file;
|
|
7867
7911
|
const primaryPath = import_node_path43.default.join(ctx.scanPath, primaryFile);
|
|
7868
7912
|
const filesTouched = [];
|
|
7869
7913
|
const depsAdded = [];
|
|
@@ -7875,14 +7919,7 @@ async function applyExtension(ctx, args, options) {
|
|
|
7875
7919
|
filesTouched.push("package.json");
|
|
7876
7920
|
depsAdded.push(`${args.instrumentation_package}@${args.version}`);
|
|
7877
7921
|
}
|
|
7878
|
-
|
|
7879
|
-
const patched = splicedContent(hookContent, args.registration_snippet);
|
|
7880
|
-
if (!patched) {
|
|
7881
|
-
throw new Error(
|
|
7882
|
-
`Could not find instrumentation insertion point in ${primaryFile}. Expected __INSTRUMENTATION_BLOCK__, instrumentations.push(, or new NodeSDK(.`
|
|
7883
|
-
);
|
|
7884
|
-
}
|
|
7885
|
-
await import_node_fs26.promises.writeFile(primaryPath, patched, "utf8");
|
|
7922
|
+
await import_node_fs26.promises.writeFile(primaryPath, primary.patched, "utf8");
|
|
7886
7923
|
filesTouched.push(primaryFile);
|
|
7887
7924
|
const cmd = await detectPackageManager(ctx.scanPath);
|
|
7888
7925
|
const installer = options?.runInstall ?? runPackageManagerInstall;
|
|
@@ -7924,7 +7961,7 @@ async function dryRunExtension(ctx, args) {
|
|
|
7924
7961
|
};
|
|
7925
7962
|
}
|
|
7926
7963
|
}
|
|
7927
|
-
const
|
|
7964
|
+
const primary = await pickPrimaryHookFile(ctx.scanPath, hookFiles, args.registration_snippet);
|
|
7928
7965
|
const filesTouched = [];
|
|
7929
7966
|
const depsToAdd = [];
|
|
7930
7967
|
let packageJsonPatch = {};
|
|
@@ -7935,10 +7972,8 @@ async function dryRunExtension(ctx, args) {
|
|
|
7935
7972
|
depsToAdd.push(`${args.instrumentation_package}@${args.version}`);
|
|
7936
7973
|
filesTouched.push("package.json");
|
|
7937
7974
|
}
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
if (patched) {
|
|
7941
|
-
filesTouched.push(primaryFile);
|
|
7975
|
+
if (primary.patched !== null) {
|
|
7976
|
+
filesTouched.push(primary.file);
|
|
7942
7977
|
templatePatch = `+ ${args.registration_snippet}`;
|
|
7943
7978
|
} else {
|
|
7944
7979
|
templatePatch = "Could not find insertion point in hook file.";
|
|
@@ -9586,7 +9621,7 @@ function registerRoutes(scope, ctx) {
|
|
|
9586
9621
|
});
|
|
9587
9622
|
}
|
|
9588
9623
|
async function buildApi(opts) {
|
|
9589
|
-
const app = (0, import_fastify.default)({ logger: false });
|
|
9624
|
+
const app = (0, import_fastify.default)({ logger: false, routerOptions: { maxParamLength: 1024 } });
|
|
9590
9625
|
await app.register(import_cors.default, { origin: true });
|
|
9591
9626
|
const env = readAuthEnv();
|
|
9592
9627
|
const authToken = opts.authToken ?? env.authToken;
|
|
@@ -9771,8 +9806,8 @@ async function runConnectorPoll(connector, ctx, graph, resolveTarget) {
|
|
|
9771
9806
|
line: callSite.line
|
|
9772
9807
|
} : void 0;
|
|
9773
9808
|
const calls = Math.trunc(signal.callCount);
|
|
9774
|
-
if (calls < 1) continue;
|
|
9775
|
-
const errors = Math.min(Math.max(Math.trunc(signal.errorCount), 0), calls);
|
|
9809
|
+
if (!Number.isFinite(calls) || calls < 1) continue;
|
|
9810
|
+
const errors = Number.isFinite(signal.errorCount) ? Math.min(Math.max(Math.trunc(signal.errorCount), 0), calls) : 0;
|
|
9776
9811
|
let created = false;
|
|
9777
9812
|
let ok = true;
|
|
9778
9813
|
for (let i = 0; i < calls; i++) {
|
|
@@ -10219,7 +10254,10 @@ function targetFromRestPath(path51) {
|
|
|
10219
10254
|
var ERROR_STATUS_THRESHOLD = 500;
|
|
10220
10255
|
function mapEdgeLogRowsToSignals(rows) {
|
|
10221
10256
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
10257
|
+
if (!Array.isArray(rows)) return [];
|
|
10222
10258
|
for (const row of rows) {
|
|
10259
|
+
if (!row || typeof row !== "object") continue;
|
|
10260
|
+
if (typeof row.path !== "string" || typeof row.timestamp !== "string") continue;
|
|
10223
10261
|
const target = targetFromRestPath(row.path);
|
|
10224
10262
|
if (!target) continue;
|
|
10225
10263
|
const key = `${target.targetKind}:${target.name}`;
|
|
@@ -10260,9 +10298,12 @@ function tableNameFromQueryText(query) {
|
|
|
10260
10298
|
function diffPgStatStatementsToSignals(rows, previous, nowIso2) {
|
|
10261
10299
|
const signals = [];
|
|
10262
10300
|
const seen = /* @__PURE__ */ new Set();
|
|
10301
|
+
if (!Array.isArray(rows)) return signals;
|
|
10263
10302
|
for (const row of rows) {
|
|
10264
|
-
|
|
10303
|
+
if (!row || typeof row !== "object" || typeof row.queryid !== "string") continue;
|
|
10265
10304
|
const calls = Number(row.calls);
|
|
10305
|
+
if (!Number.isFinite(calls)) continue;
|
|
10306
|
+
seen.add(row.queryid);
|
|
10266
10307
|
const prior = previous.get(row.queryid);
|
|
10267
10308
|
previous.set(row.queryid, { calls });
|
|
10268
10309
|
if (!prior || calls < prior.calls) continue;
|
|
@@ -10586,7 +10627,12 @@ function upsertBucket(buckets2, key, isError, timestamp, build) {
|
|
|
10586
10627
|
}
|
|
10587
10628
|
function mapRailwayHttpLogsToSignals(entries, routeIndex) {
|
|
10588
10629
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
10630
|
+
if (!Array.isArray(entries)) return [];
|
|
10589
10631
|
for (const entry of entries) {
|
|
10632
|
+
if (!entry || typeof entry !== "object") continue;
|
|
10633
|
+
if (typeof entry.method !== "string" || typeof entry.path !== "string" || typeof entry.timestamp !== "string") {
|
|
10634
|
+
continue;
|
|
10635
|
+
}
|
|
10590
10636
|
const method = entry.method.toUpperCase();
|
|
10591
10637
|
const normalizedPath = normalizePathTemplate(entry.path);
|
|
10592
10638
|
const match = findRailwayRoute(routeIndex, method, normalizedPath);
|
|
@@ -10625,8 +10671,11 @@ function mapRailwayHttpLogsToSignals(entries, routeIndex) {
|
|
|
10625
10671
|
}
|
|
10626
10672
|
function mapRailwayNetworkFlowLogsToSignals(entries) {
|
|
10627
10673
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
10674
|
+
if (!Array.isArray(entries)) return [];
|
|
10628
10675
|
for (const entry of entries) {
|
|
10629
|
-
if (!entry
|
|
10676
|
+
if (!entry || typeof entry !== "object") continue;
|
|
10677
|
+
if (typeof entry.peerServiceId !== "string" || entry.peerServiceId.length === 0) continue;
|
|
10678
|
+
if (typeof entry.timestamp !== "string") continue;
|
|
10630
10679
|
const isError = entry.dropCause !== null && entry.dropCause !== "";
|
|
10631
10680
|
upsertBucket(buckets2, entry.peerServiceId, isError, entry.timestamp, () => ({
|
|
10632
10681
|
targetKind: PEER_SERVICE_TARGET_KIND,
|
|
@@ -10754,7 +10803,7 @@ async function fetchHttpRequestLogEntries(creds, sinceIso) {
|
|
|
10754
10803
|
throw new Error(`Cloud Logging entries.list failed: ${res.status} ${res.statusText}`);
|
|
10755
10804
|
}
|
|
10756
10805
|
const json = await res.json();
|
|
10757
|
-
out.push(...json.entries
|
|
10806
|
+
if (Array.isArray(json.entries)) out.push(...json.entries);
|
|
10758
10807
|
if (!json.nextPageToken) break;
|
|
10759
10808
|
pageToken = json.nextPageToken;
|
|
10760
10809
|
}
|
|
@@ -10791,7 +10840,7 @@ function resourceNameFor(type, labels) {
|
|
|
10791
10840
|
}
|
|
10792
10841
|
}
|
|
10793
10842
|
function pathFromRequestUrl(requestUrl) {
|
|
10794
|
-
if (
|
|
10843
|
+
if (typeof requestUrl !== "string" || requestUrl.length === 0) return null;
|
|
10795
10844
|
if (requestUrl.startsWith("/")) {
|
|
10796
10845
|
const withoutQuery = requestUrl.split("?")[0];
|
|
10797
10846
|
return withoutQuery && withoutQuery.length > 0 ? withoutQuery : "/";
|
|
@@ -10806,18 +10855,19 @@ function pathFromRequestUrl(requestUrl) {
|
|
|
10806
10855
|
}
|
|
10807
10856
|
var ERROR_STATUS_THRESHOLD2 = 500;
|
|
10808
10857
|
function mapLogEntryToSignal(entry) {
|
|
10858
|
+
if (!entry || typeof entry !== "object") return null;
|
|
10809
10859
|
const resourceType = entry.resource?.type;
|
|
10810
10860
|
if (!resourceType || !isFirebaseResourceType(resourceType)) return null;
|
|
10811
10861
|
const resourceName = resourceNameFor(resourceType, entry.resource?.labels);
|
|
10812
10862
|
if (!resourceName) return null;
|
|
10813
10863
|
const req = entry.httpRequest;
|
|
10814
10864
|
if (!req) return null;
|
|
10815
|
-
if (
|
|
10865
|
+
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
10816
10866
|
const method = req.requestMethod.toUpperCase();
|
|
10817
10867
|
const path51 = pathFromRequestUrl(req.requestUrl);
|
|
10818
10868
|
if (path51 === null) return null;
|
|
10819
10869
|
const timestamp = entry.timestamp;
|
|
10820
|
-
if (
|
|
10870
|
+
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
10821
10871
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
|
|
10822
10872
|
return {
|
|
10823
10873
|
targetKind: resourceType,
|
|
@@ -10969,7 +11019,7 @@ async function queryWorkerInvocations(ctx, config, window, fetchImpl = fetch) {
|
|
|
10969
11019
|
throw new Error(`cloudflare connector: telemetry query returned an error (${message})`);
|
|
10970
11020
|
}
|
|
10971
11021
|
const events = payload.result?.events?.events;
|
|
10972
|
-
if (events
|
|
11022
|
+
if (!Array.isArray(events)) {
|
|
10973
11023
|
console.warn(
|
|
10974
11024
|
"[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"
|
|
10975
11025
|
);
|
|
@@ -10999,7 +11049,7 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
|
10999
11049
|
]);
|
|
11000
11050
|
var LEADING_TOKEN_RE = /^(\S+)\s+\S/;
|
|
11001
11051
|
function parseHttpMethodFromTrigger(trigger) {
|
|
11002
|
-
if (
|
|
11052
|
+
if (typeof trigger !== "string") return null;
|
|
11003
11053
|
const match = LEADING_TOKEN_RE.exec(trigger.trim());
|
|
11004
11054
|
const token = match?.[1];
|
|
11005
11055
|
if (!token) return null;
|
|
@@ -11015,14 +11065,17 @@ function parsePathFromTrigger(trigger) {
|
|
|
11015
11065
|
}
|
|
11016
11066
|
var ERROR_STATUS_THRESHOLD3 = 500;
|
|
11017
11067
|
function mapEventToSignal(event) {
|
|
11068
|
+
if (!event || typeof event !== "object") return null;
|
|
11018
11069
|
const metadata = event.$metadata;
|
|
11019
11070
|
const workers = event.$workers;
|
|
11020
11071
|
const method = parseHttpMethodFromTrigger(metadata?.trigger);
|
|
11021
11072
|
if (!method) return null;
|
|
11022
11073
|
const scriptName = workers?.scriptName ?? metadata?.service;
|
|
11023
|
-
if (
|
|
11074
|
+
if (typeof scriptName !== "string" || scriptName.length === 0) return null;
|
|
11024
11075
|
const timestampMs = event.timestamp ?? metadata?.startTime;
|
|
11025
11076
|
if (typeof timestampMs !== "number" || !Number.isFinite(timestampMs)) return null;
|
|
11077
|
+
const observedAt = new Date(timestampMs);
|
|
11078
|
+
if (Number.isNaN(observedAt.getTime())) return null;
|
|
11026
11079
|
const statusCode = metadata?.statusCode;
|
|
11027
11080
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
11028
11081
|
const path51 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
@@ -11031,7 +11084,7 @@ function mapEventToSignal(event) {
|
|
|
11031
11084
|
targetName: scriptName,
|
|
11032
11085
|
callCount: 1,
|
|
11033
11086
|
errorCount: isError ? 1 : 0,
|
|
11034
|
-
lastObservedIso:
|
|
11087
|
+
lastObservedIso: observedAt.toISOString(),
|
|
11035
11088
|
method,
|
|
11036
11089
|
...path51 ? { path: path51 } : {},
|
|
11037
11090
|
...typeof statusCode === "number" ? { statusCode } : {},
|