@autter/runtime-node 1.9.1 → 1.10.0
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/README.md +30 -6
- package/dist/chunk-3UODRQBD.js +878 -0
- package/dist/chunk-HBH64LWQ.cjs +878 -0
- package/dist/{chunk-VIP2EL47.js → chunk-KWAJIELR.js} +304 -201
- package/dist/{chunk-3P573RHA.cjs → chunk-S6WJ5YLP.cjs} +304 -201
- package/dist/{chunk-FV64SIRQ.cjs → chunk-STOXJZ7Z.cjs} +21 -10
- package/dist/{chunk-D3PJ7TQ4.js → chunk-V65UY6LU.js} +13 -2
- package/dist/cli.cjs +36 -9
- package/dist/cli.js +32 -5
- package/dist/index.cjs +622 -281
- package/dist/index.d.cts +152 -11
- package/dist/index.d.ts +152 -11
- package/dist/index.js +403 -62
- package/dist/testing.cjs +8 -8
- package/dist/testing.js +2 -2
- package/package.json +2 -1
- package/dist/chunk-FYMEBULO.js +0 -203
- package/dist/chunk-LYXQC4FI.cjs +0 -203
package/dist/testing.cjs
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
require('./chunk-
|
|
5
|
+
var _chunkSTOXJZ7Zcjs = require('./chunk-STOXJZ7Z.cjs');
|
|
6
|
+
require('./chunk-S6WJ5YLP.cjs');
|
|
7
7
|
|
|
8
8
|
// src/testing.ts
|
|
9
9
|
function captureRuntime() {
|
|
10
|
-
const sink =
|
|
11
|
-
const remove =
|
|
10
|
+
const sink = _chunkSTOXJZ7Zcjs.memorySink.call(void 0, );
|
|
11
|
+
const remove = _chunkSTOXJZ7Zcjs.addRuntimeSink.call(void 0, sink);
|
|
12
12
|
return {
|
|
13
13
|
get events() {
|
|
14
14
|
return [...sink.events];
|
|
15
15
|
},
|
|
16
16
|
get operations() {
|
|
17
|
-
return sink.events.filter(
|
|
17
|
+
return sink.events.filter(_chunkSTOXJZ7Zcjs.isSummary);
|
|
18
18
|
},
|
|
19
19
|
get logs() {
|
|
20
|
-
return sink.events.filter((event) => !
|
|
20
|
+
return sink.events.filter((event) => !_chunkSTOXJZ7Zcjs.isSummary.call(void 0, event));
|
|
21
21
|
},
|
|
22
22
|
get exceptions() {
|
|
23
23
|
return [...sink.exceptions];
|
|
@@ -98,7 +98,7 @@ var OperationExpectation = class {
|
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
100
|
function expectOperation(source, name) {
|
|
101
|
-
const events = Array.isArray(source) ? source.filter(
|
|
101
|
+
const events = Array.isArray(source) ? source.filter(_chunkSTOXJZ7Zcjs.isSummary) : source.operations;
|
|
102
102
|
const matches = events.filter((event2) => {
|
|
103
103
|
const actual = String(_nullishCoalesce(event2.attributes["autter.operation.name"], () => ( "")));
|
|
104
104
|
return typeof name === "string" ? actual === name : name.test(actual);
|
|
@@ -118,4 +118,4 @@ function expectOperation(source, name) {
|
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
|
|
121
|
-
exports.captureRuntime = captureRuntime; exports.expectOperation = expectOperation; exports.memorySink =
|
|
121
|
+
exports.captureRuntime = captureRuntime; exports.expectOperation = expectOperation; exports.memorySink = _chunkSTOXJZ7Zcjs.memorySink;
|
package/dist/testing.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autter/runtime-node",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Autter Runtime for Node.js: request wide events, coded errors, operation logging, same-origin browser relay and a curated OpenTelemetry server tracker",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"@types/node": "^22.10.0",
|
|
54
54
|
"bunyan": "^1.8.15",
|
|
55
55
|
"express": "^4.21.2",
|
|
56
|
+
"express5": "npm:express@^5.3.0",
|
|
56
57
|
"fastify": "^5.12.5",
|
|
57
58
|
"koa": "^3.2.1",
|
|
58
59
|
"pino": "^10.4.0",
|
package/dist/chunk-FYMEBULO.js
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
COMPAT_MANIFEST,
|
|
3
|
-
SDK_IDENTITY,
|
|
4
|
-
compatRequest,
|
|
5
|
-
evaluateCompat,
|
|
6
|
-
fetchIngesterCompat,
|
|
7
|
-
versionAtLeast
|
|
8
|
-
} from "./chunk-VIP2EL47.js";
|
|
9
|
-
|
|
10
|
-
// src/doctor.ts
|
|
11
|
-
import { existsSync, readFileSync } from "fs";
|
|
12
|
-
import { dirname, join } from "path";
|
|
13
|
-
var SDK_PACKAGES = ["@autter/runtime-node", "@autter/runtime-next", "@autter/runtime-browser"];
|
|
14
|
-
var DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
15
|
-
function resolveEndpoint(flag, env = process.env) {
|
|
16
|
-
return (flag || env.AUTTER_ENDPOINT || env.AUTTER_RUNTIME_ENDPOINT || env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_ENDPOINT).replace(/\/$/, "");
|
|
17
|
-
}
|
|
18
|
-
function installedSdks(cwd) {
|
|
19
|
-
const found = /* @__PURE__ */ new Map();
|
|
20
|
-
for (let dir = cwd; ; dir = dirname(dir)) {
|
|
21
|
-
for (const name of SDK_PACKAGES) {
|
|
22
|
-
if (found.has(name)) continue;
|
|
23
|
-
const file = join(dir, "node_modules", ...name.split("/"), "package.json");
|
|
24
|
-
if (!existsSync(file)) continue;
|
|
25
|
-
try {
|
|
26
|
-
const version = JSON.parse(readFileSync(file, "utf8")).version;
|
|
27
|
-
if (typeof version === "string") found.set(name, version);
|
|
28
|
-
} catch {
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
if (dirname(dir) === dir) break;
|
|
32
|
-
}
|
|
33
|
-
if (!found.has(SDK_IDENTITY.name)) found.set(SDK_IDENTITY.name, SDK_IDENTITY.version);
|
|
34
|
-
return [...found].map(([name, version]) => ({ name, version }));
|
|
35
|
-
}
|
|
36
|
-
function featuresInUse(sdks) {
|
|
37
|
-
return COMPAT_MANIFEST.features.filter(
|
|
38
|
-
(feature) => sdks.some((sdk) => {
|
|
39
|
-
const min = feature.sdks[sdk.name];
|
|
40
|
-
return min !== void 0 && versionAtLeast(sdk.version, min) === true;
|
|
41
|
-
})
|
|
42
|
-
).map((feature) => feature.id);
|
|
43
|
-
}
|
|
44
|
-
async function checkKey(endpoint, key, timeoutMs) {
|
|
45
|
-
const res = await compatRequest("POST", `${endpoint}/v1/traces`, {
|
|
46
|
-
body: JSON.stringify({ resourceSpans: [] }),
|
|
47
|
-
headers: { authorization: `Bearer ${key}` },
|
|
48
|
-
unref: false,
|
|
49
|
-
timeoutMs
|
|
50
|
-
});
|
|
51
|
-
if (!res) return "unknown";
|
|
52
|
-
if (res.status >= 200 && res.status < 300) return "accepted";
|
|
53
|
-
if (res.status === 401) return "rejected";
|
|
54
|
-
if (res.status === 403) return "client_key";
|
|
55
|
-
if (res.status === 503) return res.headers["retry-after"] ? "unverified" : "storage_unavailable";
|
|
56
|
-
return "unknown";
|
|
57
|
-
}
|
|
58
|
-
async function runDoctor(options = {}) {
|
|
59
|
-
const endpoint = resolveEndpoint(options.endpoint);
|
|
60
|
-
const timeoutMs = options.timeoutMs ?? 5e3;
|
|
61
|
-
const sdks = installedSdks(options.cwd ?? process.cwd());
|
|
62
|
-
const features = options.features?.length ? options.features : featuresInUse(sdks);
|
|
63
|
-
const routes = [
|
|
64
|
-
...new Set(
|
|
65
|
-
features.map((id) => COMPAT_MANIFEST.features.find((f) => f.id === id)?.route).filter((route) => Boolean(route))
|
|
66
|
-
)
|
|
67
|
-
];
|
|
68
|
-
const { info, error } = await fetchIngesterCompat(endpoint, { probeRoutes: routes, unref: false, timeoutMs });
|
|
69
|
-
const issues = [];
|
|
70
|
-
const seen = /* @__PURE__ */ new Set();
|
|
71
|
-
const add = (issue) => {
|
|
72
|
-
const key2 = `${issue.feature}:${issue.kind}:${issue.component}`;
|
|
73
|
-
if (!seen.has(key2)) {
|
|
74
|
-
seen.add(key2);
|
|
75
|
-
issues.push(issue);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
evaluateCompat({ features, ingester: info }).forEach(add);
|
|
79
|
-
for (const sdk of sdks) {
|
|
80
|
-
if (options.features?.length) {
|
|
81
|
-
evaluateCompat({ features: options.features, ingester: null, sdk }).forEach(add);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
const key = options.key ? await checkKey(endpoint, options.key, timeoutMs) : void 0;
|
|
85
|
-
const featureRows = features.flatMap((id) => {
|
|
86
|
-
const feature = COMPAT_MANIFEST.features.find((f) => f.id === id);
|
|
87
|
-
if (!feature) return [];
|
|
88
|
-
const bad = issues.some((issue) => issue.feature === id);
|
|
89
|
-
const known = info?.version != null || feature.route !== void 0 && info?.routes?.[feature.route] !== void 0;
|
|
90
|
-
return [{ id, title: feature.title, status: bad ? "incompatible" : known ? "ok" : "unknown" }];
|
|
91
|
-
});
|
|
92
|
-
const exitCode = !info ? 2 : issues.length || key === "rejected" || key === "client_key" || key === "storage_unavailable" || key === "unverified" ? 1 : 0;
|
|
93
|
-
return {
|
|
94
|
-
endpoint,
|
|
95
|
-
sdks,
|
|
96
|
-
ingester: info,
|
|
97
|
-
...error && !info ? { ingesterError: error } : {},
|
|
98
|
-
...key ? { key } : {},
|
|
99
|
-
features: featureRows,
|
|
100
|
-
issues,
|
|
101
|
-
exitCode
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
function formatDoctorReport(report) {
|
|
105
|
-
const lines = [];
|
|
106
|
-
lines.push(`Autter Runtime doctor`);
|
|
107
|
-
lines.push(` endpoint ${report.endpoint}`);
|
|
108
|
-
for (const sdk of report.sdks) lines.push(` sdk ${sdk.name}@${sdk.version}`);
|
|
109
|
-
if (!report.ingester) {
|
|
110
|
-
lines.push(` ingester unreachable or unidentified (${report.ingesterError ?? "unknown error"})`);
|
|
111
|
-
} else if (report.ingester.version) {
|
|
112
|
-
lines.push(` ingester @autter/otlp-ingester@${report.ingester.version}`);
|
|
113
|
-
const schema = report.ingester.schema;
|
|
114
|
-
if (schema) {
|
|
115
|
-
lines.push(
|
|
116
|
-
` schema ${schema.status}${schema.applied.length ? ` (level ${schema.applied[schema.applied.length - 1]})` : ""}`
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
lines.push(` ingester 1.4.0 or older (no /v1/compat endpoint; upgrade for a full report)`);
|
|
121
|
-
}
|
|
122
|
-
if (report.key) {
|
|
123
|
-
const text = {
|
|
124
|
-
accepted: "accepted",
|
|
125
|
-
rejected: "REJECTED (401): check AUTTER_RUNTIME_KEY",
|
|
126
|
-
client_key: "is a client/browser key; server SDKs need a server key",
|
|
127
|
-
storage_unavailable: "accepted, but the ingester's ClickHouse is unavailable (503)",
|
|
128
|
-
unverified: "could not be checked: the ingester's key validator is unavailable (503); exporters retry",
|
|
129
|
-
unknown: "could not be verified"
|
|
130
|
-
}[report.key];
|
|
131
|
-
lines.push(` key ${text}`);
|
|
132
|
-
}
|
|
133
|
-
if (report.features.length) {
|
|
134
|
-
lines.push("", "Features");
|
|
135
|
-
for (const feature of report.features) {
|
|
136
|
-
const mark = feature.status === "ok" ? "ok " : feature.status === "incompatible" ? "FAIL" : "?? ";
|
|
137
|
-
lines.push(` ${mark} ${feature.title} (${feature.id})`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (report.issues.length) {
|
|
141
|
-
lines.push("", "Problems");
|
|
142
|
-
for (const issue of report.issues) lines.push(` - ${issue.message}`);
|
|
143
|
-
}
|
|
144
|
-
lines.push(
|
|
145
|
-
"",
|
|
146
|
-
report.exitCode === 0 ? "Compatible." : report.exitCode === 1 ? "Incompatible: see the problems above." : "Could not check the ingester. Pass --endpoint <url> (or set AUTTER_ENDPOINT)."
|
|
147
|
-
);
|
|
148
|
-
return lines.join("\n");
|
|
149
|
-
}
|
|
150
|
-
var DOCTOR_USAGE = `Usage: npx @autter/runtime-node doctor [options]
|
|
151
|
-
|
|
152
|
-
Checks that your Autter SDKs, ingester and ClickHouse schema versions match.
|
|
153
|
-
|
|
154
|
-
Options:
|
|
155
|
-
--endpoint <url> Ingester base URL (default: $AUTTER_ENDPOINT, $OTEL_EXPORTER_OTLP_ENDPOINT, or ${DEFAULT_ENDPOINT})
|
|
156
|
-
--key <key> Also verify an ingest key (default: $AUTTER_RUNTIME_KEY)
|
|
157
|
-
--features <a,b> Only check these features (${COMPAT_MANIFEST.features.map((f) => f.id).join(", ")})
|
|
158
|
-
--json Machine-readable output
|
|
159
|
-
--timeout <ms> Per-request timeout (default 5000)
|
|
160
|
-
|
|
161
|
-
Exit codes: 0 compatible, 1 mismatch or rejected key, 2 ingester unreachable.`;
|
|
162
|
-
function parseDoctorArgs(argv, env = process.env) {
|
|
163
|
-
const options = {};
|
|
164
|
-
for (let i = 0; i < argv.length; i++) {
|
|
165
|
-
const arg = argv[i];
|
|
166
|
-
const [flag, inline] = arg.includes("=") ? [arg.slice(0, arg.indexOf("=")), arg.slice(arg.indexOf("=") + 1)] : [arg, void 0];
|
|
167
|
-
const value = () => inline ?? argv[++i];
|
|
168
|
-
switch (flag) {
|
|
169
|
-
case "-h":
|
|
170
|
-
case "--help":
|
|
171
|
-
return { help: true };
|
|
172
|
-
case "--endpoint":
|
|
173
|
-
options.endpoint = value();
|
|
174
|
-
break;
|
|
175
|
-
case "--key":
|
|
176
|
-
options.key = value();
|
|
177
|
-
break;
|
|
178
|
-
case "--features":
|
|
179
|
-
options.features = (value() ?? "").split(",").map((f) => f.trim()).filter(Boolean);
|
|
180
|
-
break;
|
|
181
|
-
case "--json":
|
|
182
|
-
options.json = true;
|
|
183
|
-
break;
|
|
184
|
-
case "--timeout": {
|
|
185
|
-
const ms = Number(value());
|
|
186
|
-
if (!Number.isFinite(ms) || ms <= 0) return { error: "--timeout needs a positive number of ms" };
|
|
187
|
-
options.timeoutMs = ms;
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
default:
|
|
191
|
-
return { error: `unknown option ${arg}` };
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (!options.key && env.AUTTER_RUNTIME_KEY) options.key = env.AUTTER_RUNTIME_KEY;
|
|
195
|
-
return options;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export {
|
|
199
|
-
runDoctor,
|
|
200
|
-
formatDoctorReport,
|
|
201
|
-
DOCTOR_USAGE,
|
|
202
|
-
parseDoctorArgs
|
|
203
|
-
};
|
package/dist/chunk-LYXQC4FI.cjs
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var _chunk3P573RHAcjs = require('./chunk-3P573RHA.cjs');
|
|
9
|
-
|
|
10
|
-
// src/doctor.ts
|
|
11
|
-
var _fs = require('fs');
|
|
12
|
-
var _path = require('path');
|
|
13
|
-
var SDK_PACKAGES = ["@autter/runtime-node", "@autter/runtime-next", "@autter/runtime-browser"];
|
|
14
|
-
var DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
15
|
-
function resolveEndpoint(flag, env = process.env) {
|
|
16
|
-
return (flag || env.AUTTER_ENDPOINT || env.AUTTER_RUNTIME_ENDPOINT || env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_ENDPOINT).replace(/\/$/, "");
|
|
17
|
-
}
|
|
18
|
-
function installedSdks(cwd) {
|
|
19
|
-
const found = /* @__PURE__ */ new Map();
|
|
20
|
-
for (let dir = cwd; ; dir = _path.dirname.call(void 0, dir)) {
|
|
21
|
-
for (const name of SDK_PACKAGES) {
|
|
22
|
-
if (found.has(name)) continue;
|
|
23
|
-
const file = _path.join.call(void 0, dir, "node_modules", ...name.split("/"), "package.json");
|
|
24
|
-
if (!_fs.existsSync.call(void 0, file)) continue;
|
|
25
|
-
try {
|
|
26
|
-
const version = JSON.parse(_fs.readFileSync.call(void 0, file, "utf8")).version;
|
|
27
|
-
if (typeof version === "string") found.set(name, version);
|
|
28
|
-
} catch (e) {
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
if (_path.dirname.call(void 0, dir) === dir) break;
|
|
32
|
-
}
|
|
33
|
-
if (!found.has(_chunk3P573RHAcjs.SDK_IDENTITY.name)) found.set(_chunk3P573RHAcjs.SDK_IDENTITY.name, _chunk3P573RHAcjs.SDK_IDENTITY.version);
|
|
34
|
-
return [...found].map(([name, version]) => ({ name, version }));
|
|
35
|
-
}
|
|
36
|
-
function featuresInUse(sdks) {
|
|
37
|
-
return _chunk3P573RHAcjs.COMPAT_MANIFEST.features.filter(
|
|
38
|
-
(feature) => sdks.some((sdk) => {
|
|
39
|
-
const min = feature.sdks[sdk.name];
|
|
40
|
-
return min !== void 0 && _chunk3P573RHAcjs.versionAtLeast.call(void 0, sdk.version, min) === true;
|
|
41
|
-
})
|
|
42
|
-
).map((feature) => feature.id);
|
|
43
|
-
}
|
|
44
|
-
async function checkKey(endpoint, key, timeoutMs) {
|
|
45
|
-
const res = await _chunk3P573RHAcjs.compatRequest.call(void 0, "POST", `${endpoint}/v1/traces`, {
|
|
46
|
-
body: JSON.stringify({ resourceSpans: [] }),
|
|
47
|
-
headers: { authorization: `Bearer ${key}` },
|
|
48
|
-
unref: false,
|
|
49
|
-
timeoutMs
|
|
50
|
-
});
|
|
51
|
-
if (!res) return "unknown";
|
|
52
|
-
if (res.status >= 200 && res.status < 300) return "accepted";
|
|
53
|
-
if (res.status === 401) return "rejected";
|
|
54
|
-
if (res.status === 403) return "client_key";
|
|
55
|
-
if (res.status === 503) return res.headers["retry-after"] ? "unverified" : "storage_unavailable";
|
|
56
|
-
return "unknown";
|
|
57
|
-
}
|
|
58
|
-
async function runDoctor(options = {}) {
|
|
59
|
-
const endpoint = resolveEndpoint(options.endpoint);
|
|
60
|
-
const timeoutMs = _nullishCoalesce(options.timeoutMs, () => ( 5e3));
|
|
61
|
-
const sdks = installedSdks(_nullishCoalesce(options.cwd, () => ( process.cwd())));
|
|
62
|
-
const features = _optionalChain([options, 'access', _ => _.features, 'optionalAccess', _2 => _2.length]) ? options.features : featuresInUse(sdks);
|
|
63
|
-
const routes = [
|
|
64
|
-
...new Set(
|
|
65
|
-
features.map((id) => _optionalChain([_chunk3P573RHAcjs.COMPAT_MANIFEST, 'access', _3 => _3.features, 'access', _4 => _4.find, 'call', _5 => _5((f) => f.id === id), 'optionalAccess', _6 => _6.route])).filter((route) => Boolean(route))
|
|
66
|
-
)
|
|
67
|
-
];
|
|
68
|
-
const { info, error } = await _chunk3P573RHAcjs.fetchIngesterCompat.call(void 0, endpoint, { probeRoutes: routes, unref: false, timeoutMs });
|
|
69
|
-
const issues = [];
|
|
70
|
-
const seen = /* @__PURE__ */ new Set();
|
|
71
|
-
const add = (issue) => {
|
|
72
|
-
const key2 = `${issue.feature}:${issue.kind}:${issue.component}`;
|
|
73
|
-
if (!seen.has(key2)) {
|
|
74
|
-
seen.add(key2);
|
|
75
|
-
issues.push(issue);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
_chunk3P573RHAcjs.evaluateCompat.call(void 0, { features, ingester: info }).forEach(add);
|
|
79
|
-
for (const sdk of sdks) {
|
|
80
|
-
if (_optionalChain([options, 'access', _7 => _7.features, 'optionalAccess', _8 => _8.length])) {
|
|
81
|
-
_chunk3P573RHAcjs.evaluateCompat.call(void 0, { features: options.features, ingester: null, sdk }).forEach(add);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
const key = options.key ? await checkKey(endpoint, options.key, timeoutMs) : void 0;
|
|
85
|
-
const featureRows = features.flatMap((id) => {
|
|
86
|
-
const feature = _chunk3P573RHAcjs.COMPAT_MANIFEST.features.find((f) => f.id === id);
|
|
87
|
-
if (!feature) return [];
|
|
88
|
-
const bad = issues.some((issue) => issue.feature === id);
|
|
89
|
-
const known = _optionalChain([info, 'optionalAccess', _9 => _9.version]) != null || feature.route !== void 0 && _optionalChain([info, 'optionalAccess', _10 => _10.routes, 'optionalAccess', _11 => _11[feature.route]]) !== void 0;
|
|
90
|
-
return [{ id, title: feature.title, status: bad ? "incompatible" : known ? "ok" : "unknown" }];
|
|
91
|
-
});
|
|
92
|
-
const exitCode = !info ? 2 : issues.length || key === "rejected" || key === "client_key" || key === "storage_unavailable" || key === "unverified" ? 1 : 0;
|
|
93
|
-
return {
|
|
94
|
-
endpoint,
|
|
95
|
-
sdks,
|
|
96
|
-
ingester: info,
|
|
97
|
-
...error && !info ? { ingesterError: error } : {},
|
|
98
|
-
...key ? { key } : {},
|
|
99
|
-
features: featureRows,
|
|
100
|
-
issues,
|
|
101
|
-
exitCode
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
function formatDoctorReport(report) {
|
|
105
|
-
const lines = [];
|
|
106
|
-
lines.push(`Autter Runtime doctor`);
|
|
107
|
-
lines.push(` endpoint ${report.endpoint}`);
|
|
108
|
-
for (const sdk of report.sdks) lines.push(` sdk ${sdk.name}@${sdk.version}`);
|
|
109
|
-
if (!report.ingester) {
|
|
110
|
-
lines.push(` ingester unreachable or unidentified (${_nullishCoalesce(report.ingesterError, () => ( "unknown error"))})`);
|
|
111
|
-
} else if (report.ingester.version) {
|
|
112
|
-
lines.push(` ingester @autter/otlp-ingester@${report.ingester.version}`);
|
|
113
|
-
const schema = report.ingester.schema;
|
|
114
|
-
if (schema) {
|
|
115
|
-
lines.push(
|
|
116
|
-
` schema ${schema.status}${schema.applied.length ? ` (level ${schema.applied[schema.applied.length - 1]})` : ""}`
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
lines.push(` ingester 1.4.0 or older (no /v1/compat endpoint; upgrade for a full report)`);
|
|
121
|
-
}
|
|
122
|
-
if (report.key) {
|
|
123
|
-
const text = {
|
|
124
|
-
accepted: "accepted",
|
|
125
|
-
rejected: "REJECTED (401): check AUTTER_RUNTIME_KEY",
|
|
126
|
-
client_key: "is a client/browser key; server SDKs need a server key",
|
|
127
|
-
storage_unavailable: "accepted, but the ingester's ClickHouse is unavailable (503)",
|
|
128
|
-
unverified: "could not be checked: the ingester's key validator is unavailable (503); exporters retry",
|
|
129
|
-
unknown: "could not be verified"
|
|
130
|
-
}[report.key];
|
|
131
|
-
lines.push(` key ${text}`);
|
|
132
|
-
}
|
|
133
|
-
if (report.features.length) {
|
|
134
|
-
lines.push("", "Features");
|
|
135
|
-
for (const feature of report.features) {
|
|
136
|
-
const mark = feature.status === "ok" ? "ok " : feature.status === "incompatible" ? "FAIL" : "?? ";
|
|
137
|
-
lines.push(` ${mark} ${feature.title} (${feature.id})`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (report.issues.length) {
|
|
141
|
-
lines.push("", "Problems");
|
|
142
|
-
for (const issue of report.issues) lines.push(` - ${issue.message}`);
|
|
143
|
-
}
|
|
144
|
-
lines.push(
|
|
145
|
-
"",
|
|
146
|
-
report.exitCode === 0 ? "Compatible." : report.exitCode === 1 ? "Incompatible: see the problems above." : "Could not check the ingester. Pass --endpoint <url> (or set AUTTER_ENDPOINT)."
|
|
147
|
-
);
|
|
148
|
-
return lines.join("\n");
|
|
149
|
-
}
|
|
150
|
-
var DOCTOR_USAGE = `Usage: npx @autter/runtime-node doctor [options]
|
|
151
|
-
|
|
152
|
-
Checks that your Autter SDKs, ingester and ClickHouse schema versions match.
|
|
153
|
-
|
|
154
|
-
Options:
|
|
155
|
-
--endpoint <url> Ingester base URL (default: $AUTTER_ENDPOINT, $OTEL_EXPORTER_OTLP_ENDPOINT, or ${DEFAULT_ENDPOINT})
|
|
156
|
-
--key <key> Also verify an ingest key (default: $AUTTER_RUNTIME_KEY)
|
|
157
|
-
--features <a,b> Only check these features (${_chunk3P573RHAcjs.COMPAT_MANIFEST.features.map((f) => f.id).join(", ")})
|
|
158
|
-
--json Machine-readable output
|
|
159
|
-
--timeout <ms> Per-request timeout (default 5000)
|
|
160
|
-
|
|
161
|
-
Exit codes: 0 compatible, 1 mismatch or rejected key, 2 ingester unreachable.`;
|
|
162
|
-
function parseDoctorArgs(argv, env = process.env) {
|
|
163
|
-
const options = {};
|
|
164
|
-
for (let i = 0; i < argv.length; i++) {
|
|
165
|
-
const arg = argv[i];
|
|
166
|
-
const [flag, inline] = arg.includes("=") ? [arg.slice(0, arg.indexOf("=")), arg.slice(arg.indexOf("=") + 1)] : [arg, void 0];
|
|
167
|
-
const value = () => _nullishCoalesce(inline, () => ( argv[++i]));
|
|
168
|
-
switch (flag) {
|
|
169
|
-
case "-h":
|
|
170
|
-
case "--help":
|
|
171
|
-
return { help: true };
|
|
172
|
-
case "--endpoint":
|
|
173
|
-
options.endpoint = value();
|
|
174
|
-
break;
|
|
175
|
-
case "--key":
|
|
176
|
-
options.key = value();
|
|
177
|
-
break;
|
|
178
|
-
case "--features":
|
|
179
|
-
options.features = (_nullishCoalesce(value(), () => ( ""))).split(",").map((f) => f.trim()).filter(Boolean);
|
|
180
|
-
break;
|
|
181
|
-
case "--json":
|
|
182
|
-
options.json = true;
|
|
183
|
-
break;
|
|
184
|
-
case "--timeout": {
|
|
185
|
-
const ms = Number(value());
|
|
186
|
-
if (!Number.isFinite(ms) || ms <= 0) return { error: "--timeout needs a positive number of ms" };
|
|
187
|
-
options.timeoutMs = ms;
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
default:
|
|
191
|
-
return { error: `unknown option ${arg}` };
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (!options.key && env.AUTTER_RUNTIME_KEY) options.key = env.AUTTER_RUNTIME_KEY;
|
|
195
|
-
return options;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
exports.runDoctor = runDoctor; exports.formatDoctorReport = formatDoctorReport; exports.DOCTOR_USAGE = DOCTOR_USAGE; exports.parseDoctorArgs = parseDoctorArgs;
|