@neat.is/core 0.4.20-dev.20260621 → 0.4.20-dev.20260622
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-IWGDXLXA.js → chunk-62ELQVIP.js} +2 -2
- package/dist/{chunk-RVOCG6UZ.js → chunk-GNAX2CBF.js} +19 -4
- package/dist/chunk-GNAX2CBF.js.map +1 -0
- package/dist/cli.cjs +78 -5
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +62 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +18 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +18 -3
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +18 -3
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-RVOCG6UZ.js.map +0 -1
- /package/dist/{chunk-IWGDXLXA.js.map → chunk-62ELQVIP.js.map} +0 -0
package/dist/cli.cjs
CHANGED
|
@@ -2931,6 +2931,9 @@ function workspaceGlobs(pkg) {
|
|
|
2931
2931
|
if (Array.isArray(ws.packages)) return ws.packages.length > 0 ? ws.packages : null;
|
|
2932
2932
|
return null;
|
|
2933
2933
|
}
|
|
2934
|
+
async function hasPythonManifest(dir) {
|
|
2935
|
+
return await exists(import_node_path9.default.join(dir, "pyproject.toml")) || await exists(import_node_path9.default.join(dir, "requirements.txt")) || await exists(import_node_path9.default.join(dir, "setup.py"));
|
|
2936
|
+
}
|
|
2934
2937
|
async function loadGitignore(scanPath) {
|
|
2935
2938
|
const gitignorePath = import_node_path9.default.join(scanPath, ".gitignore");
|
|
2936
2939
|
if (!await exists(gitignorePath)) return null;
|
|
@@ -2997,6 +3000,13 @@ function detectJsFramework(pkg) {
|
|
|
2997
3000
|
if (deps["astro"] !== void 0) return "astro";
|
|
2998
3001
|
return void 0;
|
|
2999
3002
|
}
|
|
3003
|
+
async function detectJsServiceLanguage(dir, pkg) {
|
|
3004
|
+
const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
3005
|
+
if (deps["typescript"] !== void 0) return "typescript";
|
|
3006
|
+
const entries = await import_node_fs9.promises.readdir(dir).catch(() => []);
|
|
3007
|
+
if (entries.some((name) => /^tsconfig(\..+)?\.json$/.test(name))) return "typescript";
|
|
3008
|
+
return "javascript";
|
|
3009
|
+
}
|
|
3000
3010
|
async function discoverNodeService(scanPath, dir) {
|
|
3001
3011
|
const pkgPath = import_node_path9.default.join(dir, "package.json");
|
|
3002
3012
|
if (!await exists(pkgPath)) return null;
|
|
@@ -3009,11 +3019,12 @@ async function discoverNodeService(scanPath, dir) {
|
|
|
3009
3019
|
}
|
|
3010
3020
|
if (!pkg.name) return null;
|
|
3011
3021
|
const framework = detectJsFramework(pkg);
|
|
3022
|
+
const language = await detectJsServiceLanguage(dir, pkg);
|
|
3012
3023
|
const node = {
|
|
3013
3024
|
id: (0, import_types5.serviceId)(pkg.name),
|
|
3014
3025
|
type: import_types5.NodeType.ServiceNode,
|
|
3015
3026
|
name: pkg.name,
|
|
3016
|
-
language
|
|
3027
|
+
language,
|
|
3017
3028
|
version: pkg.version,
|
|
3018
3029
|
dependencies: pkg.dependencies ?? {},
|
|
3019
3030
|
repoPath: import_node_path9.default.relative(scanPath, dir),
|
|
@@ -3056,7 +3067,11 @@ async function discoverServices(scanPath) {
|
|
|
3056
3067
|
if (wsGlobs) {
|
|
3057
3068
|
candidateDirs.push(...await expandWorkspaceGlobs(scanPath, wsGlobs));
|
|
3058
3069
|
} else {
|
|
3059
|
-
if (rootPkg && rootPkg.name)
|
|
3070
|
+
if (rootPkg && rootPkg.name) {
|
|
3071
|
+
candidateDirs.push(scanPath);
|
|
3072
|
+
} else if (await hasPythonManifest(scanPath)) {
|
|
3073
|
+
candidateDirs.push(scanPath);
|
|
3074
|
+
}
|
|
3060
3075
|
const ig = await loadGitignore(scanPath);
|
|
3061
3076
|
await walkDirs(
|
|
3062
3077
|
scanPath,
|
|
@@ -3065,7 +3080,7 @@ async function discoverServices(scanPath) {
|
|
|
3065
3080
|
async (dir) => {
|
|
3066
3081
|
if (await exists(import_node_path9.default.join(dir, "package.json"))) {
|
|
3067
3082
|
candidateDirs.push(dir);
|
|
3068
|
-
} else if (await
|
|
3083
|
+
} else if (await hasPythonManifest(dir)) {
|
|
3069
3084
|
candidateDirs.push(dir);
|
|
3070
3085
|
}
|
|
3071
3086
|
}
|
|
@@ -8697,6 +8712,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|
|
8697
8712
|
`;
|
|
8698
8713
|
|
|
8699
8714
|
// src/installers/javascript.ts
|
|
8715
|
+
var import_instrumentation_registry2 = require("@neat.is/instrumentation-registry");
|
|
8700
8716
|
var SDK_PACKAGES = [
|
|
8701
8717
|
{ name: "@opentelemetry/api", version: "^1.9.0" },
|
|
8702
8718
|
{ name: "@opentelemetry/sdk-node", version: "^0.57.0" },
|
|
@@ -8821,6 +8837,34 @@ function hasNextDependency(pkg) {
|
|
|
8821
8837
|
function allDeps(pkg) {
|
|
8822
8838
|
return { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
8823
8839
|
}
|
|
8840
|
+
var WEB_FRAMEWORK_DEPS = [
|
|
8841
|
+
"express",
|
|
8842
|
+
"fastify",
|
|
8843
|
+
"koa",
|
|
8844
|
+
"@hapi/hapi",
|
|
8845
|
+
"hapi",
|
|
8846
|
+
"restify",
|
|
8847
|
+
"connect",
|
|
8848
|
+
"@nestjs/core",
|
|
8849
|
+
"next",
|
|
8850
|
+
"hono",
|
|
8851
|
+
"elysia",
|
|
8852
|
+
"polka",
|
|
8853
|
+
"micro"
|
|
8854
|
+
];
|
|
8855
|
+
function looksLikeWebApp(pkg) {
|
|
8856
|
+
const deps = allDeps(pkg);
|
|
8857
|
+
return WEB_FRAMEWORK_DEPS.some((name) => name in deps);
|
|
8858
|
+
}
|
|
8859
|
+
function uninstrumentedLibraries(pkg) {
|
|
8860
|
+
const deps = allDeps(pkg);
|
|
8861
|
+
const out = [];
|
|
8862
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
8863
|
+
const entry2 = (0, import_instrumentation_registry2.resolve)(name, version);
|
|
8864
|
+
if (entry2 && entry2.coverage === "gap") out.push(name);
|
|
8865
|
+
}
|
|
8866
|
+
return out;
|
|
8867
|
+
}
|
|
8824
8868
|
var REMIX_ENTRY_CANDIDATES = [
|
|
8825
8869
|
"app/entry.server.ts",
|
|
8826
8870
|
"app/entry.server.tsx",
|
|
@@ -8900,6 +8944,9 @@ var SRC_INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `src/index${ext}`);
|
|
|
8900
8944
|
var SRC_NAMED_CANDIDATES = ["server", "main", "app"].flatMap(
|
|
8901
8945
|
(name) => INDEX_EXTENSIONS.map((ext) => `src/${name}${ext}`)
|
|
8902
8946
|
);
|
|
8947
|
+
var ROOT_NAMED_CANDIDATES = ["server", "app", "main"].flatMap(
|
|
8948
|
+
(name) => INDEX_EXTENSIONS.map((ext) => `${name}${ext}`)
|
|
8949
|
+
);
|
|
8903
8950
|
var SCRIPT_LAUNCHERS = /* @__PURE__ */ new Set([
|
|
8904
8951
|
"node",
|
|
8905
8952
|
"ts-node",
|
|
@@ -8974,6 +9021,10 @@ async function resolveEntry(serviceDir, pkg) {
|
|
|
8974
9021
|
const candidate = import_node_path46.default.join(serviceDir, rel);
|
|
8975
9022
|
if (await exists3(candidate)) return candidate;
|
|
8976
9023
|
}
|
|
9024
|
+
for (const rel of ROOT_NAMED_CANDIDATES) {
|
|
9025
|
+
const candidate = import_node_path46.default.join(serviceDir, rel);
|
|
9026
|
+
if (await exists3(candidate)) return candidate;
|
|
9027
|
+
}
|
|
8977
9028
|
for (const name of INDEX_CANDIDATES) {
|
|
8978
9029
|
const candidate = import_node_path46.default.join(serviceDir, name);
|
|
8979
9030
|
if (await exists3(candidate)) return candidate;
|
|
@@ -10183,8 +10234,17 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
10183
10234
|
if (!installPlans.has(key)) installPlans.set(key, cmd);
|
|
10184
10235
|
}
|
|
10185
10236
|
} else if (outcome.outcome === "already-instrumented") already++;
|
|
10186
|
-
else if (outcome.outcome === "lib-only")
|
|
10187
|
-
|
|
10237
|
+
else if (outcome.outcome === "lib-only") {
|
|
10238
|
+
libOnly++;
|
|
10239
|
+
if (svc.pkg && looksLikeWebApp(svc.pkg)) {
|
|
10240
|
+
const svcName = import_node_path50.default.basename(svc.dir);
|
|
10241
|
+
console.warn(
|
|
10242
|
+
`neat: runtime layer won't engage for ${svcName}: no entry point found.
|
|
10243
|
+
${svc.dir} depends on a web framework but neat couldn't resolve an entry to instrument.
|
|
10244
|
+
Add a "start" script to package.json, or point neat at the entry file directly.`
|
|
10245
|
+
);
|
|
10246
|
+
}
|
|
10247
|
+
} else if (outcome.outcome === "browser-bundle") {
|
|
10188
10248
|
browserBundle++;
|
|
10189
10249
|
console.log(`skipping ${svc.dir}: browser bundle; browser-OTel support lands in a future release.`);
|
|
10190
10250
|
} else if (outcome.outcome === "react-native") {
|
|
@@ -10243,6 +10303,19 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
10243
10303
|
See docs/installer-scope.md \u2192 "Manual setup for out-of-scope runtimes"`
|
|
10244
10304
|
);
|
|
10245
10305
|
}
|
|
10306
|
+
if (svc.pkg && (outcome.outcome === "instrumented" || outcome.outcome === "already-instrumented")) {
|
|
10307
|
+
const gaps = uninstrumentedLibraries(svc.pkg);
|
|
10308
|
+
if (gaps.length > 0) {
|
|
10309
|
+
const svcName = import_node_path50.default.basename(svc.dir);
|
|
10310
|
+
const list = gaps.join(", ");
|
|
10311
|
+
const verb = gaps.length === 1 ? "this library" : "these libraries";
|
|
10312
|
+
console.warn(
|
|
10313
|
+
`neat: calls to ${list} won't be observed by default in ${svcName}.
|
|
10314
|
+
${verb} aren't in the default instrumentation set, so they produce no OBSERVED edges.
|
|
10315
|
+
Run \`neat list-uninstrumented\` to review them, then \`neat extend\` to capture them.`
|
|
10316
|
+
);
|
|
10317
|
+
}
|
|
10318
|
+
}
|
|
10246
10319
|
}
|
|
10247
10320
|
const packageManagerInstalls = [];
|
|
10248
10321
|
for (const cmd of installPlans.values()) {
|