@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,335 @@
|
|
|
1
|
+
import { createMagicPayClient, } from '@mercuryo-ai/magicpay-sdk';
|
|
2
|
+
import { describeSecretRequestStatus } from '@mercuryo-ai/magicpay-sdk/core';
|
|
3
|
+
import { approveMockSecretRequest as approveMockSecretRequestRecord, claimMockSecretRequest, createOrReuseMockSecretRequest, denyMockSecretRequest as denyMockSecretRequestRecord, pollMockSecretRequest, } from './mock-secret-cabinet.js';
|
|
4
|
+
import { fetchMockSecretCatalog, resolveMockStoredSecretValues } from './mock-secret-store.js';
|
|
5
|
+
import { resolveMagicPayGatewayConfig } from './gateway.js';
|
|
6
|
+
const ENABLE_MOCK_SECRETS_ENV_NAMES = ['MAGICPAY_ENABLE_MOCK_SECRETS'];
|
|
7
|
+
const MOCK_GATEWAY_CONFIG = {
|
|
8
|
+
apiKey: 'mock-secrets',
|
|
9
|
+
apiUrl: 'https://mock.invalid',
|
|
10
|
+
};
|
|
11
|
+
function envFlagEnabled(value) {
|
|
12
|
+
if (!value) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const normalized = value.trim().toLowerCase();
|
|
16
|
+
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
|
|
17
|
+
}
|
|
18
|
+
function formatUnknownError(error) {
|
|
19
|
+
if (error instanceof Error) {
|
|
20
|
+
return error.message;
|
|
21
|
+
}
|
|
22
|
+
if (typeof error === 'string') {
|
|
23
|
+
return error;
|
|
24
|
+
}
|
|
25
|
+
if (error && typeof error === 'object') {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.stringify(error);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return Object.prototype.toString.call(error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return String(error);
|
|
34
|
+
}
|
|
35
|
+
function buildClaimId() {
|
|
36
|
+
return `magicpay-cli-mock-claim-${Date.now()}`;
|
|
37
|
+
}
|
|
38
|
+
function isTerminalSecretStatus(status) {
|
|
39
|
+
return status !== 'pending';
|
|
40
|
+
}
|
|
41
|
+
async function waitForNextPoll(delayMs, signal) {
|
|
42
|
+
if (delayMs <= 0) {
|
|
43
|
+
if (signal?.aborted) {
|
|
44
|
+
throw signal.reason ?? new DOMException('This operation was aborted', 'AbortError');
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
await new Promise((resolve, reject) => {
|
|
49
|
+
const timeoutId = setTimeout(() => {
|
|
50
|
+
signal?.removeEventListener('abort', onAbort);
|
|
51
|
+
resolve();
|
|
52
|
+
}, delayMs);
|
|
53
|
+
const onAbort = () => {
|
|
54
|
+
clearTimeout(timeoutId);
|
|
55
|
+
signal?.removeEventListener('abort', onAbort);
|
|
56
|
+
reject(signal?.reason ?? new DOMException('This operation was aborted', 'AbortError'));
|
|
57
|
+
};
|
|
58
|
+
if (signal?.aborted) {
|
|
59
|
+
onAbort();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function mockBackendEnabledMessage() {
|
|
66
|
+
return `Set ${ENABLE_MOCK_SECRETS_ENV_NAMES.join('=1 or ')}=1 only for local/dev testing.`;
|
|
67
|
+
}
|
|
68
|
+
function tryGetLiveMagicPayClient(options = {}) {
|
|
69
|
+
try {
|
|
70
|
+
return createMagicPayClient({
|
|
71
|
+
gateway: resolveMagicPayGatewayConfig(),
|
|
72
|
+
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function getLiveMagicPayClient(options = {}) {
|
|
80
|
+
return createMagicPayClient({
|
|
81
|
+
gateway: resolveMagicPayGatewayConfig(),
|
|
82
|
+
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function unsupportedSessionsClient() {
|
|
86
|
+
const fail = () => {
|
|
87
|
+
throw new SecretBackendDisabledError('MagicPay session backend is not configured. Set MAGICPAY_API_KEY for MagicPay API access.');
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
async create() {
|
|
91
|
+
return fail();
|
|
92
|
+
},
|
|
93
|
+
async get() {
|
|
94
|
+
return fail();
|
|
95
|
+
},
|
|
96
|
+
async getState() {
|
|
97
|
+
return fail();
|
|
98
|
+
},
|
|
99
|
+
describe() {
|
|
100
|
+
return fail();
|
|
101
|
+
},
|
|
102
|
+
async completeWithOutcome() {
|
|
103
|
+
return fail();
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function toClaimFailure(error) {
|
|
108
|
+
const message = formatUnknownError(error);
|
|
109
|
+
if (message === 'secret_request_already_claimed') {
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
kind: 'already_claimed',
|
|
113
|
+
reason: 'A secret payload was already claimed for this request.',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (message.startsWith('secret_request_not_fulfilled:')) {
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
kind: 'not_fulfilled',
|
|
120
|
+
reason: 'This secret request is not approved yet.',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (message === 'secret_request_not_found') {
|
|
124
|
+
return {
|
|
125
|
+
success: false,
|
|
126
|
+
kind: 'other',
|
|
127
|
+
reason: 'MagicPay mock storage did not find a secret request for the provided session ID and request ID.',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (message === 'mock_secret_values_missing') {
|
|
131
|
+
return {
|
|
132
|
+
success: false,
|
|
133
|
+
kind: 'other',
|
|
134
|
+
reason: 'MagicPay mock storage does not have secret values for the requested stored secret reference.',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
success: false,
|
|
139
|
+
kind: 'other',
|
|
140
|
+
reason: message,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
async function pollMockSecretRequestUntil(sessionId, requestId, options = {}) {
|
|
144
|
+
const startedAt = Date.now();
|
|
145
|
+
const timeoutMs = options.timeoutMs ?? 180_000;
|
|
146
|
+
const maxIntervalMs = options.maxIntervalMs ?? 30_000;
|
|
147
|
+
const backoffMultiplier = options.backoffMultiplier ?? 1.2;
|
|
148
|
+
let nextIntervalMs = options.intervalMs ?? 10_000;
|
|
149
|
+
let attempts = 0;
|
|
150
|
+
let lastResult;
|
|
151
|
+
while (true) {
|
|
152
|
+
if (options.signal?.aborted) {
|
|
153
|
+
return {
|
|
154
|
+
success: false,
|
|
155
|
+
requestId,
|
|
156
|
+
attempts,
|
|
157
|
+
elapsedMs: Date.now() - startedAt,
|
|
158
|
+
kind: 'aborted',
|
|
159
|
+
reason: formatUnknownError(options.signal.reason),
|
|
160
|
+
...(lastResult ? { lastResult } : {}),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
attempts += 1;
|
|
164
|
+
const outcome = pollMockSecretRequest(sessionId, requestId);
|
|
165
|
+
const elapsedMs = Date.now() - startedAt;
|
|
166
|
+
options.onAttempt?.({
|
|
167
|
+
attempt: attempts,
|
|
168
|
+
elapsedMs,
|
|
169
|
+
nextIntervalMs,
|
|
170
|
+
outcome,
|
|
171
|
+
});
|
|
172
|
+
if (outcome.success) {
|
|
173
|
+
lastResult = outcome.result;
|
|
174
|
+
const statusContract = describeSecretRequestStatus(outcome.result.snapshot.status, outcome.result.snapshot.requestType);
|
|
175
|
+
const stopWhen = options.stopWhen ?? 'terminal';
|
|
176
|
+
const shouldStop = stopWhen === 'fulfilled'
|
|
177
|
+
? outcome.result.snapshot.status === 'fulfilled'
|
|
178
|
+
: isTerminalSecretStatus(outcome.result.snapshot.status);
|
|
179
|
+
if (shouldStop) {
|
|
180
|
+
return {
|
|
181
|
+
success: true,
|
|
182
|
+
requestId,
|
|
183
|
+
attempts,
|
|
184
|
+
elapsedMs,
|
|
185
|
+
result: outcome.result,
|
|
186
|
+
statusContract,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
return {
|
|
192
|
+
success: false,
|
|
193
|
+
requestId,
|
|
194
|
+
attempts,
|
|
195
|
+
elapsedMs,
|
|
196
|
+
kind: outcome.kind,
|
|
197
|
+
reason: outcome.reason,
|
|
198
|
+
...(lastResult ? { lastResult } : {}),
|
|
199
|
+
...(outcome.status !== undefined ? { status: outcome.status } : {}),
|
|
200
|
+
...(outcome.errorCode !== undefined ? { errorCode: outcome.errorCode } : {}),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (elapsedMs >= timeoutMs) {
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
requestId,
|
|
207
|
+
attempts,
|
|
208
|
+
elapsedMs,
|
|
209
|
+
kind: 'timeout',
|
|
210
|
+
reason: `MagicPay mock secret request polling timed out after ${timeoutMs}ms.`,
|
|
211
|
+
...(lastResult ? { lastResult } : {}),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const remainingMs = Math.max(0, timeoutMs - elapsedMs);
|
|
215
|
+
const delayMs = Math.min(nextIntervalMs, remainingMs);
|
|
216
|
+
try {
|
|
217
|
+
await waitForNextPoll(delayMs, options.signal);
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
return {
|
|
221
|
+
success: false,
|
|
222
|
+
requestId,
|
|
223
|
+
attempts,
|
|
224
|
+
elapsedMs: Date.now() - startedAt,
|
|
225
|
+
kind: 'aborted',
|
|
226
|
+
reason: formatUnknownError(error),
|
|
227
|
+
...(lastResult ? { lastResult } : {}),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
nextIntervalMs = Math.min(maxIntervalMs, Math.round(nextIntervalMs * backoffMultiplier));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function createMockMagicPayClient(options = {}) {
|
|
234
|
+
const liveClient = tryGetLiveMagicPayClient(options);
|
|
235
|
+
return {
|
|
236
|
+
gateway: liveClient?.gateway ?? MOCK_GATEWAY_CONFIG,
|
|
237
|
+
sessions: liveClient?.sessions ?? unsupportedSessionsClient(),
|
|
238
|
+
secrets: {
|
|
239
|
+
async fetchCatalog(_sessionId, urlOrHost, _request) {
|
|
240
|
+
return fetchMockSecretCatalog(urlOrHost);
|
|
241
|
+
},
|
|
242
|
+
async createRequest(input) {
|
|
243
|
+
return createOrReuseMockSecretRequest(input);
|
|
244
|
+
},
|
|
245
|
+
async poll(sessionId, requestId) {
|
|
246
|
+
return pollMockSecretRequest(sessionId, requestId);
|
|
247
|
+
},
|
|
248
|
+
async pollUntil(sessionId, requestId, pollOptions) {
|
|
249
|
+
return pollMockSecretRequestUntil(sessionId, requestId, pollOptions);
|
|
250
|
+
},
|
|
251
|
+
async claim(sessionId, requestId, claimIdOrOptions, _maybeOptions) {
|
|
252
|
+
const claimId = typeof claimIdOrOptions === 'string' ? claimIdOrOptions : buildClaimId();
|
|
253
|
+
try {
|
|
254
|
+
return {
|
|
255
|
+
success: true,
|
|
256
|
+
result: claimMockSecretRequest(sessionId, requestId, claimId, {
|
|
257
|
+
resolveValues: (storedSecretRef) => resolveMockStoredSecretValues(storedSecretRef),
|
|
258
|
+
}),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
return toClaimFailure(error);
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
export class SecretBackendDisabledError extends Error {
|
|
269
|
+
constructor(message = 'Secret backend is not configured.') {
|
|
270
|
+
super(message);
|
|
271
|
+
this.name = 'SecretBackendDisabledError';
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function toMockSecretDecisionResult(record) {
|
|
275
|
+
return {
|
|
276
|
+
requestId: record.requestId,
|
|
277
|
+
sessionId: record.sessionId,
|
|
278
|
+
status: record.status === 'denied' ? 'denied' : 'fulfilled',
|
|
279
|
+
updatedAt: record.updatedAt,
|
|
280
|
+
...(record.resolvedAt ? { resolvedAt: record.resolvedAt } : {}),
|
|
281
|
+
...(record.expiresAt ? { expiresAt: record.expiresAt } : {}),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
const mockSecretBackend = {
|
|
285
|
+
kind: 'mock',
|
|
286
|
+
async fetchSecretCatalog(_sessionId, urlOrHost, _options) {
|
|
287
|
+
return fetchMockSecretCatalog(urlOrHost);
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
const magicpayApiSecretBackend = {
|
|
291
|
+
kind: 'magicpay_api',
|
|
292
|
+
async fetchSecretCatalog(sessionId, urlOrHost, options) {
|
|
293
|
+
return options
|
|
294
|
+
? getLiveMagicPayClient().secrets.fetchCatalog(sessionId, urlOrHost, options)
|
|
295
|
+
: getLiveMagicPayClient().secrets.fetchCatalog(sessionId, urlOrHost);
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
export function isMockSecretBackendEnabled() {
|
|
299
|
+
return ENABLE_MOCK_SECRETS_ENV_NAMES.some((envName) => envFlagEnabled(process.env[envName]));
|
|
300
|
+
}
|
|
301
|
+
export function getMagicPayClient(options = {}) {
|
|
302
|
+
if (isMockSecretBackendEnabled()) {
|
|
303
|
+
return createMockMagicPayClient(options);
|
|
304
|
+
}
|
|
305
|
+
return getLiveMagicPayClient(options);
|
|
306
|
+
}
|
|
307
|
+
export function getSecretBackend() {
|
|
308
|
+
if (isMockSecretBackendEnabled()) {
|
|
309
|
+
return mockSecretBackend;
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
resolveMagicPayGatewayConfig();
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
throw new SecretBackendDisabledError(`Secret backend is not configured. Set MAGICPAY_API_KEY for MagicPay API access or ${mockBackendEnabledMessage()}`);
|
|
316
|
+
}
|
|
317
|
+
return magicpayApiSecretBackend;
|
|
318
|
+
}
|
|
319
|
+
function ensureMockSecretBackendEnabled() {
|
|
320
|
+
if (!isMockSecretBackendEnabled()) {
|
|
321
|
+
throw new SecretBackendDisabledError(`Mock secret backend is disabled. ${mockBackendEnabledMessage()}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
export function approveMockSecretRequest(requestId) {
|
|
325
|
+
ensureMockSecretBackendEnabled();
|
|
326
|
+
return toMockSecretDecisionResult(approveMockSecretRequestRecord(requestId));
|
|
327
|
+
}
|
|
328
|
+
export function denyMockSecretRequest(requestId) {
|
|
329
|
+
ensureMockSecretBackendEnabled();
|
|
330
|
+
return toMockSecretDecisionResult(denyMockSecretRequestRecord(requestId));
|
|
331
|
+
}
|
|
332
|
+
export const __testSecretBackend = {
|
|
333
|
+
approveMockSecretRequest,
|
|
334
|
+
denyMockSecretRequest,
|
|
335
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretCatalog, SecretRequestSnapshot } from '@mercuryo-ai/magicpay-sdk';
|
|
2
|
+
import type { MagicPaySession } from './workflow-state.js';
|
|
3
|
+
export declare function saveSecretCatalog(session: MagicPaySession, snapshot: SecretCatalog): SecretCatalog;
|
|
4
|
+
export declare function getSecretCatalog(session: MagicPaySession, host: string): SecretCatalog | null;
|
|
5
|
+
export declare function saveSecretRequestSnapshot(session: MagicPaySession, snapshot: SecretRequestSnapshot): SecretRequestSnapshot;
|
|
6
|
+
export declare function getSecretRequestSnapshot(session: MagicPaySession, requestId: string): SecretRequestSnapshot | null;
|
|
7
|
+
//# sourceMappingURL=secret-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-state.d.ts","sourceRoot":"","sources":["../src/secret-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,aAAa,GACtB,aAAa,CAcf;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,MAAM,GACX,aAAa,GAAG,IAAI,CAEtB;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,qBAAqB,GAC9B,qBAAqB,CAIvB;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,GAChB,qBAAqB,GAAG,IAAI,CAE9B"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function saveSecretCatalog(session, snapshot) {
|
|
2
|
+
const catalog = (session.secretCatalogByHost ??= {});
|
|
3
|
+
catalog[snapshot.host] = {
|
|
4
|
+
...snapshot,
|
|
5
|
+
storedSecrets: snapshot.storedSecrets.map((secret) => ({
|
|
6
|
+
...secret,
|
|
7
|
+
fieldKeys: [...secret.fieldKeys],
|
|
8
|
+
fieldPolicies: secret.fieldPolicies ? { ...secret.fieldPolicies } : undefined,
|
|
9
|
+
preferredForMerchantKeys: secret.preferredForMerchantKeys
|
|
10
|
+
? [...secret.preferredForMerchantKeys]
|
|
11
|
+
: undefined,
|
|
12
|
+
})),
|
|
13
|
+
};
|
|
14
|
+
return catalog[snapshot.host];
|
|
15
|
+
}
|
|
16
|
+
export function getSecretCatalog(session, host) {
|
|
17
|
+
return session.secretCatalogByHost?.[host] ?? null;
|
|
18
|
+
}
|
|
19
|
+
export function saveSecretRequestSnapshot(session, snapshot) {
|
|
20
|
+
const snapshots = (session.secretRequestSnapshots ??= {});
|
|
21
|
+
snapshots[snapshot.requestId] = { ...snapshot };
|
|
22
|
+
return snapshots[snapshot.requestId];
|
|
23
|
+
}
|
|
24
|
+
export function getSecretRequestSnapshot(session, requestId) {
|
|
25
|
+
return session.secretRequestSnapshots?.[requestId] ?? null;
|
|
26
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ClaimRemoteSecretResponse, ClaimedRemoteSecret, CompleteRemoteSessionInput, CompleteRemoteSessionResponse, CreateRemoteSecretRequestInput, CreateRemoteSessionEventInput, CreateRemoteSessionInput, RemoteSecretRequestEnvelope, RemoteSessionEventEnvelope, RemoteSessionSecretRequestEnvelope, SessionResponse, SessionBackendCurrentRequest, SessionBackendEvent, SessionBackendRequest, SessionBackendSecretCatalogEntry, SessionBackendSession } from '@mercuryo-ai/magicpay-sdk/session-client';
|
|
2
|
+
import type { CompleteRemoteSessionOutcome } from '@mercuryo-ai/magicpay-sdk/session-flow';
|
|
3
|
+
export type { ClaimRemoteSecretResponse, ClaimedRemoteSecret, CompleteRemoteSessionOutcome, CompleteRemoteSessionInput, CompleteRemoteSessionResponse, CreateRemoteSecretRequestInput, CreateRemoteSessionEventInput, CreateRemoteSessionInput, RemoteSecretRequestEnvelope, RemoteSessionEventEnvelope, RemoteSessionSecretRequestEnvelope, SessionResponse, SessionBackendCurrentRequest, SessionBackendEvent, SessionBackendRequest, SessionBackendSecretCatalogEntry, SessionBackendSession, };
|
|
4
|
+
export declare function getMagicPayClient(options?: {
|
|
5
|
+
fetchImpl?: typeof fetch;
|
|
6
|
+
}): import("@mercuryo-ai/magicpay-sdk").MagicPayClient;
|
|
7
|
+
export declare function createRemoteSession(input: CreateRemoteSessionInput, options?: {
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
}): Promise<SessionResponse>;
|
|
10
|
+
export declare function getRemoteSession(sessionId: string, options?: {
|
|
11
|
+
fetchImpl?: typeof fetch;
|
|
12
|
+
}): Promise<SessionResponse>;
|
|
13
|
+
export declare function getRemoteSessionSecretCatalog(sessionId: string, host: string, options?: {
|
|
14
|
+
fetchImpl?: typeof fetch;
|
|
15
|
+
}): Promise<SessionBackendSecretCatalogEntry[]>;
|
|
16
|
+
export declare function createRemoteSessionEvent(sessionId: string, input: CreateRemoteSessionEventInput, options?: {
|
|
17
|
+
fetchImpl?: typeof fetch;
|
|
18
|
+
}): Promise<RemoteSessionEventEnvelope>;
|
|
19
|
+
export declare function completeRemoteSession(sessionId: string, input: CompleteRemoteSessionInput, options?: {
|
|
20
|
+
fetchImpl?: typeof fetch;
|
|
21
|
+
}): Promise<CompleteRemoteSessionResponse>;
|
|
22
|
+
export declare function completeRemoteSessionWithOutcome(sessionId: string, input: CompleteRemoteSessionInput, options?: {
|
|
23
|
+
fetchImpl?: typeof fetch;
|
|
24
|
+
}): Promise<CompleteRemoteSessionOutcome>;
|
|
25
|
+
export declare function createRemoteSecretRequest(sessionId: string, input: CreateRemoteSecretRequestInput, options?: {
|
|
26
|
+
fetchImpl?: typeof fetch;
|
|
27
|
+
}): Promise<RemoteSecretRequestEnvelope>;
|
|
28
|
+
export declare function getRemoteSecretRequest(sessionId: string, requestId: string, options?: {
|
|
29
|
+
fetchImpl?: typeof fetch;
|
|
30
|
+
}): Promise<RemoteSessionSecretRequestEnvelope>;
|
|
31
|
+
export declare function claimRemoteSecret(sessionId: string, requestId: string, claimId: string, options?: {
|
|
32
|
+
fetchImpl?: typeof fetch;
|
|
33
|
+
}): Promise<ClaimRemoteSecretResponse>;
|
|
34
|
+
//# sourceMappingURL=session-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-backend.d.ts","sourceRoot":"","sources":["../src/session-backend.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,0BAA0B,EAC1B,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,EAC7B,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,kCAAkC,EAClC,eAAe,EACf,4BAA4B,EAC5B,mBAAmB,EACnB,qBAAqB,EACrB,gCAAgC,EAChC,qBAAqB,EACtB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAG3F,YAAY,EACV,yBAAyB,EACzB,mBAAmB,EACnB,4BAA4B,EAC5B,0BAA0B,EAC1B,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,EAC7B,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,kCAAkC,EAClC,eAAe,EACf,4BAA4B,EAC5B,mBAAmB,EACnB,qBAAqB,EACrB,gCAAgC,EAChC,qBAAqB,GACtB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,sDAK3E;AAED,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,EAC/B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED,wBAAsB,6BAA6B,CACjD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,gCAAgC,EAAE,CAAC,CAO7C;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,6BAA6B,EACpC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAOrC;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,6BAA6B,CAAC,CAExC;AAED,wBAAsB,gCAAgC,CACpD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,4BAA4B,CAAC,CAEvC;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,8BAA8B,EACrC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,2BAA2B,CAAC,CAOtC;AAED,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,kCAAkC,CAAC,CAO7C;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GACzC,OAAO,CAAC,yBAAyB,CAAC,CAQpC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createMagicPayClient, } from '@mercuryo-ai/magicpay-sdk';
|
|
2
|
+
import { claimRemoteSecret as claimRemoteSecretWithGateway, completeRemoteSession as completeRemoteSessionWithGateway, createRemoteSecretRequest as createRemoteSecretRequestWithGateway, createRemoteSessionEvent as createRemoteSessionEventWithGateway, getRemoteSecretRequest as getRemoteSecretRequestWithGateway, getRemoteSessionSecretCatalog as getRemoteSessionSecretCatalogWithGateway, } from '@mercuryo-ai/magicpay-sdk/session-client';
|
|
3
|
+
import { resolveMagicPayGatewayConfig } from './gateway.js';
|
|
4
|
+
export function getMagicPayClient(options = {}) {
|
|
5
|
+
return createMagicPayClient({
|
|
6
|
+
gateway: resolveMagicPayGatewayConfig(),
|
|
7
|
+
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export async function createRemoteSession(input, options = {}) {
|
|
11
|
+
return getMagicPayClient(options).sessions.create(input);
|
|
12
|
+
}
|
|
13
|
+
export async function getRemoteSession(sessionId, options = {}) {
|
|
14
|
+
return getMagicPayClient(options).sessions.get(sessionId);
|
|
15
|
+
}
|
|
16
|
+
export async function getRemoteSessionSecretCatalog(sessionId, host, options = {}) {
|
|
17
|
+
return getRemoteSessionSecretCatalogWithGateway(resolveMagicPayGatewayConfig(), sessionId, host, options);
|
|
18
|
+
}
|
|
19
|
+
export async function createRemoteSessionEvent(sessionId, input, options = {}) {
|
|
20
|
+
return createRemoteSessionEventWithGateway(resolveMagicPayGatewayConfig(), sessionId, input, options);
|
|
21
|
+
}
|
|
22
|
+
export async function completeRemoteSession(sessionId, input, options = {}) {
|
|
23
|
+
return completeRemoteSessionWithGateway(resolveMagicPayGatewayConfig(), sessionId, input, options);
|
|
24
|
+
}
|
|
25
|
+
export async function completeRemoteSessionWithOutcome(sessionId, input, options = {}) {
|
|
26
|
+
return getMagicPayClient(options).sessions.completeWithOutcome(sessionId, input);
|
|
27
|
+
}
|
|
28
|
+
export async function createRemoteSecretRequest(sessionId, input, options = {}) {
|
|
29
|
+
return createRemoteSecretRequestWithGateway(resolveMagicPayGatewayConfig(), sessionId, input, options);
|
|
30
|
+
}
|
|
31
|
+
export async function getRemoteSecretRequest(sessionId, requestId, options = {}) {
|
|
32
|
+
return getRemoteSecretRequestWithGateway(resolveMagicPayGatewayConfig(), sessionId, requestId, options);
|
|
33
|
+
}
|
|
34
|
+
export async function claimRemoteSecret(sessionId, requestId, claimId, options = {}) {
|
|
35
|
+
return claimRemoteSecretWithGateway(resolveMagicPayGatewayConfig(), sessionId, requestId, claimId, options);
|
|
36
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type CliUpdateNotice = {
|
|
2
|
+
command: string;
|
|
3
|
+
message: string;
|
|
4
|
+
};
|
|
5
|
+
export type CliUpdateCheckOptions = {
|
|
6
|
+
fetchImpl?: typeof fetch;
|
|
7
|
+
now?: Date;
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
ttlMs?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function compareVersions(left: string, right: string): number;
|
|
12
|
+
export declare function checkForCliUpdate(options?: CliUpdateCheckOptions): Promise<CliUpdateNotice | null>;
|
|
13
|
+
//# sourceMappingURL=update-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA8DnE;AAED,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA2BjC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { getMagicPayUpdateStatePath } from '@mercuryo-ai/magicpay-home';
|
|
4
|
+
import { readCurrentPackageVersion } from './package-version.js';
|
|
5
|
+
const PACKAGE_NAME = '@mercuryo-ai/magicpay-cli';
|
|
6
|
+
const REGISTRY_METADATA_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}`;
|
|
7
|
+
const DEFAULT_UPDATE_CHECK_TIMEOUT_MS = 1500;
|
|
8
|
+
const DEFAULT_UPDATE_TTL_MS = 12 * 60 * 60 * 1000;
|
|
9
|
+
export function compareVersions(left, right) {
|
|
10
|
+
const parsedLeft = parseVersion(left);
|
|
11
|
+
const parsedRight = parseVersion(right);
|
|
12
|
+
if (!parsedLeft || !parsedRight) {
|
|
13
|
+
return left.localeCompare(right, undefined, {
|
|
14
|
+
numeric: true,
|
|
15
|
+
sensitivity: 'base',
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
for (let i = 0; i < 3; i += 1) {
|
|
19
|
+
const diff = parsedLeft.core[i] - parsedRight.core[i];
|
|
20
|
+
if (diff !== 0) {
|
|
21
|
+
return diff;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!parsedLeft.prerelease && !parsedRight.prerelease) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
if (!parsedLeft.prerelease) {
|
|
28
|
+
return 1;
|
|
29
|
+
}
|
|
30
|
+
if (!parsedRight.prerelease) {
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
const length = Math.max(parsedLeft.prerelease.length, parsedRight.prerelease.length);
|
|
34
|
+
for (let i = 0; i < length; i += 1) {
|
|
35
|
+
const leftPart = parsedLeft.prerelease[i];
|
|
36
|
+
const rightPart = parsedRight.prerelease[i];
|
|
37
|
+
if (leftPart === undefined) {
|
|
38
|
+
return -1;
|
|
39
|
+
}
|
|
40
|
+
if (rightPart === undefined) {
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
if (typeof leftPart === 'number' && typeof rightPart === 'number') {
|
|
44
|
+
const diff = leftPart - rightPart;
|
|
45
|
+
if (diff !== 0) {
|
|
46
|
+
return diff;
|
|
47
|
+
}
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (typeof leftPart === 'number') {
|
|
51
|
+
return -1;
|
|
52
|
+
}
|
|
53
|
+
if (typeof rightPart === 'number') {
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
const diff = leftPart.localeCompare(rightPart);
|
|
57
|
+
if (diff !== 0) {
|
|
58
|
+
return diff;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
export async function checkForCliUpdate(options = {}) {
|
|
64
|
+
const currentVersion = readCurrentPackageVersion();
|
|
65
|
+
const now = options.now ?? new Date();
|
|
66
|
+
const ttlMs = options.ttlMs ?? DEFAULT_UPDATE_TTL_MS;
|
|
67
|
+
const cachedState = readUpdateState();
|
|
68
|
+
const cachedNotice = buildCliUpdateNotice(currentVersion, cachedState?.latestVersion);
|
|
69
|
+
if (cachedState && !isCacheStale(cachedState.lastCheckedAt, now, ttlMs)) {
|
|
70
|
+
return cachedNotice;
|
|
71
|
+
}
|
|
72
|
+
const latestVersion = await fetchLatestVersion({
|
|
73
|
+
fetchImpl: options.fetchImpl,
|
|
74
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_UPDATE_CHECK_TIMEOUT_MS,
|
|
75
|
+
}).catch(() => null);
|
|
76
|
+
if (!latestVersion) {
|
|
77
|
+
return cachedNotice;
|
|
78
|
+
}
|
|
79
|
+
writeUpdateState({
|
|
80
|
+
packageName: PACKAGE_NAME,
|
|
81
|
+
latestVersion,
|
|
82
|
+
lastCheckedAt: now.toISOString(),
|
|
83
|
+
});
|
|
84
|
+
return buildCliUpdateNotice(currentVersion, latestVersion);
|
|
85
|
+
}
|
|
86
|
+
function parseVersion(version) {
|
|
87
|
+
const match = version
|
|
88
|
+
.trim()
|
|
89
|
+
.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+.*)?$/);
|
|
90
|
+
if (!match) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const prerelease = match[4]
|
|
94
|
+
? match[4].split('.').map((part) => (/^\d+$/.test(part) ? Number(part) : part))
|
|
95
|
+
: null;
|
|
96
|
+
return {
|
|
97
|
+
core: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
98
|
+
prerelease,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function buildCliUpdateNotice(currentVersion, latestVersion) {
|
|
102
|
+
if (!latestVersion || compareVersions(latestVersion, currentVersion) <= 0) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const command = `npm i -g ${PACKAGE_NAME}@latest`;
|
|
106
|
+
return {
|
|
107
|
+
command,
|
|
108
|
+
message: `Update magicpay-cli before continuing. Run: ${command}. Then run magicpay --version and magicpay status again.`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function readUpdateState() {
|
|
112
|
+
const updateStatePath = getUpdateStatePath();
|
|
113
|
+
if (!existsSync(updateStatePath)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const raw = JSON.parse(readFileSync(updateStatePath, 'utf-8'));
|
|
118
|
+
if (raw.packageName !== PACKAGE_NAME ||
|
|
119
|
+
typeof raw.latestVersion !== 'string' ||
|
|
120
|
+
typeof raw.lastCheckedAt !== 'string') {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
packageName: raw.packageName,
|
|
125
|
+
latestVersion: raw.latestVersion,
|
|
126
|
+
lastCheckedAt: raw.lastCheckedAt,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function writeUpdateState(state) {
|
|
134
|
+
const updateStatePath = getUpdateStatePath();
|
|
135
|
+
mkdirSync(dirname(updateStatePath), { recursive: true });
|
|
136
|
+
writeFileSync(updateStatePath, JSON.stringify(state, null, 2) + '\n', 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
function isCacheStale(lastCheckedAt, now, ttlMs) {
|
|
139
|
+
const lastCheckedAtMs = new Date(lastCheckedAt).getTime();
|
|
140
|
+
if (!Number.isFinite(lastCheckedAtMs)) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
return now.getTime() - lastCheckedAtMs >= ttlMs;
|
|
144
|
+
}
|
|
145
|
+
async function fetchLatestVersion(options) {
|
|
146
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
147
|
+
if (typeof fetchImpl !== 'function') {
|
|
148
|
+
throw new Error('Global fetch is not available.');
|
|
149
|
+
}
|
|
150
|
+
const controller = new AbortController();
|
|
151
|
+
const timeout = setTimeout(() => controller.abort(), options.timeoutMs);
|
|
152
|
+
try {
|
|
153
|
+
const response = await fetchImpl(REGISTRY_METADATA_URL, {
|
|
154
|
+
headers: {
|
|
155
|
+
Accept: 'application/json',
|
|
156
|
+
},
|
|
157
|
+
signal: controller.signal,
|
|
158
|
+
});
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
throw new Error(`Registry responded with ${response.status}.`);
|
|
161
|
+
}
|
|
162
|
+
const metadata = (await response.json());
|
|
163
|
+
const latestVersion = metadata['dist-tags']?.latest;
|
|
164
|
+
if (!latestVersion || typeof latestVersion !== 'string') {
|
|
165
|
+
throw new Error('Registry metadata does not include dist-tags.latest.');
|
|
166
|
+
}
|
|
167
|
+
return latestVersion;
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
clearTimeout(timeout);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function getUpdateStatePath() {
|
|
174
|
+
return getMagicPayUpdateStatePath();
|
|
175
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MagicPaySession } from './workflow-state.js';
|
|
2
|
+
import { type CompleteRemoteSessionResponse } from './session-backend.js';
|
|
3
|
+
import { type StepCommand } from './run-store.js';
|
|
4
|
+
export type WorkflowSessionTerminalStatus = 'completed' | 'canceled' | 'error';
|
|
5
|
+
export type WorkflowRunTerminalStatus = 'completed' | 'aborted' | 'failed';
|
|
6
|
+
export type CompleteWorkflowSessionRemoteResult = {
|
|
7
|
+
success: true;
|
|
8
|
+
response: CompleteRemoteSessionResponse;
|
|
9
|
+
completedAt: string;
|
|
10
|
+
runId: string;
|
|
11
|
+
stepId: string | null;
|
|
12
|
+
} | {
|
|
13
|
+
success: false;
|
|
14
|
+
error: 'workflow_session_unavailable' | 'workflow_session_already_closed' | 'workflow_run_unavailable' | 'workflow_step_unavailable' | 'backend_session_complete_failed';
|
|
15
|
+
reason: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function formatUnknownWorkflowCompletionError(error: unknown): string;
|
|
18
|
+
export declare function completeWorkflowSessionRemote(params: {
|
|
19
|
+
session: MagicPaySession;
|
|
20
|
+
stepId: string | undefined;
|
|
21
|
+
command: StepCommand;
|
|
22
|
+
terminalStatus: WorkflowSessionTerminalStatus;
|
|
23
|
+
runStatus: WorkflowRunTerminalStatus;
|
|
24
|
+
summary: string;
|
|
25
|
+
outcomeType: string;
|
|
26
|
+
message: string;
|
|
27
|
+
reason?: string;
|
|
28
|
+
details?: Record<string, unknown>;
|
|
29
|
+
allowMissingStep?: boolean;
|
|
30
|
+
fetchImpl?: typeof fetch;
|
|
31
|
+
}): Promise<CompleteWorkflowSessionRemoteResult>;
|
|
32
|
+
//# sourceMappingURL=workflow-session-completion.d.ts.map
|