@neat.is/core 0.4.2 → 0.4.4
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-NTQHMXWE.js → chunk-G3YGPWJL.js} +2 -2
- package/dist/{chunk-CB2UK4EH.js → chunk-J4YBTD24.js} +44 -3
- package/dist/{chunk-CB2UK4EH.js.map → chunk-J4YBTD24.js.map} +1 -1
- package/dist/{chunk-D5PIJFBE.js → chunk-YJOA7BBF.js} +2 -2
- package/dist/{chunk-KYRIQIPG.js → chunk-ZVNP3ZDH.js} +97 -25
- package/dist/chunk-ZVNP3ZDH.js.map +1 -0
- package/dist/cli.cjs +307 -125
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +215 -105
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +136 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -4
- package/dist/neatd.cjs +136 -23
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +3 -3
- package/dist/{otel-grpc-QTX2YQJZ.js → otel-grpc-FIERFRGD.js} +3 -3
- package/dist/server.cjs +95 -23
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +3 -3
- package/package.json +2 -2
- package/dist/chunk-KYRIQIPG.js.map +0 -1
- /package/dist/{chunk-NTQHMXWE.js.map → chunk-G3YGPWJL.js.map} +0 -0
- /package/dist/{chunk-D5PIJFBE.js.map → chunk-YJOA7BBF.js.map} +0 -0
- /package/dist/{otel-grpc-QTX2YQJZ.js.map → otel-grpc-FIERFRGD.js.map} +0 -0
package/dist/cli.cjs
CHANGED
|
@@ -401,6 +401,64 @@ async function buildOtelReceiver(opts) {
|
|
|
401
401
|
for (const s of spans) queue.push(s);
|
|
402
402
|
drainPromise = drainPromise.then(() => drain());
|
|
403
403
|
};
|
|
404
|
+
const projectQueue = [];
|
|
405
|
+
let projectDraining = false;
|
|
406
|
+
let projectDrainPromise = Promise.resolve();
|
|
407
|
+
const drainProject = async () => {
|
|
408
|
+
if (projectDraining) return;
|
|
409
|
+
projectDraining = true;
|
|
410
|
+
try {
|
|
411
|
+
while (projectQueue.length > 0) {
|
|
412
|
+
const { project, span } = projectQueue.shift();
|
|
413
|
+
try {
|
|
414
|
+
if (opts.onProjectSpan) {
|
|
415
|
+
await opts.onProjectSpan(project, span);
|
|
416
|
+
} else {
|
|
417
|
+
await opts.onSpan(span);
|
|
418
|
+
}
|
|
419
|
+
} catch (err) {
|
|
420
|
+
console.warn(`[neat] otel handler error: ${err.message}`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
} finally {
|
|
424
|
+
projectDraining = false;
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
const enqueueProject = (project, spans) => {
|
|
428
|
+
if (spans.length === 0) return;
|
|
429
|
+
for (const s of spans) projectQueue.push({ project, span: s });
|
|
430
|
+
projectDrainPromise = projectDrainPromise.then(() => drainProject());
|
|
431
|
+
};
|
|
432
|
+
const legacyEndpointWarned = /* @__PURE__ */ new Set();
|
|
433
|
+
function warnLegacyEndpoint(serviceName) {
|
|
434
|
+
if (legacyEndpointWarned.has(serviceName)) return;
|
|
435
|
+
legacyEndpointWarned.add(serviceName);
|
|
436
|
+
console.warn(
|
|
437
|
+
`[neatd] received span on the global endpoint; migrate OTEL_EXPORTER_OTLP_TRACES_ENDPOINT to /projects/<name>/v1/traces (service.name="${serviceName}").`
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
async function readOtlpBody(req) {
|
|
441
|
+
const ct = (req.headers["content-type"] ?? "").toString().split(";")[0].trim().toLowerCase();
|
|
442
|
+
if (ct === "application/x-protobuf") {
|
|
443
|
+
try {
|
|
444
|
+
const body = await decodeProtobufBody(req.body);
|
|
445
|
+
return { ok: true, body, flavor: "protobuf" };
|
|
446
|
+
} catch (err) {
|
|
447
|
+
return { ok: false, code: 400, error: `protobuf decode failed: ${err.message}` };
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
if (!ct || ct === "application/json") {
|
|
451
|
+
return { ok: true, body: req.body ?? {}, flavor: "json" };
|
|
452
|
+
}
|
|
453
|
+
return { ok: false, code: 415, error: `unsupported content-type: ${ct}` };
|
|
454
|
+
}
|
|
455
|
+
function sendOtlpSuccess(reply, flavor) {
|
|
456
|
+
if (flavor === "protobuf") {
|
|
457
|
+
const buf = encodeProtobufResponseBody();
|
|
458
|
+
return reply.code(200).header("content-type", "application/x-protobuf").send(buf);
|
|
459
|
+
}
|
|
460
|
+
return reply.code(200).header("content-type", "application/json").send({ partialSuccess: {} });
|
|
461
|
+
}
|
|
404
462
|
app.addContentTypeParser(
|
|
405
463
|
"application/x-protobuf",
|
|
406
464
|
{ parseAs: "buffer", bodyLimit: opts.bodyLimit ?? 16 * 1024 * 1024 },
|
|
@@ -410,26 +468,44 @@ async function buildOtelReceiver(opts) {
|
|
|
410
468
|
);
|
|
411
469
|
app.get("/health", async () => ({ ok: true }));
|
|
412
470
|
app.post("/v1/traces", async (req, reply) => {
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
471
|
+
const result = await readOtlpBody(req);
|
|
472
|
+
if (!result.ok) {
|
|
473
|
+
return reply.code(result.code).send({ error: result.error });
|
|
474
|
+
}
|
|
475
|
+
const spans = parseOtlpRequest(result.body);
|
|
476
|
+
for (const s of spans) warnLegacyEndpoint(s.service);
|
|
477
|
+
if (opts.onErrorSpanSync) {
|
|
418
478
|
try {
|
|
419
|
-
|
|
479
|
+
for (const span of spans) {
|
|
480
|
+
if (span.statusCode === 2) await opts.onErrorSpanSync(span);
|
|
481
|
+
}
|
|
420
482
|
} catch (err) {
|
|
421
|
-
return reply.code(
|
|
422
|
-
error: `
|
|
483
|
+
return reply.code(500).send({
|
|
484
|
+
error: `error-event write failed: ${err.message}`
|
|
423
485
|
});
|
|
424
486
|
}
|
|
425
|
-
} else if (!ct || ct === "application/json") {
|
|
426
|
-
responseFlavor = "json";
|
|
427
|
-
body = req.body ?? {};
|
|
428
|
-
} else {
|
|
429
|
-
return reply.code(415).send({ error: `unsupported content-type: ${ct}` });
|
|
430
487
|
}
|
|
431
|
-
|
|
432
|
-
|
|
488
|
+
enqueue(spans);
|
|
489
|
+
return sendOtlpSuccess(reply, result.flavor);
|
|
490
|
+
});
|
|
491
|
+
app.post("/projects/:project/v1/traces", async (req, reply) => {
|
|
492
|
+
const project = req.params.project;
|
|
493
|
+
const result = await readOtlpBody(req);
|
|
494
|
+
if (!result.ok) {
|
|
495
|
+
return reply.code(result.code).send({ error: result.error });
|
|
496
|
+
}
|
|
497
|
+
const spans = parseOtlpRequest(result.body);
|
|
498
|
+
if (opts.onProjectErrorSpanSync) {
|
|
499
|
+
try {
|
|
500
|
+
for (const span of spans) {
|
|
501
|
+
if (span.statusCode === 2) await opts.onProjectErrorSpanSync(project, span);
|
|
502
|
+
}
|
|
503
|
+
} catch (err) {
|
|
504
|
+
return reply.code(500).send({
|
|
505
|
+
error: `error-event write failed: ${err.message}`
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
} else if (opts.onErrorSpanSync) {
|
|
433
509
|
try {
|
|
434
510
|
for (const span of spans) {
|
|
435
511
|
if (span.statusCode === 2) await opts.onErrorSpanSync(span);
|
|
@@ -440,17 +516,13 @@ async function buildOtelReceiver(opts) {
|
|
|
440
516
|
});
|
|
441
517
|
}
|
|
442
518
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
const buf = encodeProtobufResponseBody();
|
|
446
|
-
return reply.code(200).header("content-type", "application/x-protobuf").send(buf);
|
|
447
|
-
}
|
|
448
|
-
return reply.code(200).header("content-type", "application/json").send({ partialSuccess: {} });
|
|
519
|
+
enqueueProject(project, spans);
|
|
520
|
+
return sendOtlpSuccess(reply, result.flavor);
|
|
449
521
|
});
|
|
450
522
|
const decorated = app;
|
|
451
523
|
decorated.flushPending = async () => {
|
|
452
|
-
while (queue.length > 0 || draining) {
|
|
453
|
-
await drainPromise;
|
|
524
|
+
while (queue.length > 0 || draining || projectQueue.length > 0 || projectDraining) {
|
|
525
|
+
await Promise.all([drainPromise, projectDrainPromise]);
|
|
454
526
|
}
|
|
455
527
|
};
|
|
456
528
|
return decorated;
|
|
@@ -6484,45 +6556,31 @@ var import_node_path40 = __toESM(require("path"), 1);
|
|
|
6484
6556
|
init_cjs_shims();
|
|
6485
6557
|
var OTEL_INIT_HEADER = "// Generated by `neat init --apply` (ADR-069). OpenTelemetry auto-instrumentation hook.";
|
|
6486
6558
|
var OTEL_INIT_CJS = `${OTEL_INIT_HEADER}
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
try {
|
|
6491
|
-
require('dotenv').config({ path: path.join(__dirname, '.env.neat') })
|
|
6492
|
-
} catch (err) {
|
|
6493
|
-
// dotenv unavailable \u2014 fall through to process.env.
|
|
6494
|
-
}
|
|
6559
|
+
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
6560
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
6561
|
+
|
|
6495
6562
|
require('@opentelemetry/auto-instrumentations-node/register')
|
|
6496
6563
|
`;
|
|
6497
6564
|
var OTEL_INIT_ESM = `${OTEL_INIT_HEADER}
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
import { fileURLToPath } from 'node:url'
|
|
6501
|
-
import path from 'node:path'
|
|
6502
|
-
import dotenv from 'dotenv'
|
|
6503
|
-
|
|
6504
|
-
const here = path.dirname(fileURLToPath(import.meta.url))
|
|
6505
|
-
dotenv.config({ path: path.join(here, '.env.neat') })
|
|
6565
|
+
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
6566
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
6506
6567
|
|
|
6507
6568
|
await import('@opentelemetry/auto-instrumentations-node/register')
|
|
6508
6569
|
`;
|
|
6509
6570
|
var OTEL_INIT_TS = `${OTEL_INIT_HEADER}
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
import { fileURLToPath } from 'node:url'
|
|
6513
|
-
import path from 'node:path'
|
|
6514
|
-
import dotenv from 'dotenv'
|
|
6515
|
-
|
|
6516
|
-
const here = path.dirname(fileURLToPath(import.meta.url))
|
|
6517
|
-
dotenv.config({ path: path.join(here, '.env.neat') })
|
|
6571
|
+
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
6572
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
6518
6573
|
|
|
6519
6574
|
await import('@opentelemetry/auto-instrumentations-node/register')
|
|
6520
6575
|
`;
|
|
6521
|
-
function
|
|
6576
|
+
function renderNodeOtelInit(template, serviceName, projectName) {
|
|
6577
|
+
return template.replace(/__SERVICE_NAME__/g, serviceName).replace(/__PROJECT__/g, projectName);
|
|
6578
|
+
}
|
|
6579
|
+
function renderEnvNeat(serviceName, projectName) {
|
|
6522
6580
|
return [
|
|
6523
6581
|
"# Generated by `neat init --apply` (ADR-069).",
|
|
6524
|
-
`OTEL_SERVICE_NAME=${
|
|
6525
|
-
|
|
6582
|
+
`OTEL_SERVICE_NAME=${serviceName}`,
|
|
6583
|
+
`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/projects/${projectName}/v1/traces`,
|
|
6526
6584
|
""
|
|
6527
6585
|
].join("\n");
|
|
6528
6586
|
}
|
|
@@ -6542,54 +6600,34 @@ export async function register() {
|
|
|
6542
6600
|
}
|
|
6543
6601
|
`;
|
|
6544
6602
|
var NEXT_INSTRUMENTATION_NODE_TS = `${NEXT_INSTRUMENTATION_HEADER}
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
import path from 'node:path'
|
|
6549
|
-
import dotenv from 'dotenv'
|
|
6603
|
+
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
6604
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
6605
|
+
|
|
6550
6606
|
import { NodeSDK } from '@opentelemetry/sdk-node'
|
|
6551
6607
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
|
|
6552
6608
|
|
|
6553
|
-
|
|
6554
|
-
dotenv.config({ path: path.join(here, '.env.neat') })
|
|
6555
|
-
|
|
6556
|
-
const sdk = new NodeSDK({
|
|
6557
|
-
serviceName: process.env.OTEL_SERVICE_NAME,
|
|
6558
|
-
instrumentations: [getNodeAutoInstrumentations()],
|
|
6559
|
-
})
|
|
6560
|
-
sdk.start()
|
|
6609
|
+
new NodeSDK({ instrumentations: [getNodeAutoInstrumentations()] }).start()
|
|
6561
6610
|
`;
|
|
6562
6611
|
var NEXT_INSTRUMENTATION_NODE_JS = `${NEXT_INSTRUMENTATION_HEADER}
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
import { fileURLToPath } from 'node:url'
|
|
6566
|
-
import path from 'node:path'
|
|
6567
|
-
import dotenv from 'dotenv'
|
|
6568
|
-
import { NodeSDK } from '@opentelemetry/sdk-node'
|
|
6569
|
-
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
|
|
6612
|
+
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
6613
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
6570
6614
|
|
|
6571
|
-
const
|
|
6572
|
-
|
|
6615
|
+
const { NodeSDK } = require('@opentelemetry/sdk-node')
|
|
6616
|
+
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
|
|
6573
6617
|
|
|
6574
|
-
|
|
6575
|
-
serviceName: process.env.OTEL_SERVICE_NAME,
|
|
6576
|
-
instrumentations: [getNodeAutoInstrumentations()],
|
|
6577
|
-
})
|
|
6578
|
-
sdk.start()
|
|
6618
|
+
new NodeSDK({ instrumentations: [getNodeAutoInstrumentations()] }).start()
|
|
6579
6619
|
`;
|
|
6620
|
+
function renderNextInstrumentationNode(template, serviceName, projectName) {
|
|
6621
|
+
return template.replace(/__SERVICE_NAME__/g, serviceName).replace(/__PROJECT__/g, projectName);
|
|
6622
|
+
}
|
|
6580
6623
|
var FRAMEWORK_OTEL_INIT_HEADER = "// Generated by `neat init --apply` (ADR-074). OpenTelemetry SDK hook.";
|
|
6581
6624
|
var FRAMEWORK_OTEL_INIT_TS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
import path from 'node:path'
|
|
6586
|
-
import dotenv from 'dotenv'
|
|
6625
|
+
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
6626
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
6627
|
+
|
|
6587
6628
|
import { NodeSDK } from '@opentelemetry/sdk-node'
|
|
6588
6629
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
|
|
6589
6630
|
|
|
6590
|
-
const here = path.dirname(fileURLToPath(import.meta.url))
|
|
6591
|
-
dotenv.config({ path: path.join(here, '.env.neat') })
|
|
6592
|
-
|
|
6593
6631
|
const sdk = new NodeSDK({
|
|
6594
6632
|
serviceName: process.env.OTEL_SERVICE_NAME,
|
|
6595
6633
|
instrumentations: [getNodeAutoInstrumentations()],
|
|
@@ -6597,14 +6635,9 @@ const sdk = new NodeSDK({
|
|
|
6597
6635
|
sdk.start()
|
|
6598
6636
|
`;
|
|
6599
6637
|
var FRAMEWORK_OTEL_INIT_JS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
try {
|
|
6604
|
-
require('dotenv').config({ path: path.join(__dirname, '.env.neat') })
|
|
6605
|
-
} catch (err) {
|
|
6606
|
-
// dotenv unavailable \u2014 fall through to process.env.
|
|
6607
|
-
}
|
|
6638
|
+
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
6639
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
6640
|
+
|
|
6608
6641
|
const { NodeSDK } = require('@opentelemetry/sdk-node')
|
|
6609
6642
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
|
|
6610
6643
|
|
|
@@ -6614,6 +6647,9 @@ const sdk = new NodeSDK({
|
|
|
6614
6647
|
})
|
|
6615
6648
|
sdk.start()
|
|
6616
6649
|
`;
|
|
6650
|
+
function renderFrameworkOtelInit(template, serviceName, projectName) {
|
|
6651
|
+
return template.replace(/__SERVICE_NAME__/g, serviceName).replace(/__PROJECT__/g, projectName);
|
|
6652
|
+
}
|
|
6617
6653
|
var REMIX_OTEL_SERVER_TS = FRAMEWORK_OTEL_INIT_TS_BODY;
|
|
6618
6654
|
var REMIX_OTEL_SERVER_JS = FRAMEWORK_OTEL_INIT_JS_BODY;
|
|
6619
6655
|
var SVELTEKIT_OTEL_INIT_TS = FRAMEWORK_OTEL_INIT_TS_BODY;
|
|
@@ -6676,11 +6712,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|
|
6676
6712
|
var SDK_PACKAGES = [
|
|
6677
6713
|
{ name: "@opentelemetry/api", version: "^1.9.0" },
|
|
6678
6714
|
{ name: "@opentelemetry/sdk-node", version: "^0.57.0" },
|
|
6679
|
-
{ name: "@opentelemetry/auto-instrumentations-node", version: "^0.55.0" }
|
|
6680
|
-
// ADR-069 §5 — dotenv is the fourth dep. The generated otel-init loads
|
|
6681
|
-
// .env.neat through it so OTEL_SERVICE_NAME and the endpoint are in scope
|
|
6682
|
-
// before the auto-instrumentation hook attaches.
|
|
6683
|
-
{ name: "dotenv", version: "^16.4.5" }
|
|
6715
|
+
{ name: "@opentelemetry/auto-instrumentations-node", version: "^0.55.0" }
|
|
6684
6716
|
];
|
|
6685
6717
|
var OTEL_ENV = {
|
|
6686
6718
|
// ADR-069 §4 — endpoint moves into the per-package .env.neat (written
|
|
@@ -6688,13 +6720,36 @@ var OTEL_ENV = {
|
|
|
6688
6720
|
// patch render: it documents the key/value the user can inspect in the
|
|
6689
6721
|
// generated .env.neat.
|
|
6690
6722
|
file: null,
|
|
6691
|
-
key: "
|
|
6692
|
-
value: "http://localhost:4318"
|
|
6723
|
+
key: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
|
6724
|
+
value: "http://localhost:4318/projects/<project>/v1/traces"
|
|
6693
6725
|
};
|
|
6694
|
-
function
|
|
6726
|
+
function serviceNodeName(pkg, serviceDir) {
|
|
6727
|
+
return pkg.name ?? import_node_path40.default.basename(serviceDir);
|
|
6728
|
+
}
|
|
6729
|
+
function projectToken(pkg, serviceDir, project) {
|
|
6695
6730
|
if (project && project.length > 0) return project;
|
|
6696
6731
|
return pkg.name ?? import_node_path40.default.basename(serviceDir);
|
|
6697
6732
|
}
|
|
6733
|
+
async function readJsonFile(p) {
|
|
6734
|
+
try {
|
|
6735
|
+
const raw = await import_node_fs25.promises.readFile(p, "utf8");
|
|
6736
|
+
return JSON.parse(raw);
|
|
6737
|
+
} catch {
|
|
6738
|
+
return null;
|
|
6739
|
+
}
|
|
6740
|
+
}
|
|
6741
|
+
async function detectRuntimeKind(pkgRoot, pkg) {
|
|
6742
|
+
const deps = allDeps(pkg);
|
|
6743
|
+
if ("react-native" in deps || "expo" in deps) return "react-native";
|
|
6744
|
+
const appJson = await readJsonFile(import_node_path40.default.join(pkgRoot, "app.json"));
|
|
6745
|
+
if (appJson && typeof appJson === "object" && "expo" in appJson) {
|
|
6746
|
+
return "react-native";
|
|
6747
|
+
}
|
|
6748
|
+
if (await exists2(import_node_path40.default.join(pkgRoot, "vite.config.js")) || await exists2(import_node_path40.default.join(pkgRoot, "vite.config.ts")) || await exists2(import_node_path40.default.join(pkgRoot, "vite.config.mjs")) || "vite" in deps) {
|
|
6749
|
+
return "browser-bundle";
|
|
6750
|
+
}
|
|
6751
|
+
return "node";
|
|
6752
|
+
}
|
|
6698
6753
|
async function readPackageJson(serviceDir) {
|
|
6699
6754
|
try {
|
|
6700
6755
|
const raw = await import_node_fs25.promises.readFile(import_node_path40.default.join(serviceDir, "package.json"), "utf8");
|
|
@@ -6919,14 +6974,25 @@ function lineIsOtelInjection(line) {
|
|
|
6919
6974
|
if (trimmed.length === 0) return false;
|
|
6920
6975
|
return /(?:require\(|import\s+)['"]\.\/otel-init[^'"]*['"]/.test(trimmed);
|
|
6921
6976
|
}
|
|
6977
|
+
async function detectsSrcLayout(serviceDir) {
|
|
6978
|
+
const [hasSrcApp, hasSrcPages, hasRootApp, hasRootPages] = await Promise.all([
|
|
6979
|
+
exists2(import_node_path40.default.join(serviceDir, "src", "app")),
|
|
6980
|
+
exists2(import_node_path40.default.join(serviceDir, "src", "pages")),
|
|
6981
|
+
exists2(import_node_path40.default.join(serviceDir, "app")),
|
|
6982
|
+
exists2(import_node_path40.default.join(serviceDir, "pages"))
|
|
6983
|
+
]);
|
|
6984
|
+
return (hasSrcApp || hasSrcPages) && !hasRootApp && !hasRootPages;
|
|
6985
|
+
}
|
|
6922
6986
|
async function planNext(serviceDir, pkg, manifestPath, nextConfigPath, project) {
|
|
6923
6987
|
const useTs = await isTypeScriptProject(serviceDir);
|
|
6924
|
-
const
|
|
6988
|
+
const srcLayout = await detectsSrcLayout(serviceDir);
|
|
6989
|
+
const baseDir = srcLayout ? import_node_path40.default.join(serviceDir, "src") : serviceDir;
|
|
6990
|
+
const instrumentationFile = import_node_path40.default.join(baseDir, useTs ? "instrumentation.ts" : "instrumentation.js");
|
|
6925
6991
|
const instrumentationNodeFile = import_node_path40.default.join(
|
|
6926
|
-
|
|
6992
|
+
baseDir,
|
|
6927
6993
|
useTs ? "instrumentation.node.ts" : "instrumentation.node.js"
|
|
6928
6994
|
);
|
|
6929
|
-
const envNeatFile = import_node_path40.default.join(
|
|
6995
|
+
const envNeatFile = import_node_path40.default.join(baseDir, ".env.neat");
|
|
6930
6996
|
const existingDeps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
6931
6997
|
const dependencyEdits = [];
|
|
6932
6998
|
for (const sdk of SDK_PACKAGES) {
|
|
@@ -6938,6 +7004,8 @@ async function planNext(serviceDir, pkg, manifestPath, nextConfigPath, project)
|
|
|
6938
7004
|
version: sdk.version
|
|
6939
7005
|
});
|
|
6940
7006
|
}
|
|
7007
|
+
const svcName = serviceNodeName(pkg, serviceDir);
|
|
7008
|
+
const projectName = projectToken(pkg, serviceDir, project);
|
|
6941
7009
|
const generatedFiles = [];
|
|
6942
7010
|
if (!await exists2(instrumentationFile)) {
|
|
6943
7011
|
generatedFiles.push({
|
|
@@ -6949,14 +7017,18 @@ async function planNext(serviceDir, pkg, manifestPath, nextConfigPath, project)
|
|
|
6949
7017
|
if (!await exists2(instrumentationNodeFile)) {
|
|
6950
7018
|
generatedFiles.push({
|
|
6951
7019
|
file: instrumentationNodeFile,
|
|
6952
|
-
contents:
|
|
7020
|
+
contents: renderNextInstrumentationNode(
|
|
7021
|
+
useTs ? NEXT_INSTRUMENTATION_NODE_TS : NEXT_INSTRUMENTATION_NODE_JS,
|
|
7022
|
+
svcName,
|
|
7023
|
+
projectName
|
|
7024
|
+
),
|
|
6953
7025
|
skipIfExists: true
|
|
6954
7026
|
});
|
|
6955
7027
|
}
|
|
6956
7028
|
if (!await exists2(envNeatFile)) {
|
|
6957
7029
|
generatedFiles.push({
|
|
6958
7030
|
file: envNeatFile,
|
|
6959
|
-
contents: renderEnvNeat(
|
|
7031
|
+
contents: renderEnvNeat(svcName, projectName),
|
|
6960
7032
|
skipIfExists: true
|
|
6961
7033
|
});
|
|
6962
7034
|
}
|
|
@@ -7017,11 +7089,21 @@ async function queueEnvNeat(serviceDir, pkg, project, generatedFiles) {
|
|
|
7017
7089
|
if (!await exists2(envNeatFile)) {
|
|
7018
7090
|
generatedFiles.push({
|
|
7019
7091
|
file: envNeatFile,
|
|
7020
|
-
contents: renderEnvNeat(
|
|
7092
|
+
contents: renderEnvNeat(
|
|
7093
|
+
serviceNodeName(pkg, serviceDir),
|
|
7094
|
+
projectToken(pkg, serviceDir, project)
|
|
7095
|
+
),
|
|
7021
7096
|
skipIfExists: true
|
|
7022
7097
|
});
|
|
7023
7098
|
}
|
|
7024
7099
|
}
|
|
7100
|
+
function renderFrameworkOtelInitForPkg(template, pkg, serviceDir, project) {
|
|
7101
|
+
return renderFrameworkOtelInit(
|
|
7102
|
+
template,
|
|
7103
|
+
serviceNodeName(pkg, serviceDir),
|
|
7104
|
+
projectToken(pkg, serviceDir, project)
|
|
7105
|
+
);
|
|
7106
|
+
}
|
|
7025
7107
|
function fileImportsOtelHook(raw, specifiers) {
|
|
7026
7108
|
const lines = raw.split(/\r?\n/);
|
|
7027
7109
|
for (const line of lines) {
|
|
@@ -7047,7 +7129,12 @@ async function planRemix(serviceDir, pkg, manifestPath, entryFile, project) {
|
|
|
7047
7129
|
if (!await exists2(otelServerFile)) {
|
|
7048
7130
|
generatedFiles.push({
|
|
7049
7131
|
file: otelServerFile,
|
|
7050
|
-
contents:
|
|
7132
|
+
contents: renderFrameworkOtelInitForPkg(
|
|
7133
|
+
useTs ? REMIX_OTEL_SERVER_TS : REMIX_OTEL_SERVER_JS,
|
|
7134
|
+
pkg,
|
|
7135
|
+
serviceDir,
|
|
7136
|
+
project
|
|
7137
|
+
),
|
|
7051
7138
|
skipIfExists: true
|
|
7052
7139
|
});
|
|
7053
7140
|
}
|
|
@@ -7101,7 +7188,12 @@ async function planSvelteKit(serviceDir, pkg, manifestPath, hooksFile, project)
|
|
|
7101
7188
|
if (!await exists2(otelInitFile)) {
|
|
7102
7189
|
generatedFiles.push({
|
|
7103
7190
|
file: otelInitFile,
|
|
7104
|
-
contents:
|
|
7191
|
+
contents: renderFrameworkOtelInitForPkg(
|
|
7192
|
+
useTs ? SVELTEKIT_OTEL_INIT_TS : SVELTEKIT_OTEL_INIT_JS,
|
|
7193
|
+
pkg,
|
|
7194
|
+
serviceDir,
|
|
7195
|
+
project
|
|
7196
|
+
),
|
|
7105
7197
|
skipIfExists: true
|
|
7106
7198
|
});
|
|
7107
7199
|
}
|
|
@@ -7164,7 +7256,12 @@ async function planNuxt(serviceDir, pkg, manifestPath, project) {
|
|
|
7164
7256
|
if (!await exists2(otelInitFile)) {
|
|
7165
7257
|
generatedFiles.push({
|
|
7166
7258
|
file: otelInitFile,
|
|
7167
|
-
contents:
|
|
7259
|
+
contents: renderFrameworkOtelInitForPkg(
|
|
7260
|
+
useTs ? NUXT_OTEL_INIT_TS : NUXT_OTEL_INIT_JS,
|
|
7261
|
+
pkg,
|
|
7262
|
+
serviceDir,
|
|
7263
|
+
project
|
|
7264
|
+
),
|
|
7168
7265
|
skipIfExists: true
|
|
7169
7266
|
});
|
|
7170
7267
|
}
|
|
@@ -7220,7 +7317,12 @@ async function planAstro(serviceDir, pkg, manifestPath, project) {
|
|
|
7220
7317
|
if (!await exists2(otelInitFile)) {
|
|
7221
7318
|
generatedFiles.push({
|
|
7222
7319
|
file: otelInitFile,
|
|
7223
|
-
contents:
|
|
7320
|
+
contents: renderFrameworkOtelInitForPkg(
|
|
7321
|
+
useTs ? ASTRO_OTEL_INIT_TS : ASTRO_OTEL_INIT_JS,
|
|
7322
|
+
pkg,
|
|
7323
|
+
serviceDir,
|
|
7324
|
+
project
|
|
7325
|
+
),
|
|
7224
7326
|
skipIfExists: true
|
|
7225
7327
|
});
|
|
7226
7328
|
}
|
|
@@ -7312,6 +7414,10 @@ async function plan(serviceDir, opts) {
|
|
|
7312
7414
|
return planAstro(serviceDir, pkg, manifestPath, project);
|
|
7313
7415
|
}
|
|
7314
7416
|
}
|
|
7417
|
+
const runtimeKind = await detectRuntimeKind(serviceDir, pkg);
|
|
7418
|
+
if (runtimeKind !== "node") {
|
|
7419
|
+
return { ...empty, runtimeKind };
|
|
7420
|
+
}
|
|
7315
7421
|
const entryFile = await resolveEntry(serviceDir, pkg);
|
|
7316
7422
|
if (!entryFile) {
|
|
7317
7423
|
return { ...empty, libOnly: true };
|
|
@@ -7346,18 +7452,20 @@ async function plan(serviceDir, opts) {
|
|
|
7346
7452
|
} catch {
|
|
7347
7453
|
return { ...empty, libOnly: true };
|
|
7348
7454
|
}
|
|
7455
|
+
const svcName = serviceNodeName(pkg, serviceDir);
|
|
7456
|
+
const projectName = projectToken(pkg, serviceDir, project);
|
|
7349
7457
|
const generatedFiles = [];
|
|
7350
7458
|
if (!await exists2(otelInitFile)) {
|
|
7351
7459
|
generatedFiles.push({
|
|
7352
7460
|
file: otelInitFile,
|
|
7353
|
-
contents: otelInitContents(flavor),
|
|
7461
|
+
contents: renderNodeOtelInit(otelInitContents(flavor), svcName, projectName),
|
|
7354
7462
|
skipIfExists: true
|
|
7355
7463
|
});
|
|
7356
7464
|
}
|
|
7357
7465
|
if (!await exists2(envNeatFile)) {
|
|
7358
7466
|
generatedFiles.push({
|
|
7359
7467
|
file: envNeatFile,
|
|
7360
|
-
contents: renderEnvNeat(
|
|
7468
|
+
contents: renderEnvNeat(svcName, projectName),
|
|
7361
7469
|
skipIfExists: true
|
|
7362
7470
|
});
|
|
7363
7471
|
}
|
|
@@ -7382,9 +7490,13 @@ function isAllowedWritePath(serviceDir, target) {
|
|
|
7382
7490
|
if (base === "package.json") return true;
|
|
7383
7491
|
if (base === ".env.neat") return true;
|
|
7384
7492
|
if (/^otel-init\.(?:js|cjs|mjs|ts)$/.test(base)) return true;
|
|
7385
|
-
if (/^instrumentation(?:\.node)?\.(?:js|cjs|mjs|ts)$/.test(base)) return true;
|
|
7386
|
-
if (/^next\.config\.(?:js|mjs|ts)$/.test(base)) return true;
|
|
7387
7493
|
const relPosix = rel.split(import_node_path40.default.sep).join("/");
|
|
7494
|
+
if (/^instrumentation(?:\.node)?\.(?:js|cjs|mjs|ts)$/.test(base)) {
|
|
7495
|
+
if (relPosix === base) return true;
|
|
7496
|
+
if (relPosix === `src/${base}`) return true;
|
|
7497
|
+
return false;
|
|
7498
|
+
}
|
|
7499
|
+
if (/^next\.config\.(?:js|mjs|ts)$/.test(base)) return true;
|
|
7388
7500
|
if (relPosix === "app/otel.server.ts" || relPosix === "app/otel.server.js") return true;
|
|
7389
7501
|
if (/^app\/entry\.server\.(?:tsx?|jsx?)$/.test(relPosix)) return true;
|
|
7390
7502
|
if (relPosix === "src/otel-init.ts" || relPosix === "src/otel-init.js") return true;
|
|
@@ -7410,6 +7522,22 @@ async function apply(installPlan) {
|
|
|
7410
7522
|
writtenFiles: []
|
|
7411
7523
|
};
|
|
7412
7524
|
}
|
|
7525
|
+
if (installPlan.runtimeKind === "browser-bundle") {
|
|
7526
|
+
return {
|
|
7527
|
+
serviceDir,
|
|
7528
|
+
outcome: "browser-bundle",
|
|
7529
|
+
reason: "browser bundle; Node OTel SDK cannot run here",
|
|
7530
|
+
writtenFiles: []
|
|
7531
|
+
};
|
|
7532
|
+
}
|
|
7533
|
+
if (installPlan.runtimeKind === "react-native") {
|
|
7534
|
+
return {
|
|
7535
|
+
serviceDir,
|
|
7536
|
+
outcome: "react-native",
|
|
7537
|
+
reason: "React Native / Expo target; Node OTel SDK cannot run here",
|
|
7538
|
+
writtenFiles: []
|
|
7539
|
+
};
|
|
7540
|
+
}
|
|
7413
7541
|
if (installPlan.dependencyEdits.length === 0 && installPlan.entrypointEdits.length === 0 && (installPlan.generatedFiles?.length ?? 0) === 0 && installPlan.nextConfigEdit === void 0) {
|
|
7414
7542
|
return {
|
|
7415
7543
|
serviceDir,
|
|
@@ -7896,11 +8024,13 @@ async function applyInstallersOver(services, project) {
|
|
|
7896
8024
|
let instrumented = 0;
|
|
7897
8025
|
let already = 0;
|
|
7898
8026
|
let libOnly = 0;
|
|
8027
|
+
let browserBundle = 0;
|
|
8028
|
+
let reactNative = 0;
|
|
7899
8029
|
for (const svc of services) {
|
|
7900
8030
|
const installer = await pickInstaller(svc.dir);
|
|
7901
8031
|
if (!installer) continue;
|
|
7902
8032
|
const plan3 = await installer.plan(svc.dir, { project });
|
|
7903
|
-
if (isEmptyPlan(plan3) && !plan3.libOnly) {
|
|
8033
|
+
if (isEmptyPlan(plan3) && !plan3.libOnly && plan3.runtimeKind === void 0) {
|
|
7904
8034
|
already++;
|
|
7905
8035
|
continue;
|
|
7906
8036
|
}
|
|
@@ -7908,8 +8038,15 @@ async function applyInstallersOver(services, project) {
|
|
|
7908
8038
|
if (outcome.outcome === "instrumented") instrumented++;
|
|
7909
8039
|
else if (outcome.outcome === "already-instrumented") already++;
|
|
7910
8040
|
else if (outcome.outcome === "lib-only") libOnly++;
|
|
8041
|
+
else if (outcome.outcome === "browser-bundle") {
|
|
8042
|
+
browserBundle++;
|
|
8043
|
+
console.log(`skipping ${svc.dir}: browser bundle; browser-OTel support lands in a future release.`);
|
|
8044
|
+
} else if (outcome.outcome === "react-native") {
|
|
8045
|
+
reactNative++;
|
|
8046
|
+
console.log(`skipping ${svc.dir}: React Native target; browser-OTel support lands in a future release.`);
|
|
8047
|
+
}
|
|
7911
8048
|
}
|
|
7912
|
-
return { instrumented, alreadyInstrumented: already, libOnly };
|
|
8049
|
+
return { instrumented, alreadyInstrumented: already, libOnly, browserBundle, reactNative };
|
|
7913
8050
|
}
|
|
7914
8051
|
async function promptYesNo(question) {
|
|
7915
8052
|
const rl = import_node_readline.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -8113,13 +8250,15 @@ async function runOrchestrator(opts) {
|
|
|
8113
8250
|
if (gi.action !== "unchanged") {
|
|
8114
8251
|
console.log(`${gi.action} .gitignore (neat-out/)`);
|
|
8115
8252
|
}
|
|
8253
|
+
let currentProjectName = opts.project;
|
|
8116
8254
|
try {
|
|
8117
|
-
await addProject({
|
|
8255
|
+
const entry2 = await addProject({
|
|
8118
8256
|
name: opts.project,
|
|
8119
8257
|
path: opts.scanPath,
|
|
8120
8258
|
languages,
|
|
8121
8259
|
status: "active"
|
|
8122
8260
|
});
|
|
8261
|
+
currentProjectName = entry2.name;
|
|
8123
8262
|
} catch (err) {
|
|
8124
8263
|
if (!(err instanceof ProjectNameCollisionError)) throw err;
|
|
8125
8264
|
console.error(`neat: ${err.message}`);
|
|
@@ -8127,6 +8266,20 @@ async function runOrchestrator(opts) {
|
|
|
8127
8266
|
result.exitCode = 1;
|
|
8128
8267
|
return result;
|
|
8129
8268
|
}
|
|
8269
|
+
const siblings = await listProjects();
|
|
8270
|
+
const paused = [];
|
|
8271
|
+
for (const p of siblings) {
|
|
8272
|
+
if (p.name !== currentProjectName && p.status === "active") {
|
|
8273
|
+
await setStatus(p.name, "paused");
|
|
8274
|
+
paused.push(p.name);
|
|
8275
|
+
}
|
|
8276
|
+
}
|
|
8277
|
+
if (paused.length > 0) {
|
|
8278
|
+
const plural = paused.length === 1 ? "" : "s";
|
|
8279
|
+
console.log(
|
|
8280
|
+
`neat: paused ${paused.length} sibling project${plural}; run \`neat resume <name>\` to bring one back active.`
|
|
8281
|
+
);
|
|
8282
|
+
}
|
|
8130
8283
|
if (!runApply) {
|
|
8131
8284
|
result.steps.apply.skipped = true;
|
|
8132
8285
|
console.log("skipped instrumentation (--no-instrument)");
|
|
@@ -8799,7 +8952,7 @@ async function runSync(opts) {
|
|
|
8799
8952
|
snapshotPath = target;
|
|
8800
8953
|
}
|
|
8801
8954
|
const skipApply = opts.dryRun || opts.noInstrument;
|
|
8802
|
-
const applyTally = skipApply ? { instrumented: 0, alreadyInstrumented: 0, libOnly: 0 } : await applyInstallersOver(persisted.services, entry2.name);
|
|
8955
|
+
const applyTally = skipApply ? { instrumented: 0, alreadyInstrumented: 0, libOnly: 0, browserBundle: 0, reactNative: 0 } : await applyInstallersOver(persisted.services, entry2.name);
|
|
8803
8956
|
const warnings = [];
|
|
8804
8957
|
let daemonState = "skipped";
|
|
8805
8958
|
let exitCode = 0;
|
|
@@ -9147,7 +9300,7 @@ async function buildPatchSections(services, project) {
|
|
|
9147
9300
|
const installer = await pickInstaller(svc.dir);
|
|
9148
9301
|
if (!installer) continue;
|
|
9149
9302
|
const plan3 = await installer.plan(svc.dir, { project });
|
|
9150
|
-
if (isEmptyPlan(plan3) && !plan3.libOnly) continue;
|
|
9303
|
+
if (isEmptyPlan(plan3) && !plan3.libOnly && plan3.runtimeKind === void 0) continue;
|
|
9151
9304
|
sections.push({ installer: installer.name, plan: plan3 });
|
|
9152
9305
|
}
|
|
9153
9306
|
return sections;
|
|
@@ -9191,13 +9344,15 @@ async function runInit(opts) {
|
|
|
9191
9344
|
written.push(gitignoreResult.file);
|
|
9192
9345
|
}
|
|
9193
9346
|
const languages = [...new Set(services.map((s) => s.node.language))].sort();
|
|
9347
|
+
let currentProjectName = opts.project;
|
|
9194
9348
|
try {
|
|
9195
|
-
await addProject({
|
|
9349
|
+
const entry2 = await addProject({
|
|
9196
9350
|
name: opts.project,
|
|
9197
9351
|
path: opts.scanPath,
|
|
9198
9352
|
languages,
|
|
9199
9353
|
status: "active"
|
|
9200
9354
|
});
|
|
9355
|
+
currentProjectName = entry2.name;
|
|
9201
9356
|
} catch (err) {
|
|
9202
9357
|
if (err instanceof ProjectNameCollisionError) {
|
|
9203
9358
|
console.error(`neat init: ${err.message}`);
|
|
@@ -9206,11 +9361,27 @@ async function runInit(opts) {
|
|
|
9206
9361
|
}
|
|
9207
9362
|
throw err;
|
|
9208
9363
|
}
|
|
9364
|
+
const siblings = await listProjects();
|
|
9365
|
+
const paused = [];
|
|
9366
|
+
for (const p of siblings) {
|
|
9367
|
+
if (p.name !== currentProjectName && p.status === "active") {
|
|
9368
|
+
await setStatus(p.name, "paused");
|
|
9369
|
+
paused.push(p.name);
|
|
9370
|
+
}
|
|
9371
|
+
}
|
|
9372
|
+
if (paused.length > 0) {
|
|
9373
|
+
const plural = paused.length === 1 ? "" : "s";
|
|
9374
|
+
console.log(
|
|
9375
|
+
`neat: paused ${paused.length} sibling project${plural}; run \`neat resume <name>\` to bring one back active.`
|
|
9376
|
+
);
|
|
9377
|
+
}
|
|
9209
9378
|
if (!opts.noInstall) {
|
|
9210
9379
|
if (opts.apply) {
|
|
9211
9380
|
let instrumented = 0;
|
|
9212
9381
|
let alreadyInstrumented = 0;
|
|
9213
9382
|
let libOnly = 0;
|
|
9383
|
+
let browserBundle = 0;
|
|
9384
|
+
let reactNative = 0;
|
|
9214
9385
|
for (const section of sections) {
|
|
9215
9386
|
const installer = INSTALLERS.find((i) => i.name === section.installer);
|
|
9216
9387
|
if (!installer) continue;
|
|
@@ -9222,13 +9393,24 @@ async function runInit(opts) {
|
|
|
9222
9393
|
alreadyInstrumented++;
|
|
9223
9394
|
} else if (outcome.outcome === "lib-only") {
|
|
9224
9395
|
libOnly++;
|
|
9396
|
+
} else if (outcome.outcome === "browser-bundle") {
|
|
9397
|
+
browserBundle++;
|
|
9398
|
+
console.log(`skipping ${section.plan.serviceDir}: browser bundle; browser-OTel support lands in a future release.`);
|
|
9399
|
+
} else if (outcome.outcome === "react-native") {
|
|
9400
|
+
reactNative++;
|
|
9401
|
+
console.log(`skipping ${section.plan.serviceDir}: React Native target; browser-OTel support lands in a future release.`);
|
|
9225
9402
|
}
|
|
9226
9403
|
}
|
|
9227
9404
|
if (sections.length > 0) {
|
|
9228
9405
|
console.log("");
|
|
9229
|
-
|
|
9230
|
-
`
|
|
9231
|
-
|
|
9406
|
+
const parts = [
|
|
9407
|
+
`instrumented ${instrumented}`,
|
|
9408
|
+
`already-instrumented ${alreadyInstrumented}`,
|
|
9409
|
+
`lib-only ${libOnly}`
|
|
9410
|
+
];
|
|
9411
|
+
if (browserBundle > 0) parts.push(`browser-bundle ${browserBundle}`);
|
|
9412
|
+
if (reactNative > 0) parts.push(`react-native ${reactNative}`);
|
|
9413
|
+
console.log(`apply: ${parts.join(", ")}`);
|
|
9232
9414
|
console.log("Run `npm install` (or your language equivalent) to refresh lockfiles.");
|
|
9233
9415
|
}
|
|
9234
9416
|
} else {
|
|
@@ -9718,7 +9900,7 @@ async function runQueryVerb(cmd, parsed) {
|
|
|
9718
9900
|
}
|
|
9719
9901
|
}
|
|
9720
9902
|
var entry = process.argv[1] ?? "";
|
|
9721
|
-
if (/[\\/]cli\.(?:cjs|js)$/.test(entry) || entry.endsWith("/cli") || entry.endsWith("/neat")) {
|
|
9903
|
+
if (/[\\/]cli\.(?:cjs|js)$/.test(entry) || entry.endsWith("/cli") || entry.endsWith("/neat") || entry.endsWith("/neat.is")) {
|
|
9722
9904
|
main().catch((err) => {
|
|
9723
9905
|
console.error(err);
|
|
9724
9906
|
process.exit(1);
|