@mercuryo-ai/magicpay-cli 0.1.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 +56 -0
- package/dist/agentbrowse-assistive.d.ts +2 -0
- package/dist/agentbrowse-assistive.d.ts.map +1 -0
- package/dist/agentbrowse-assistive.js +66 -0
- package/dist/assistive-llm-client.d.ts +13 -0
- package/dist/assistive-llm-client.d.ts.map +1 -0
- package/dist/assistive-llm-client.js +152 -0
- package/dist/browser-bridge/act.d.ts +5 -0
- package/dist/browser-bridge/act.d.ts.map +1 -0
- package/dist/browser-bridge/act.js +8 -0
- package/dist/browser-bridge/observe.d.ts +5 -0
- package/dist/browser-bridge/observe.d.ts.map +1 -0
- package/dist/browser-bridge/observe.js +53 -0
- package/dist/browser-home.d.ts +7 -0
- package/dist/browser-home.d.ts.map +1 -0
- package/dist/browser-home.js +34 -0
- package/dist/commands/act.d.ts +5 -0
- package/dist/commands/act.d.ts.map +1 -0
- package/dist/commands/act.js +8 -0
- package/dist/commands/attach.d.ts +4 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +10 -0
- package/dist/commands/browser-status.d.ts +5 -0
- package/dist/commands/browser-status.d.ts.map +1 -0
- package/dist/commands/browser-status.js +5 -0
- package/dist/commands/close.d.ts +4 -0
- package/dist/commands/close.d.ts.map +1 -0
- package/dist/commands/close.js +11 -0
- package/dist/commands/end-session.d.ts +22 -0
- package/dist/commands/end-session.d.ts.map +1 -0
- package/dist/commands/end-session.js +104 -0
- package/dist/commands/extract.d.ts +4 -0
- package/dist/commands/extract.d.ts.map +1 -0
- package/dist/commands/extract.js +14 -0
- package/dist/commands/fill-secret.d.ts +10 -0
- package/dist/commands/fill-secret.d.ts.map +1 -0
- package/dist/commands/fill-secret.js +483 -0
- package/dist/commands/find-form.d.ts +57 -0
- package/dist/commands/find-form.d.ts.map +1 -0
- package/dist/commands/find-form.js +138 -0
- package/dist/commands/get-secrets-catalog.d.ts +13 -0
- package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
- package/dist/commands/get-secrets-catalog.js +103 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +28 -0
- package/dist/commands/launch.d.ts +4 -0
- package/dist/commands/launch.d.ts.map +1 -0
- package/dist/commands/launch.js +10 -0
- package/dist/commands/mock-approve-secret.d.ts +21 -0
- package/dist/commands/mock-approve-secret.d.ts.map +1 -0
- package/dist/commands/mock-approve-secret.js +69 -0
- package/dist/commands/mock-deny-secret.d.ts +21 -0
- package/dist/commands/mock-deny-secret.d.ts.map +1 -0
- package/dist/commands/mock-deny-secret.js +69 -0
- package/dist/commands/navigate.d.ts +4 -0
- package/dist/commands/navigate.d.ts.map +1 -0
- package/dist/commands/navigate.js +9 -0
- package/dist/commands/observe.d.ts +5 -0
- package/dist/commands/observe.d.ts.map +1 -0
- package/dist/commands/observe.js +53 -0
- package/dist/commands/poll-secret.d.ts +13 -0
- package/dist/commands/poll-secret.d.ts.map +1 -0
- package/dist/commands/poll-secret.js +87 -0
- package/dist/commands/request-secret.d.ts +15 -0
- package/dist/commands/request-secret.d.ts.map +1 -0
- package/dist/commands/request-secret.js +235 -0
- package/dist/commands/screenshot.d.ts +4 -0
- package/dist/commands/screenshot.d.ts.map +1 -0
- package/dist/commands/screenshot.js +11 -0
- package/dist/commands/solve-captcha.d.ts +19 -0
- package/dist/commands/solve-captcha.d.ts.map +1 -0
- package/dist/commands/solve-captcha.js +63 -0
- package/dist/commands/start-session.d.ts +28 -0
- package/dist/commands/start-session.d.ts.map +1 -0
- package/dist/commands/start-session.js +298 -0
- package/dist/commands/status.d.ts +27 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +51 -0
- package/dist/commands/submit-form.d.ts +36 -0
- package/dist/commands/submit-form.d.ts.map +1 -0
- package/dist/commands/submit-form.js +242 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +1 -0
- package/dist/fillable-form-state.d.ts +5 -0
- package/dist/fillable-form-state.d.ts.map +1 -0
- package/dist/fillable-form-state.js +22 -0
- package/dist/gateway.d.ts +10 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +49 -0
- package/dist/generated/build-config.d.ts +2 -0
- package/dist/generated/build-config.d.ts.map +1 -0
- package/dist/generated/build-config.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +398 -0
- package/dist/mock-secret-cabinet.d.ts +37 -0
- package/dist/mock-secret-cabinet.d.ts.map +1 -0
- package/dist/mock-secret-cabinet.js +321 -0
- package/dist/mock-secret-store.d.ts +12 -0
- package/dist/mock-secret-store.d.ts.map +1 -0
- package/dist/mock-secret-store.js +108 -0
- package/dist/mock-stored-secrets.json +180 -0
- package/dist/otel-exporter.d.ts +58 -0
- package/dist/otel-exporter.d.ts.map +1 -0
- package/dist/otel-exporter.js +241 -0
- package/dist/otel-projector.d.ts +59 -0
- package/dist/otel-projector.d.ts.map +1 -0
- package/dist/otel-projector.js +325 -0
- package/dist/output.d.ts +10 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +29 -0
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +14 -0
- package/dist/protected-exposure.d.ts +4 -0
- package/dist/protected-exposure.d.ts.map +1 -0
- package/dist/protected-exposure.js +17 -0
- package/dist/request-output.d.ts +4 -0
- package/dist/request-output.d.ts.map +1 -0
- package/dist/request-output.js +27 -0
- package/dist/run-store.d.ts +130 -0
- package/dist/run-store.d.ts.map +1 -0
- package/dist/run-store.js +245 -0
- package/dist/secret-backend.d.ts +28 -0
- package/dist/secret-backend.d.ts.map +1 -0
- package/dist/secret-backend.js +335 -0
- package/dist/secret-state.d.ts +7 -0
- package/dist/secret-state.d.ts.map +1 -0
- package/dist/secret-state.js +26 -0
- package/dist/session-backend.d.ts +34 -0
- package/dist/session-backend.d.ts.map +1 -0
- package/dist/session-backend.js +36 -0
- package/dist/update-check.d.ts +13 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +175 -0
- package/dist/workflow-session-completion.d.ts +32 -0
- package/dist/workflow-session-completion.d.ts.map +1 -0
- package/dist/workflow-session-completion.js +149 -0
- package/dist/workflow-state.d.ts +2 -0
- package/dist/workflow-state.d.ts.map +1 -0
- package/dist/workflow-state.js +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { buildMagicPayTelemetryTracesUrl, tryResolveMagicPayGatewayConfig, } from './gateway.js';
|
|
2
|
+
import { projectRunRootToOtlpTraceRequest, projectStepToOtlpTraceRequest } from './otel-projector.js';
|
|
3
|
+
import { loadRunRecord, loadStepRecord, setRunIngestState } from './run-store.js';
|
|
4
|
+
const DEFAULT_HTTP_TIMEOUT_MS = 5_000;
|
|
5
|
+
const DISABLE_TELEMETRY_ENV = 'MAGICPAY_DISABLE_TELEMETRY';
|
|
6
|
+
function trimEnv(value) {
|
|
7
|
+
const trimmed = value?.trim();
|
|
8
|
+
return trimmed ? trimmed : undefined;
|
|
9
|
+
}
|
|
10
|
+
function telemetryDisabled(env) {
|
|
11
|
+
const value = trimEnv(env[DISABLE_TELEMETRY_ENV]);
|
|
12
|
+
if (!value) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const normalized = value.toLowerCase();
|
|
16
|
+
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
|
|
17
|
+
}
|
|
18
|
+
function parseHeaderList(value) {
|
|
19
|
+
if (!value) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const headers = {};
|
|
23
|
+
for (const chunk of value.split(',')) {
|
|
24
|
+
const separatorIndex = chunk.indexOf('=');
|
|
25
|
+
if (separatorIndex === -1) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const key = chunk.slice(0, separatorIndex).trim();
|
|
29
|
+
const headerValue = chunk.slice(separatorIndex + 1).trim();
|
|
30
|
+
if (!key || !headerValue) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
headers[key] = headerValue;
|
|
34
|
+
}
|
|
35
|
+
return headers;
|
|
36
|
+
}
|
|
37
|
+
function parseTimeoutMs(value) {
|
|
38
|
+
const parsed = value ? Number(value) : Number.NaN;
|
|
39
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_HTTP_TIMEOUT_MS;
|
|
40
|
+
}
|
|
41
|
+
function buildTracesEndpoint(base) {
|
|
42
|
+
return `${base.replace(/\/+$/, '')}/v1/traces`;
|
|
43
|
+
}
|
|
44
|
+
async function postOtlpTraceRequest(params) {
|
|
45
|
+
const controller = new AbortController();
|
|
46
|
+
const timeout = setTimeout(() => controller.abort(), params.config.timeoutMs);
|
|
47
|
+
try {
|
|
48
|
+
return await params.fetchImpl(params.config.tracesEndpoint, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: {
|
|
51
|
+
'content-type': 'application/json',
|
|
52
|
+
...params.config.headers,
|
|
53
|
+
},
|
|
54
|
+
body: JSON.stringify(params.payload),
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
clearTimeout(timeout);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function loadOtlpHttpJsonExporterConfig(env = process.env) {
|
|
63
|
+
if (telemetryDisabled(env)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const protocol = trimEnv(env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL) ??
|
|
67
|
+
trimEnv(env.OTEL_EXPORTER_OTLP_PROTOCOL) ??
|
|
68
|
+
'http/json';
|
|
69
|
+
if (protocol !== 'http/json') {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const tracesEndpoint = trimEnv(env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT);
|
|
73
|
+
const baseEndpoint = trimEnv(env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
|
74
|
+
const gateway = tryResolveMagicPayGatewayConfig();
|
|
75
|
+
const resolvedEndpoint = tracesEndpoint ??
|
|
76
|
+
(baseEndpoint ? buildTracesEndpoint(baseEndpoint) : null) ??
|
|
77
|
+
(gateway ? buildMagicPayTelemetryTracesUrl(gateway.apiUrl) : null);
|
|
78
|
+
if (!resolvedEndpoint) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const timeoutMs = parseTimeoutMs(trimEnv(env.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT) ??
|
|
82
|
+
trimEnv(env.OTEL_EXPORTER_OTLP_TIMEOUT));
|
|
83
|
+
const headers = {
|
|
84
|
+
...parseHeaderList(trimEnv(env.OTEL_EXPORTER_OTLP_HEADERS)),
|
|
85
|
+
...parseHeaderList(trimEnv(env.OTEL_EXPORTER_OTLP_TRACES_HEADERS)),
|
|
86
|
+
};
|
|
87
|
+
if (!headers.authorization && gateway) {
|
|
88
|
+
headers.authorization = `Bearer ${gateway.apiKey}`;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
tracesEndpoint: resolvedEndpoint,
|
|
92
|
+
headers,
|
|
93
|
+
timeoutMs,
|
|
94
|
+
protocol: 'http/json',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export function buildRunStepOtlpTraceRequest(runId, stepId) {
|
|
98
|
+
const run = loadRunRecord(runId);
|
|
99
|
+
if (!run) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const step = loadStepRecord(runId, stepId);
|
|
103
|
+
if (!step) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return projectStepToOtlpTraceRequest({
|
|
107
|
+
run,
|
|
108
|
+
step,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
export async function exportRunStepToOtlpHttpJson(params = {
|
|
112
|
+
runId: '',
|
|
113
|
+
stepId: '',
|
|
114
|
+
}) {
|
|
115
|
+
const run = loadRunRecord(params.runId);
|
|
116
|
+
if (!run) {
|
|
117
|
+
return { attempted: false, reason: 'run_missing' };
|
|
118
|
+
}
|
|
119
|
+
const step = loadStepRecord(params.runId, params.stepId);
|
|
120
|
+
if (!step) {
|
|
121
|
+
return { attempted: false, reason: 'step_missing' };
|
|
122
|
+
}
|
|
123
|
+
const payload = buildRunStepOtlpTraceRequest(params.runId, params.stepId);
|
|
124
|
+
if (!payload) {
|
|
125
|
+
return { attempted: false, reason: 'step_missing' };
|
|
126
|
+
}
|
|
127
|
+
const fetchImpl = params.fetchImpl ?? fetch;
|
|
128
|
+
const config = params.config ?? loadOtlpHttpJsonExporterConfig();
|
|
129
|
+
if (!config) {
|
|
130
|
+
return { attempted: false, reason: 'config_missing' };
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const response = await postOtlpTraceRequest({
|
|
134
|
+
payload,
|
|
135
|
+
config,
|
|
136
|
+
fetchImpl,
|
|
137
|
+
});
|
|
138
|
+
if (!response.ok) {
|
|
139
|
+
setRunIngestState(params.runId, 'export_failed');
|
|
140
|
+
return {
|
|
141
|
+
attempted: true,
|
|
142
|
+
success: false,
|
|
143
|
+
status: response.status,
|
|
144
|
+
reason: `otlp_http_status_${response.status}`,
|
|
145
|
+
payload,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
setRunIngestState(params.runId, 'exported');
|
|
149
|
+
return {
|
|
150
|
+
attempted: true,
|
|
151
|
+
success: true,
|
|
152
|
+
status: response.status,
|
|
153
|
+
payload,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
setRunIngestState(params.runId, 'export_failed');
|
|
158
|
+
return {
|
|
159
|
+
attempted: true,
|
|
160
|
+
success: false,
|
|
161
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
162
|
+
payload,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export function buildRunRootOtlpTraceRequest(runId) {
|
|
167
|
+
const run = loadRunRecord(runId);
|
|
168
|
+
if (!run) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
return projectRunRootToOtlpTraceRequest({ run });
|
|
172
|
+
}
|
|
173
|
+
export async function exportRunRootToOtlpHttpJson(params = {
|
|
174
|
+
runId: '',
|
|
175
|
+
}) {
|
|
176
|
+
const config = params.config ?? loadOtlpHttpJsonExporterConfig();
|
|
177
|
+
if (!config) {
|
|
178
|
+
return { attempted: false, reason: 'config_missing' };
|
|
179
|
+
}
|
|
180
|
+
const run = loadRunRecord(params.runId);
|
|
181
|
+
if (!run) {
|
|
182
|
+
return { attempted: false, reason: 'run_missing' };
|
|
183
|
+
}
|
|
184
|
+
const payload = buildRunRootOtlpTraceRequest(params.runId);
|
|
185
|
+
if (!payload) {
|
|
186
|
+
return { attempted: false, reason: 'run_missing' };
|
|
187
|
+
}
|
|
188
|
+
const fetchImpl = params.fetchImpl ?? fetch;
|
|
189
|
+
try {
|
|
190
|
+
const response = await postOtlpTraceRequest({
|
|
191
|
+
payload,
|
|
192
|
+
config,
|
|
193
|
+
fetchImpl,
|
|
194
|
+
});
|
|
195
|
+
if (!response.ok) {
|
|
196
|
+
setRunIngestState(params.runId, 'export_failed');
|
|
197
|
+
return {
|
|
198
|
+
attempted: true,
|
|
199
|
+
success: false,
|
|
200
|
+
status: response.status,
|
|
201
|
+
reason: `otlp_http_status_${response.status}`,
|
|
202
|
+
payload,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
setRunIngestState(params.runId, 'exported');
|
|
206
|
+
return {
|
|
207
|
+
attempted: true,
|
|
208
|
+
success: true,
|
|
209
|
+
status: response.status,
|
|
210
|
+
payload,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
setRunIngestState(params.runId, 'export_failed');
|
|
215
|
+
return {
|
|
216
|
+
attempted: true,
|
|
217
|
+
success: false,
|
|
218
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
219
|
+
payload,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export async function exportRunStepToOtlpHttpJsonBestEffort(runId, stepId, options = {}) {
|
|
224
|
+
if (!runId || !stepId) {
|
|
225
|
+
return { attempted: false, reason: 'step_missing' };
|
|
226
|
+
}
|
|
227
|
+
return exportRunStepToOtlpHttpJson({
|
|
228
|
+
runId,
|
|
229
|
+
stepId,
|
|
230
|
+
fetchImpl: options.fetchImpl,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
export async function exportRunRootToOtlpHttpJsonBestEffort(runId, options = {}) {
|
|
234
|
+
if (!runId) {
|
|
235
|
+
return { attempted: false, reason: 'run_missing' };
|
|
236
|
+
}
|
|
237
|
+
return exportRunRootToOtlpHttpJson({
|
|
238
|
+
runId,
|
|
239
|
+
fetchImpl: options.fetchImpl,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { RunRecord, StepRecord } from './run-store.js';
|
|
2
|
+
type OtlpAnyValue = {
|
|
3
|
+
stringValue: string;
|
|
4
|
+
} | {
|
|
5
|
+
boolValue: boolean;
|
|
6
|
+
} | {
|
|
7
|
+
intValue: string;
|
|
8
|
+
} | {
|
|
9
|
+
doubleValue: number;
|
|
10
|
+
} | {
|
|
11
|
+
arrayValue: {
|
|
12
|
+
values: OtlpAnyValue[];
|
|
13
|
+
};
|
|
14
|
+
} | {
|
|
15
|
+
kvlistValue: {
|
|
16
|
+
values: OtlpKeyValue[];
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
type OtlpKeyValue = {
|
|
20
|
+
key: string;
|
|
21
|
+
value: OtlpAnyValue;
|
|
22
|
+
};
|
|
23
|
+
type OtlpSpan = {
|
|
24
|
+
traceId: string;
|
|
25
|
+
spanId: string;
|
|
26
|
+
parentSpanId?: string;
|
|
27
|
+
name: string;
|
|
28
|
+
kind: number;
|
|
29
|
+
startTimeUnixNano: string;
|
|
30
|
+
endTimeUnixNano: string;
|
|
31
|
+
attributes?: OtlpKeyValue[];
|
|
32
|
+
status?: {
|
|
33
|
+
code: number;
|
|
34
|
+
message?: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export type OtlpTraceRequest = {
|
|
38
|
+
resourceSpans: Array<{
|
|
39
|
+
resource: {
|
|
40
|
+
attributes: OtlpKeyValue[];
|
|
41
|
+
};
|
|
42
|
+
scopeSpans: Array<{
|
|
43
|
+
scope: {
|
|
44
|
+
name: string;
|
|
45
|
+
};
|
|
46
|
+
spans: OtlpSpan[];
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
export declare function sanitizeUrlForTelemetry(url: string): string;
|
|
51
|
+
export declare function projectStepToOtlpTraceRequest(params: {
|
|
52
|
+
run: RunRecord;
|
|
53
|
+
step: StepRecord;
|
|
54
|
+
}): OtlpTraceRequest;
|
|
55
|
+
export declare function projectRunRootToOtlpTraceRequest(params: {
|
|
56
|
+
run: RunRecord;
|
|
57
|
+
}): OtlpTraceRequest;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=otel-projector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-projector.d.ts","sourceRoot":"","sources":["../src/otel-projector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAuB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjF,KAAK,YAAY,GACb;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GACvB;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,GACtB;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpB;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GACvB;IAAE,UAAU,EAAE;QAAE,MAAM,EAAE,YAAY,EAAE,CAAA;KAAE,CAAA;CAAE,GAC1C;IAAE,WAAW,EAAE;QAAE,MAAM,EAAE,YAAY,EAAE,CAAA;KAAE,CAAA;CAAE,CAAC;AAEhD,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,KAAK,QAAQ,GAAG;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE,KAAK,CAAC;QACnB,QAAQ,EAAE;YACR,UAAU,EAAE,YAAY,EAAE,CAAC;SAC5B,CAAC;QACF,UAAU,EAAE,KAAK,CAAC;YAChB,KAAK,EAAE;gBACL,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;YACF,KAAK,EAAE,QAAQ,EAAE,CAAC;SACnB,CAAC,CAAC;KACJ,CAAC,CAAC;CACJ,CAAC;AAwBF,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAW3D;AAgQD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE;IACpD,GAAG,EAAE,SAAS,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;CAClB,GAAG,gBAAgB,CA0CnB;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,GAAG,gBAAgB,CA2C7F"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
const INTERNAL_SPAN_KIND = 1;
|
|
2
|
+
const CLIENT_SPAN_KIND = 3;
|
|
3
|
+
const STATUS_CODE_UNSET = 0;
|
|
4
|
+
const STATUS_CODE_OK = 1;
|
|
5
|
+
const STATUS_CODE_ERROR = 2;
|
|
6
|
+
const MAX_ATTRIBUTE_STRING_LENGTH = 256;
|
|
7
|
+
const MAX_REASON_LENGTH = 512;
|
|
8
|
+
const SENSITIVE_KEY_PATTERN = /(secret|token|password|authorization|cookie|api[-_]?key|raw[-_]?value|raw[-_]?values|resolved[-_]?values|protected[-_]?values)/i;
|
|
9
|
+
function isoToUnixNano(value, fallback) {
|
|
10
|
+
const source = value ?? fallback;
|
|
11
|
+
const millis = new Date(source).getTime();
|
|
12
|
+
const safeMillis = Number.isFinite(millis) ? millis : new Date(fallback).getTime();
|
|
13
|
+
return `${Math.max(0, safeMillis) * 1_000_000}`;
|
|
14
|
+
}
|
|
15
|
+
function truncateString(value, maxLength = MAX_ATTRIBUTE_STRING_LENGTH) {
|
|
16
|
+
return value.length <= maxLength ? value : `${value.slice(0, maxLength)}...`;
|
|
17
|
+
}
|
|
18
|
+
export function sanitizeUrlForTelemetry(url) {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = new URL(url);
|
|
21
|
+
parsed.username = '';
|
|
22
|
+
parsed.password = '';
|
|
23
|
+
parsed.search = '';
|
|
24
|
+
parsed.hash = '';
|
|
25
|
+
return parsed.toString();
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return truncateString(url);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function isSensitiveKey(key) {
|
|
32
|
+
return SENSITIVE_KEY_PATTERN.test(key);
|
|
33
|
+
}
|
|
34
|
+
function normalizePrimitiveForTelemetry(key, value) {
|
|
35
|
+
if (value === null || value === undefined) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
if (isSensitiveKey(key)) {
|
|
39
|
+
return '[redacted]';
|
|
40
|
+
}
|
|
41
|
+
if (typeof value === 'string') {
|
|
42
|
+
if (key.toLowerCase().includes('url')) {
|
|
43
|
+
return sanitizeUrlForTelemetry(value);
|
|
44
|
+
}
|
|
45
|
+
if (key.toLowerCase().includes('reason')) {
|
|
46
|
+
return truncateString(value, MAX_REASON_LENGTH);
|
|
47
|
+
}
|
|
48
|
+
if (key.toLowerCase().includes('message')) {
|
|
49
|
+
return truncateString(value, MAX_ATTRIBUTE_STRING_LENGTH);
|
|
50
|
+
}
|
|
51
|
+
return truncateString(value);
|
|
52
|
+
}
|
|
53
|
+
if (typeof value === 'boolean' || typeof value === 'number') {
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
function flattenTelemetryAttributes(prefix, value, target) {
|
|
59
|
+
if (value === null || value === undefined) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
if (value.length === 0) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const normalized = value
|
|
67
|
+
.map((entry, index) => normalizePrimitiveForTelemetry(`${prefix}[${index}]`, entry))
|
|
68
|
+
.filter((entry) => entry !== undefined);
|
|
69
|
+
if (normalized.length > 0) {
|
|
70
|
+
target[prefix] = normalized;
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (typeof value === 'object') {
|
|
75
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
76
|
+
const nextPrefix = prefix.length > 0 ? `${prefix}.${key}` : key;
|
|
77
|
+
flattenTelemetryAttributes(nextPrefix, nested, target);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const normalized = normalizePrimitiveForTelemetry(prefix, value);
|
|
82
|
+
if (normalized !== undefined) {
|
|
83
|
+
target[prefix] = normalized;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function toAnyValue(value) {
|
|
87
|
+
if (typeof value === 'string') {
|
|
88
|
+
return { stringValue: value };
|
|
89
|
+
}
|
|
90
|
+
if (typeof value === 'boolean') {
|
|
91
|
+
return { boolValue: value };
|
|
92
|
+
}
|
|
93
|
+
if (typeof value === 'number') {
|
|
94
|
+
if (Number.isInteger(value)) {
|
|
95
|
+
return { intValue: String(value) };
|
|
96
|
+
}
|
|
97
|
+
return { doubleValue: value };
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
const values = value.map(toAnyValue).filter((entry) => entry !== null);
|
|
101
|
+
return { arrayValue: { values } };
|
|
102
|
+
}
|
|
103
|
+
if (value && typeof value === 'object') {
|
|
104
|
+
const values = Object.entries(value)
|
|
105
|
+
.map(([key, nested]) => {
|
|
106
|
+
const nestedValue = toAnyValue(nested);
|
|
107
|
+
return nestedValue ? { key, value: nestedValue } : null;
|
|
108
|
+
})
|
|
109
|
+
.filter((entry) => entry !== null);
|
|
110
|
+
return { kvlistValue: { values } };
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
function toKeyValues(values) {
|
|
115
|
+
return Object.entries(values)
|
|
116
|
+
.map(([key, value]) => {
|
|
117
|
+
const anyValue = toAnyValue(value);
|
|
118
|
+
return anyValue ? { key, value: anyValue } : null;
|
|
119
|
+
})
|
|
120
|
+
.filter((entry) => entry !== null);
|
|
121
|
+
}
|
|
122
|
+
function getPrimaryRunSiteHost(run) {
|
|
123
|
+
return run.hostHints?.find((entry) => typeof entry === 'string' && entry.length > 0);
|
|
124
|
+
}
|
|
125
|
+
function buildResourceAttributes(run) {
|
|
126
|
+
const siteHost = getPrimaryRunSiteHost(run);
|
|
127
|
+
const values = {
|
|
128
|
+
'service.name': run.resource.serviceName,
|
|
129
|
+
'service.version': run.resource.serviceVersion,
|
|
130
|
+
'service.instance.id': run.resource.serviceInstanceId,
|
|
131
|
+
'telemetry.sdk.language': run.resource.telemetrySdkLanguage,
|
|
132
|
+
'agentbrowse.session.id': run.sessionId,
|
|
133
|
+
'agentbrowse.run.id': run.runId,
|
|
134
|
+
'agentbrowse.run.source': run.source,
|
|
135
|
+
'agentbrowse.run.entry_command': run.entryCommand,
|
|
136
|
+
'agentbrowse.run.display_name': run.displayName,
|
|
137
|
+
'agentbrowse.run.profile': run.profile,
|
|
138
|
+
'agentbrowse.run.site_host': siteHost,
|
|
139
|
+
'agentbrowse.run.started_at': run.startedAt,
|
|
140
|
+
'agentbrowse.run.ended_at': run.endedAt,
|
|
141
|
+
'agentbrowse.run.status': run.status,
|
|
142
|
+
'agentbrowse.run.protected': run.protectedRun,
|
|
143
|
+
'agentbrowse.run.final_outcome_type': run.finalOutcome?.outcomeType,
|
|
144
|
+
'agentbrowse.run.final_message': run.finalOutcome?.message,
|
|
145
|
+
'agentbrowse.run.final_reason': run.finalOutcome?.reason,
|
|
146
|
+
};
|
|
147
|
+
if (run.hostHints && run.hostHints.length > 0) {
|
|
148
|
+
values['agentbrowse.run.host_hints'] = run.hostHints.map((host) => truncateString(host));
|
|
149
|
+
}
|
|
150
|
+
return toKeyValues(values);
|
|
151
|
+
}
|
|
152
|
+
function buildStepAttributes(run, step) {
|
|
153
|
+
const values = {
|
|
154
|
+
'agentbrowse.run.id': run.runId,
|
|
155
|
+
'agentbrowse.session.id': run.sessionId,
|
|
156
|
+
'agentbrowse.step.id': step.stepId,
|
|
157
|
+
'agentbrowse.step.ordinal': step.ordinal,
|
|
158
|
+
'agentbrowse.step.command': step.command,
|
|
159
|
+
'agentbrowse.step.protected': step.protectedStep,
|
|
160
|
+
'agentbrowse.step.page_ref': step.refs?.pageRef,
|
|
161
|
+
'agentbrowse.step.target_ref': step.refs?.targetRef,
|
|
162
|
+
'agentbrowse.step.surface_ref': step.refs?.surfaceRef,
|
|
163
|
+
'agentbrowse.step.fill_ref': step.refs?.fillRef,
|
|
164
|
+
'agentbrowse.step.request_id': step.refs?.requestId,
|
|
165
|
+
'agentbrowse.step.success': step.outputSummary?.success,
|
|
166
|
+
'agentbrowse.step.outcome_type': step.outputSummary?.outcomeType,
|
|
167
|
+
'agentbrowse.step.message': step.outputSummary?.message,
|
|
168
|
+
'agentbrowse.step.reason': step.outputSummary?.reason,
|
|
169
|
+
'agentbrowse.step.event_count': step.eventIds.length,
|
|
170
|
+
'agentbrowse.step.child_span_count': step.childSpans.length,
|
|
171
|
+
'agentbrowse.trace.propagation_mode': run.traceContext.propagationMode,
|
|
172
|
+
};
|
|
173
|
+
const flattenedInput = {};
|
|
174
|
+
flattenTelemetryAttributes('agentbrowse.step.input', step.input, flattenedInput);
|
|
175
|
+
Object.assign(values, flattenedInput);
|
|
176
|
+
return toKeyValues(values);
|
|
177
|
+
}
|
|
178
|
+
function buildRunRootSpanName(run) {
|
|
179
|
+
const siteHost = getPrimaryRunSiteHost(run);
|
|
180
|
+
const displayName = typeof run.displayName === 'string' && run.displayName.trim().length > 0
|
|
181
|
+
? run.displayName.trim()
|
|
182
|
+
: undefined;
|
|
183
|
+
if (siteHost && displayName) {
|
|
184
|
+
return truncateString(`${siteHost} - ${displayName}`);
|
|
185
|
+
}
|
|
186
|
+
if (displayName) {
|
|
187
|
+
return truncateString(displayName);
|
|
188
|
+
}
|
|
189
|
+
if (siteHost) {
|
|
190
|
+
return truncateString(siteHost);
|
|
191
|
+
}
|
|
192
|
+
if (run.entryCommand) {
|
|
193
|
+
return `magicpay.${truncateString(run.entryCommand)}`;
|
|
194
|
+
}
|
|
195
|
+
return 'magicpay.run';
|
|
196
|
+
}
|
|
197
|
+
function buildRunRootSpanAttributes(run) {
|
|
198
|
+
const siteHost = getPrimaryRunSiteHost(run);
|
|
199
|
+
const values = {
|
|
200
|
+
'agentbrowse.run.id': run.runId,
|
|
201
|
+
'agentbrowse.session.id': run.sessionId,
|
|
202
|
+
'agentbrowse.run.entry_command': run.entryCommand,
|
|
203
|
+
'agentbrowse.run.display_name': run.displayName,
|
|
204
|
+
'agentbrowse.run.site_host': siteHost,
|
|
205
|
+
'agentbrowse.run.status': run.status,
|
|
206
|
+
'agentbrowse.run.protected': run.protectedRun,
|
|
207
|
+
'agentbrowse.run.step_count': run.stepIds.length,
|
|
208
|
+
'agentbrowse.run.final_outcome_type': run.finalOutcome?.outcomeType,
|
|
209
|
+
'agentbrowse.run.final_message': run.finalOutcome?.message,
|
|
210
|
+
'agentbrowse.run.final_reason': run.finalOutcome?.reason,
|
|
211
|
+
};
|
|
212
|
+
if (run.hostHints && run.hostHints.length > 0) {
|
|
213
|
+
values['agentbrowse.run.host_hints'] = run.hostHints.map((host) => truncateString(host));
|
|
214
|
+
}
|
|
215
|
+
return toKeyValues(values);
|
|
216
|
+
}
|
|
217
|
+
function buildStepStatus(step) {
|
|
218
|
+
const code = step.otel.statusCode === 'ok'
|
|
219
|
+
? STATUS_CODE_OK
|
|
220
|
+
: step.otel.statusCode === 'error'
|
|
221
|
+
? STATUS_CODE_ERROR
|
|
222
|
+
: STATUS_CODE_UNSET;
|
|
223
|
+
return {
|
|
224
|
+
code,
|
|
225
|
+
...(step.otel.statusMessage ? { message: truncateString(step.otel.statusMessage) } : {}),
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function buildChildSpanStatus(childSpan) {
|
|
229
|
+
const code = childSpan.statusCode === 'ok'
|
|
230
|
+
? STATUS_CODE_OK
|
|
231
|
+
: childSpan.statusCode === 'error'
|
|
232
|
+
? STATUS_CODE_ERROR
|
|
233
|
+
: STATUS_CODE_UNSET;
|
|
234
|
+
return {
|
|
235
|
+
code,
|
|
236
|
+
...(childSpan.statusMessage ? { message: truncateString(childSpan.statusMessage) } : {}),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function buildChildSpanAttributes(childSpan) {
|
|
240
|
+
const flattened = {};
|
|
241
|
+
flattenTelemetryAttributes('', childSpan.attributes, flattened);
|
|
242
|
+
return toKeyValues(flattened);
|
|
243
|
+
}
|
|
244
|
+
export function projectStepToOtlpTraceRequest(params) {
|
|
245
|
+
const stepSpan = {
|
|
246
|
+
traceId: params.step.otel.traceId,
|
|
247
|
+
spanId: params.step.otel.spanId,
|
|
248
|
+
...(params.step.otel.parentSpanId ? { parentSpanId: params.step.otel.parentSpanId } : {}),
|
|
249
|
+
name: params.step.otel.spanName,
|
|
250
|
+
kind: INTERNAL_SPAN_KIND,
|
|
251
|
+
startTimeUnixNano: isoToUnixNano(params.step.startedAt, params.run.startedAt),
|
|
252
|
+
endTimeUnixNano: isoToUnixNano(params.step.endedAt, params.step.startedAt),
|
|
253
|
+
attributes: buildStepAttributes(params.run, params.step),
|
|
254
|
+
status: buildStepStatus(params.step),
|
|
255
|
+
};
|
|
256
|
+
const childSpans = params.step.childSpans.map((childSpan) => ({
|
|
257
|
+
traceId: params.step.otel.traceId,
|
|
258
|
+
spanId: childSpan.spanId,
|
|
259
|
+
parentSpanId: childSpan.parentSpanId,
|
|
260
|
+
name: childSpan.name,
|
|
261
|
+
kind: CLIENT_SPAN_KIND,
|
|
262
|
+
startTimeUnixNano: isoToUnixNano(childSpan.startedAt, params.step.startedAt),
|
|
263
|
+
endTimeUnixNano: isoToUnixNano(childSpan.endedAt, childSpan.startedAt),
|
|
264
|
+
attributes: buildChildSpanAttributes(childSpan),
|
|
265
|
+
status: buildChildSpanStatus(childSpan),
|
|
266
|
+
}));
|
|
267
|
+
return {
|
|
268
|
+
resourceSpans: [
|
|
269
|
+
{
|
|
270
|
+
resource: {
|
|
271
|
+
attributes: buildResourceAttributes(params.run),
|
|
272
|
+
},
|
|
273
|
+
scopeSpans: [
|
|
274
|
+
{
|
|
275
|
+
scope: {
|
|
276
|
+
name: params.step.otel.instrumentationScope,
|
|
277
|
+
},
|
|
278
|
+
spans: [stepSpan, ...childSpans],
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
export function projectRunRootToOtlpTraceRequest(params) {
|
|
286
|
+
const statusCode = params.run.finalOutcome?.success === true || params.run.status === 'completed'
|
|
287
|
+
? STATUS_CODE_OK
|
|
288
|
+
: params.run.finalOutcome?.success === false ||
|
|
289
|
+
params.run.status === 'failed' ||
|
|
290
|
+
params.run.status === 'aborted'
|
|
291
|
+
? STATUS_CODE_ERROR
|
|
292
|
+
: STATUS_CODE_UNSET;
|
|
293
|
+
const span = {
|
|
294
|
+
traceId: params.run.traceContext.traceId,
|
|
295
|
+
spanId: params.run.traceContext.rootSpanId,
|
|
296
|
+
name: buildRunRootSpanName(params.run),
|
|
297
|
+
kind: INTERNAL_SPAN_KIND,
|
|
298
|
+
startTimeUnixNano: isoToUnixNano(params.run.startedAt, params.run.startedAt),
|
|
299
|
+
endTimeUnixNano: isoToUnixNano(params.run.endedAt, params.run.startedAt),
|
|
300
|
+
attributes: buildRunRootSpanAttributes(params.run),
|
|
301
|
+
status: {
|
|
302
|
+
code: statusCode,
|
|
303
|
+
...(params.run.finalOutcome?.reason
|
|
304
|
+
? { message: truncateString(params.run.finalOutcome.reason) }
|
|
305
|
+
: {}),
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
return {
|
|
309
|
+
resourceSpans: [
|
|
310
|
+
{
|
|
311
|
+
resource: {
|
|
312
|
+
attributes: buildResourceAttributes(params.run),
|
|
313
|
+
},
|
|
314
|
+
scopeSpans: [
|
|
315
|
+
{
|
|
316
|
+
scope: {
|
|
317
|
+
name: 'magicpay.local-run-store',
|
|
318
|
+
},
|
|
319
|
+
spans: [span],
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
};
|
|
325
|
+
}
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CliResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function outputJSON<T extends CliResult>(result: T): never;
|
|
6
|
+
export declare function outputError(error: string): never;
|
|
7
|
+
export declare function writeInfo(message: string): void;
|
|
8
|
+
export declare function info(message: string): never;
|
|
9
|
+
export declare function fatal(message: string): never;
|
|
10
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAMhE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAEhD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAG3C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAG5C"}
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const DEFAULT_COMMAND_NAME = 'magicpay';
|
|
2
|
+
function serializeResult(result) {
|
|
3
|
+
return `${JSON.stringify(result, null, 2)}\n`;
|
|
4
|
+
}
|
|
5
|
+
function commandName() {
|
|
6
|
+
const normalized = process.env.MAGICPAY_COMMAND?.trim();
|
|
7
|
+
return normalized && normalized.length > 0 ? normalized : DEFAULT_COMMAND_NAME;
|
|
8
|
+
}
|
|
9
|
+
export function outputJSON(result) {
|
|
10
|
+
const normalizedResult = result.success
|
|
11
|
+
? result
|
|
12
|
+
: { ...result, error: result.error ?? 'Unknown error' };
|
|
13
|
+
process.stdout.write(serializeResult(normalizedResult));
|
|
14
|
+
process.exit(result.success ? 0 : 1);
|
|
15
|
+
}
|
|
16
|
+
export function outputError(error) {
|
|
17
|
+
outputJSON({ success: false, error });
|
|
18
|
+
}
|
|
19
|
+
export function writeInfo(message) {
|
|
20
|
+
process.stderr.write(`${message}\n`);
|
|
21
|
+
}
|
|
22
|
+
export function info(message) {
|
|
23
|
+
process.stdout.write(`${message}\n`);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
export function fatal(message) {
|
|
27
|
+
process.stderr.write(`[${commandName()}] Fatal: ${message}\n`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-version.d.ts","sourceRoot":"","sources":["../src/package-version.ts"],"names":[],"mappings":"AAMA,wBAAgB,yBAAyB,IAAI,MAAM,CAYlD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
const PACKAGE_JSON_URL = new URL('../package.json', import.meta.url);
|
|
3
|
+
let cachedPackageVersion = null;
|
|
4
|
+
export function readCurrentPackageVersion() {
|
|
5
|
+
if (cachedPackageVersion) {
|
|
6
|
+
return cachedPackageVersion;
|
|
7
|
+
}
|
|
8
|
+
const raw = JSON.parse(readFileSync(PACKAGE_JSON_URL, 'utf-8'));
|
|
9
|
+
if (!raw.version || typeof raw.version !== 'string') {
|
|
10
|
+
throw new Error('Package version is missing from package.json.');
|
|
11
|
+
}
|
|
12
|
+
cachedPackageVersion = raw.version;
|
|
13
|
+
return cachedPackageVersion;
|
|
14
|
+
}
|