@proxy-checkout/cli 0.1.0-prx-128.104.1
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/LICENSE +21 -0
- package/README.md +128 -0
- package/dist/cjs/auth.d.cts +38 -0
- package/dist/cjs/auth.d.ts +38 -0
- package/dist/cjs/auth.js +258 -0
- package/dist/cjs/bin.d.cts +2 -0
- package/dist/cjs/bin.d.ts +2 -0
- package/dist/cjs/bin.js +10 -0
- package/dist/cjs/cli.d.cts +10 -0
- package/dist/cjs/cli.d.ts +10 -0
- package/dist/cjs/cli.js +469 -0
- package/dist/cjs/command-schema.d.cts +23 -0
- package/dist/cjs/command-schema.d.ts +23 -0
- package/dist/cjs/command-schema.js +238 -0
- package/dist/cjs/config.d.cts +55 -0
- package/dist/cjs/config.d.ts +55 -0
- package/dist/cjs/config.js +339 -0
- package/dist/cjs/errors.d.cts +20 -0
- package/dist/cjs/errors.d.ts +20 -0
- package/dist/cjs/errors.js +52 -0
- package/dist/cjs/http-client.d.cts +25 -0
- package/dist/cjs/http-client.d.ts +25 -0
- package/dist/cjs/http-client.js +102 -0
- package/dist/cjs/index.d.cts +5 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +17 -0
- package/dist/cjs/output.d.cts +19 -0
- package/dist/cjs/output.d.ts +19 -0
- package/dist/cjs/output.js +76 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/webhooks.d.cts +81 -0
- package/dist/cjs/webhooks.d.ts +81 -0
- package/dist/cjs/webhooks.js +343 -0
- package/dist/esm/auth.d.ts +38 -0
- package/dist/esm/auth.js +253 -0
- package/dist/esm/bin.d.ts +2 -0
- package/dist/esm/bin.js +8 -0
- package/dist/esm/cli.d.ts +10 -0
- package/dist/esm/cli.js +465 -0
- package/dist/esm/command-schema.d.ts +23 -0
- package/dist/esm/command-schema.js +232 -0
- package/dist/esm/config.d.ts +55 -0
- package/dist/esm/config.js +333 -0
- package/dist/esm/errors.d.ts +20 -0
- package/dist/esm/errors.js +46 -0
- package/dist/esm/http-client.d.ts +25 -0
- package/dist/esm/http-client.js +98 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/output.d.ts +19 -0
- package/dist/esm/output.js +71 -0
- package/dist/esm/webhooks.d.ts +81 -0
- package/dist/esm/webhooks.js +337 -0
- package/package.json +68 -0
package/dist/cjs/cli.js
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cliVersion = void 0;
|
|
4
|
+
exports.runCli = runCli;
|
|
5
|
+
const promises_1 = require("node:readline/promises");
|
|
6
|
+
const auth_js_1 = require("./auth.js");
|
|
7
|
+
const command_schema_js_1 = require("./command-schema.js");
|
|
8
|
+
const config_js_1 = require("./config.js");
|
|
9
|
+
const errors_js_1 = require("./errors.js");
|
|
10
|
+
const output_js_1 = require("./output.js");
|
|
11
|
+
const webhooks_js_1 = require("./webhooks.js");
|
|
12
|
+
exports.cliVersion = "0.1.0-prx-128.104.1";
|
|
13
|
+
async function runCli(argv, options = {}) {
|
|
14
|
+
const io = options.io ?? {
|
|
15
|
+
isTTY: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
16
|
+
stderr: process.stderr,
|
|
17
|
+
stdin: process.stdin,
|
|
18
|
+
stdout: process.stdout,
|
|
19
|
+
};
|
|
20
|
+
let output = new output_js_1.CliOutput(io.isTTY ? "human" : "jsonl", io);
|
|
21
|
+
let processSignal;
|
|
22
|
+
try {
|
|
23
|
+
const parsedGlobals = parseGlobalOptions([...argv], io, options.environment ?? process.env);
|
|
24
|
+
output = new output_js_1.CliOutput(parsedGlobals.options.format, io);
|
|
25
|
+
if (parsedGlobals.options.version) {
|
|
26
|
+
output.result({ version: exports.cliVersion }, `proxy ${exports.cliVersion}`);
|
|
27
|
+
return errors_js_1.cliExitCodes.success;
|
|
28
|
+
}
|
|
29
|
+
if (parsedGlobals.options.llmsFull) {
|
|
30
|
+
const document = (0, command_schema_js_1.llmsFullDocument)();
|
|
31
|
+
output.result({ document, schema_version: "2026-07-14" }, document);
|
|
32
|
+
return errors_js_1.cliExitCodes.success;
|
|
33
|
+
}
|
|
34
|
+
if (parsedGlobals.args.join(" ") === "commands schema") {
|
|
35
|
+
output.result((0, command_schema_js_1.commandSchemaDocument)(), JSON.stringify((0, command_schema_js_1.commandSchemaDocument)(), null, 2));
|
|
36
|
+
return errors_js_1.cliExitCodes.success;
|
|
37
|
+
}
|
|
38
|
+
const matched = matchCommand(parsedGlobals.args);
|
|
39
|
+
if (parsedGlobals.options.schema) {
|
|
40
|
+
if (!matched)
|
|
41
|
+
throw (0, errors_js_1.usageError)("Unknown command for --schema");
|
|
42
|
+
const schema = (0, command_schema_js_1.commandSchemaDocument)(matched.command.path);
|
|
43
|
+
if (!schema)
|
|
44
|
+
throw (0, errors_js_1.usageError)("Unknown command for --schema");
|
|
45
|
+
output.result(schema, JSON.stringify(schema, null, 2));
|
|
46
|
+
return errors_js_1.cliExitCodes.success;
|
|
47
|
+
}
|
|
48
|
+
if (!matched || parsedGlobals.options.help) {
|
|
49
|
+
output.result({ commands: command_schema_js_1.commandSchemas.map((command) => command.path), version: exports.cliVersion }, matched ? commandHelp(matched.command) : rootHelp());
|
|
50
|
+
return matched || parsedGlobals.options.help ? errors_js_1.cliExitCodes.success : errors_js_1.cliExitCodes.usage;
|
|
51
|
+
}
|
|
52
|
+
if (matched.command.streaming && parsedGlobals.options.format === "json") {
|
|
53
|
+
throw (0, errors_js_1.usageError)("Streaming commands require --format jsonl or human");
|
|
54
|
+
}
|
|
55
|
+
assertRequestedMode(matched.command, parsedGlobals.options.expectedMode);
|
|
56
|
+
const commandOptions = parseCommandOptions(matched.args, matched.command.options);
|
|
57
|
+
const configStore = options.configStore ??
|
|
58
|
+
new config_js_1.CliConfigStore({ environment: options.environment ?? process.env });
|
|
59
|
+
const profileName = configStore.profileName(parsedGlobals.options.profileName ?? readOptionalString(commandOptions, "--profile"));
|
|
60
|
+
const requestedApiBase = parsedGlobals.options.apiBaseUrl ?? readOptionalString(commandOptions, "--api-base");
|
|
61
|
+
processSignal = options.signal ? undefined : createProcessSignal();
|
|
62
|
+
const signal = options.signal ?? processSignal?.signal;
|
|
63
|
+
if (!signal)
|
|
64
|
+
throw new Error("CLI abort signal was not initialized");
|
|
65
|
+
await executeCommand({
|
|
66
|
+
command: matched.command,
|
|
67
|
+
configStore,
|
|
68
|
+
expectedMerchantId: parsedGlobals.options.expectedMerchantId,
|
|
69
|
+
expectedMode: parsedGlobals.options.expectedMode,
|
|
70
|
+
io,
|
|
71
|
+
noInput: parsedGlobals.options.noInput,
|
|
72
|
+
options: commandOptions,
|
|
73
|
+
output,
|
|
74
|
+
profileName,
|
|
75
|
+
requestedApiBase,
|
|
76
|
+
signal,
|
|
77
|
+
});
|
|
78
|
+
return errors_js_1.cliExitCodes.success;
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
const cliError = (0, errors_js_1.asCliError)(error);
|
|
82
|
+
output.error(cliError);
|
|
83
|
+
return cliError.exitCode;
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
processSignal?.dispose();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function executeCommand(input) {
|
|
90
|
+
if (input.command.path === "auth login") {
|
|
91
|
+
const existingProfile = await input.configStore.readProfile(input.profileName);
|
|
92
|
+
const apiBaseUrl = input.configStore.apiBaseUrl(input.requestedApiBase, existingProfile);
|
|
93
|
+
const profile = await (0, auth_js_1.login)({
|
|
94
|
+
apiBaseUrl,
|
|
95
|
+
configStore: input.configStore,
|
|
96
|
+
expectedMerchantId: input.expectedMerchantId,
|
|
97
|
+
expectedMode: input.expectedMode,
|
|
98
|
+
name: readOptionalString(input.options, "--name"),
|
|
99
|
+
noBrowser: readBoolean(input.options, "--no-browser"),
|
|
100
|
+
output: input.output,
|
|
101
|
+
profileName: input.profileName,
|
|
102
|
+
signal: input.signal,
|
|
103
|
+
});
|
|
104
|
+
input.output.result(publicProfile(input.profileName, profile), `Authenticated profile ${input.profileName} for test merchant ${profile.merchantId}.`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const resolved = await input.configStore.resolveCredential({
|
|
108
|
+
apiBaseUrl: input.requestedApiBase,
|
|
109
|
+
profileName: input.profileName,
|
|
110
|
+
});
|
|
111
|
+
if (input.command.path === "auth status") {
|
|
112
|
+
const remoteProfile = await (0, auth_js_1.status)(resolved);
|
|
113
|
+
assertRemoteTarget(remoteProfile, input);
|
|
114
|
+
input.output.result({
|
|
115
|
+
profile: {
|
|
116
|
+
...remoteProfile,
|
|
117
|
+
credential_source: resolved.source,
|
|
118
|
+
profile: resolved.profileName,
|
|
119
|
+
},
|
|
120
|
+
}, `Profile ${resolved.profileName} is authenticated for ${remoteProfile.merchant_id} (${remoteProfile.mode}).`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (input.command.path === "auth logout") {
|
|
124
|
+
if (input.expectedMerchantId || input.expectedMode) {
|
|
125
|
+
assertRemoteTarget(await (0, auth_js_1.status)(resolved), input);
|
|
126
|
+
}
|
|
127
|
+
await (0, auth_js_1.logout)({
|
|
128
|
+
apiBaseUrl: resolved.apiBaseUrl,
|
|
129
|
+
configStore: input.configStore,
|
|
130
|
+
profileName: resolved.profileName,
|
|
131
|
+
removeLocalProfile: resolved.source !== "environment",
|
|
132
|
+
token: resolved.token,
|
|
133
|
+
});
|
|
134
|
+
input.output.result({ profile: resolved.profileName, revoked: true }, `Logged out profile ${resolved.profileName}.`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (input.expectedMerchantId || input.expectedMode) {
|
|
138
|
+
assertRemoteTarget(await (0, auth_js_1.status)(resolved), input);
|
|
139
|
+
}
|
|
140
|
+
const webhooks = new webhooks_js_1.ProxyWebhooksClient(resolved.apiBaseUrl, resolved.token);
|
|
141
|
+
if (input.command.path === "webhooks endpoints list") {
|
|
142
|
+
const endpoints = await webhooks.listEndpoints();
|
|
143
|
+
input.output.result({ webhook_endpoints: endpoints }, formatEndpointList(endpoints));
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (input.command.path === "webhooks listeners create") {
|
|
147
|
+
const listener = await webhooks.createListener(readRequiredString(input.options, "--endpoint"));
|
|
148
|
+
input.output.result({ listener }, `Created listener ${listener.id}; lease expires ${listener.lease_expires_at}.`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (input.command.path === "webhooks listeners status") {
|
|
152
|
+
const listener = await webhooks.getListener(readRequiredString(input.options, "--listener"));
|
|
153
|
+
input.output.result({ listener }, `Listener ${listener.id} is ${listener.status}; lease expires ${listener.lease_expires_at}.`);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (input.command.path === "webhooks listeners heartbeat") {
|
|
157
|
+
const listener = await webhooks.heartbeat(readRequiredString(input.options, "--listener"));
|
|
158
|
+
input.output.result({ listener }, `Extended listener ${listener.id} through ${listener.lease_expires_at}.`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (input.command.path === "webhooks listeners close") {
|
|
162
|
+
const listener = await webhooks.close(readRequiredString(input.options, "--listener"));
|
|
163
|
+
input.output.result({ listener }, `Closed listener ${listener.id}.`);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (input.command.path === "webhooks deliveries list") {
|
|
167
|
+
const deliveries = await webhooks.listDeliveries(readRequiredString(input.options, "--listener"), readOptionalInteger(input.options, "--limit"));
|
|
168
|
+
input.output.result({ deliveries }, `${deliveries.length} local webhook deliveries.`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (input.command.path === "webhooks deliveries replay") {
|
|
172
|
+
const replay = await webhooks.replay(readRequiredString(input.options, "--listener"), readRequiredString(input.options, "--delivery"), readRequiredString(input.options, "--reason"));
|
|
173
|
+
input.output.result(replay, "Replay scheduled.");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (input.command.path === "webhooks deliveries forward") {
|
|
177
|
+
const deliveryId = readOptionalString(input.options, "--delivery");
|
|
178
|
+
const replayOutboxEventId = readOptionalString(input.options, "--replay-outbox");
|
|
179
|
+
if (Number(Boolean(deliveryId)) + Number(Boolean(replayOutboxEventId)) !== 1) {
|
|
180
|
+
throw (0, errors_js_1.usageError)("Exactly one of --delivery or --replay-outbox is required");
|
|
181
|
+
}
|
|
182
|
+
const result = await (0, webhooks_js_1.forwardSelectedDelivery)({
|
|
183
|
+
client: webhooks,
|
|
184
|
+
...(deliveryId ? { deliveryId } : {}),
|
|
185
|
+
forwardTo: readRequiredString(input.options, "--forward-to"),
|
|
186
|
+
listenerId: readRequiredString(input.options, "--listener"),
|
|
187
|
+
...(replayOutboxEventId ? { replayOutboxEventId } : {}),
|
|
188
|
+
signal: input.signal,
|
|
189
|
+
});
|
|
190
|
+
input.output.result(result, `Forwarded selected delivery ${result.webhook_delivery_id}.`);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (input.command.path === "listen") {
|
|
194
|
+
const endpoints = await webhooks.listEndpoints();
|
|
195
|
+
const sourceEndpointId = await selectEndpoint({
|
|
196
|
+
endpoints,
|
|
197
|
+
io: input.io,
|
|
198
|
+
noInput: input.noInput,
|
|
199
|
+
output: input.output,
|
|
200
|
+
requested: readOptionalString(input.options, "--endpoint"),
|
|
201
|
+
});
|
|
202
|
+
const maxEvents = readOptionalInteger(input.options, "--max-events") ?? 0;
|
|
203
|
+
if (maxEvents < 0)
|
|
204
|
+
throw (0, errors_js_1.usageError)("--max-events must be zero or greater");
|
|
205
|
+
await (0, webhooks_js_1.runListener)({
|
|
206
|
+
client: webhooks,
|
|
207
|
+
forwardTo: readRequiredString(input.options, "--forward-to"),
|
|
208
|
+
maxEvents,
|
|
209
|
+
output: input.output,
|
|
210
|
+
pspConfigId: readOptionalString(input.options, "--stripe-psp-config"),
|
|
211
|
+
signal: input.signal,
|
|
212
|
+
sourceEndpointId,
|
|
213
|
+
stripe: readBoolean(input.options, "--stripe"),
|
|
214
|
+
});
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
throw (0, errors_js_1.usageError)(`Unsupported command: ${input.command.path}`);
|
|
218
|
+
}
|
|
219
|
+
function parseGlobalOptions(args, io, environment) {
|
|
220
|
+
const defaultFormat = io.isTTY ? "human" : "jsonl";
|
|
221
|
+
const options = {
|
|
222
|
+
format: parseFormat(environment.PROXY_FORMAT ?? defaultFormat),
|
|
223
|
+
help: false,
|
|
224
|
+
llmsFull: false,
|
|
225
|
+
noInput: false,
|
|
226
|
+
schema: false,
|
|
227
|
+
version: false,
|
|
228
|
+
};
|
|
229
|
+
const remaining = [];
|
|
230
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
231
|
+
const argument = args[index];
|
|
232
|
+
const [name, inlineValue] = splitOption(argument);
|
|
233
|
+
if (name === "--format" ||
|
|
234
|
+
name === "--profile" ||
|
|
235
|
+
name === "--api-base" ||
|
|
236
|
+
name === "--merchant" ||
|
|
237
|
+
name === "--mode") {
|
|
238
|
+
const value = inlineValue ?? args[index + 1];
|
|
239
|
+
if (!value || value.startsWith("--"))
|
|
240
|
+
throw (0, errors_js_1.usageError)(`${name} requires a value`);
|
|
241
|
+
if (inlineValue === undefined)
|
|
242
|
+
index += 1;
|
|
243
|
+
if (name === "--format")
|
|
244
|
+
options.format = parseFormat(value);
|
|
245
|
+
if (name === "--profile")
|
|
246
|
+
options.profileName = value;
|
|
247
|
+
if (name === "--api-base")
|
|
248
|
+
options.apiBaseUrl = value;
|
|
249
|
+
if (name === "--merchant") {
|
|
250
|
+
if (!/^merch_[A-Za-z0-9_-]+$/.test(value)) {
|
|
251
|
+
throw (0, errors_js_1.usageError)("--merchant must be a Proxy merchant ID");
|
|
252
|
+
}
|
|
253
|
+
options.expectedMerchantId = value;
|
|
254
|
+
}
|
|
255
|
+
if (name === "--mode") {
|
|
256
|
+
if (value !== "test" && value !== "live") {
|
|
257
|
+
throw (0, errors_js_1.usageError)("--mode must be test or live");
|
|
258
|
+
}
|
|
259
|
+
options.expectedMode = value;
|
|
260
|
+
}
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
if (name === "--no-input")
|
|
264
|
+
options.noInput = true;
|
|
265
|
+
else if (name === "--schema")
|
|
266
|
+
options.schema = true;
|
|
267
|
+
else if (name === "--llms-full")
|
|
268
|
+
options.llmsFull = true;
|
|
269
|
+
else if (name === "--help" || name === "-h")
|
|
270
|
+
options.help = true;
|
|
271
|
+
else if (name === "--version" || name === "-v")
|
|
272
|
+
options.version = true;
|
|
273
|
+
else
|
|
274
|
+
remaining.push(argument);
|
|
275
|
+
}
|
|
276
|
+
return { args: remaining, options };
|
|
277
|
+
}
|
|
278
|
+
function parseCommandOptions(args, schemas) {
|
|
279
|
+
const allowed = new Map(schemas.map((schema) => [schema.name, schema]));
|
|
280
|
+
const values = new Map();
|
|
281
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
282
|
+
const argument = args[index];
|
|
283
|
+
if (!argument.startsWith("--"))
|
|
284
|
+
throw (0, errors_js_1.usageError)(`Unexpected argument: ${argument}`);
|
|
285
|
+
const [name, inlineValue] = splitOption(argument);
|
|
286
|
+
const schema = allowed.get(name);
|
|
287
|
+
if (!schema)
|
|
288
|
+
throw (0, errors_js_1.usageError)(`Unknown option for this command: ${name}`);
|
|
289
|
+
if (values.has(schema.name))
|
|
290
|
+
throw (0, errors_js_1.usageError)(`Option may be specified only once: ${name}`);
|
|
291
|
+
if (schema.type === "boolean") {
|
|
292
|
+
if (inlineValue !== undefined)
|
|
293
|
+
throw (0, errors_js_1.usageError)(`${name} does not accept a value`);
|
|
294
|
+
values.set(schema.name, true);
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
const raw = inlineValue ?? args[index + 1];
|
|
298
|
+
if (!raw || raw.startsWith("--"))
|
|
299
|
+
throw (0, errors_js_1.usageError)(`${name} requires a value`);
|
|
300
|
+
if (inlineValue === undefined)
|
|
301
|
+
index += 1;
|
|
302
|
+
if (schema.type === "integer") {
|
|
303
|
+
if (!/^-?\d+$/.test(raw))
|
|
304
|
+
throw (0, errors_js_1.usageError)(`${name} requires an integer`);
|
|
305
|
+
values.set(schema.name, Number(raw));
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
values.set(schema.name, raw);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
for (const schema of schemas) {
|
|
312
|
+
if (schema.required && !values.has(schema.name)) {
|
|
313
|
+
throw (0, errors_js_1.usageError)(`Missing required option: ${schema.name}`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return values;
|
|
317
|
+
}
|
|
318
|
+
function matchCommand(args) {
|
|
319
|
+
const sorted = [...command_schema_js_1.commandSchemas].sort((left, right) => right.path.split(" ").length - left.path.split(" ").length);
|
|
320
|
+
for (const command of sorted) {
|
|
321
|
+
const parts = command.path.split(" ");
|
|
322
|
+
if (parts.every((part, index) => args[index] === part)) {
|
|
323
|
+
return { args: args.slice(parts.length), command };
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
async function selectEndpoint(input) {
|
|
329
|
+
if (input.requested) {
|
|
330
|
+
if (!input.endpoints.some((endpoint) => endpoint.id === input.requested)) {
|
|
331
|
+
throw new errors_js_1.CliError("Requested source endpoint is not active or does not belong to this merchant", "cli_source_endpoint_not_found", errors_js_1.cliExitCodes.conflict);
|
|
332
|
+
}
|
|
333
|
+
return input.requested;
|
|
334
|
+
}
|
|
335
|
+
if (input.endpoints.length === 0) {
|
|
336
|
+
throw new errors_js_1.CliError("No active HTTPS webhook endpoint is available as a relay source", "cli_source_endpoint_required", errors_js_1.cliExitCodes.conflict);
|
|
337
|
+
}
|
|
338
|
+
if (input.endpoints.length === 1)
|
|
339
|
+
return input.endpoints[0].id;
|
|
340
|
+
if (input.noInput || !input.io.isTTY) {
|
|
341
|
+
throw (0, errors_js_1.usageError)("Multiple source endpoints are available; pass --endpoint with --no-input");
|
|
342
|
+
}
|
|
343
|
+
input.output.notice(input.endpoints
|
|
344
|
+
.map((endpoint, index) => `${index + 1}. ${endpoint.id} — ${endpoint.url}`)
|
|
345
|
+
.join("\n"));
|
|
346
|
+
const prompt = (0, promises_1.createInterface)({
|
|
347
|
+
input: input.io.stdin,
|
|
348
|
+
output: input.io.stderr,
|
|
349
|
+
});
|
|
350
|
+
try {
|
|
351
|
+
const answer = await prompt.question("Select a source endpoint number: ");
|
|
352
|
+
const selected = input.endpoints[Number(answer) - 1];
|
|
353
|
+
if (!selected)
|
|
354
|
+
throw (0, errors_js_1.usageError)("Invalid endpoint selection");
|
|
355
|
+
return selected.id;
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
prompt.close();
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function publicProfile(profileName, profile) {
|
|
362
|
+
return {
|
|
363
|
+
profile: {
|
|
364
|
+
api_base_url: profile.apiBaseUrl,
|
|
365
|
+
api_version: profile.apiVersion,
|
|
366
|
+
capability_version: profile.capabilityVersion,
|
|
367
|
+
credential_id: profile.credentialId,
|
|
368
|
+
credential_store: profile.credentialStore,
|
|
369
|
+
expires_at: profile.expiresAt,
|
|
370
|
+
merchant_id: profile.merchantId,
|
|
371
|
+
mode: profile.mode,
|
|
372
|
+
name: profile.name,
|
|
373
|
+
organization_id: profile.organizationId,
|
|
374
|
+
profile: profileName,
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function formatEndpointList(endpoints) {
|
|
379
|
+
return endpoints.length === 0
|
|
380
|
+
? "No active HTTPS webhook endpoints."
|
|
381
|
+
: endpoints.map((endpoint) => `${endpoint.id}\t${endpoint.url}`).join("\n");
|
|
382
|
+
}
|
|
383
|
+
function parseFormat(value) {
|
|
384
|
+
if (value === "human" || value === "json" || value === "jsonl")
|
|
385
|
+
return value;
|
|
386
|
+
throw (0, errors_js_1.usageError)("--format must be human, json, or jsonl");
|
|
387
|
+
}
|
|
388
|
+
function assertRequestedMode(command, mode) {
|
|
389
|
+
if (!mode || command.modes.includes(mode)) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
throw new errors_js_1.CliError(mode === "live"
|
|
393
|
+
? "This CLI command is not enabled for live mode"
|
|
394
|
+
: "This CLI command is not enabled for the requested mode", mode === "live" ? "cli_live_mode_not_enabled" : "cli_mode_not_allowed", errors_js_1.cliExitCodes.permission);
|
|
395
|
+
}
|
|
396
|
+
function assertRemoteTarget(profile, expected) {
|
|
397
|
+
if (expected.expectedMerchantId && profile.merchant_id !== expected.expectedMerchantId) {
|
|
398
|
+
throw new errors_js_1.CliError("The CLI credential does not match the requested merchant", "cli_merchant_not_allowed", errors_js_1.cliExitCodes.permission);
|
|
399
|
+
}
|
|
400
|
+
if (expected.expectedMode && profile.mode !== expected.expectedMode) {
|
|
401
|
+
throw new errors_js_1.CliError("The CLI credential does not match the requested mode", expected.expectedMode === "live" ? "cli_live_mode_not_enabled" : "cli_mode_not_allowed", errors_js_1.cliExitCodes.permission);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function splitOption(value) {
|
|
405
|
+
const separator = value.indexOf("=");
|
|
406
|
+
return separator < 0
|
|
407
|
+
? [value, undefined]
|
|
408
|
+
: [value.slice(0, separator), value.slice(separator + 1)];
|
|
409
|
+
}
|
|
410
|
+
function readRequiredString(values, name) {
|
|
411
|
+
const value = values.get(name);
|
|
412
|
+
if (typeof value !== "string")
|
|
413
|
+
throw (0, errors_js_1.usageError)(`Missing required option: ${name}`);
|
|
414
|
+
return value;
|
|
415
|
+
}
|
|
416
|
+
function readOptionalString(values, name) {
|
|
417
|
+
const value = values.get(name);
|
|
418
|
+
return typeof value === "string" ? value : undefined;
|
|
419
|
+
}
|
|
420
|
+
function readOptionalInteger(values, name) {
|
|
421
|
+
const value = values.get(name);
|
|
422
|
+
return typeof value === "number" ? value : undefined;
|
|
423
|
+
}
|
|
424
|
+
function readBoolean(values, name) {
|
|
425
|
+
return values.get(name) === true;
|
|
426
|
+
}
|
|
427
|
+
function createProcessSignal() {
|
|
428
|
+
const controller = new AbortController();
|
|
429
|
+
const abort = () => controller.abort();
|
|
430
|
+
process.once("SIGINT", abort);
|
|
431
|
+
process.once("SIGTERM", abort);
|
|
432
|
+
return {
|
|
433
|
+
signal: controller.signal,
|
|
434
|
+
dispose() {
|
|
435
|
+
process.removeListener("SIGINT", abort);
|
|
436
|
+
process.removeListener("SIGTERM", abort);
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function rootHelp() {
|
|
441
|
+
return [
|
|
442
|
+
`Proxy CLI ${exports.cliVersion}`,
|
|
443
|
+
"",
|
|
444
|
+
"Usage: proxy <command> [options]",
|
|
445
|
+
"",
|
|
446
|
+
...command_schema_js_1.commandSchemas.map((command) => ` ${command.path.padEnd(31)} ${command.description}`),
|
|
447
|
+
"",
|
|
448
|
+
"Global options:",
|
|
449
|
+
" --format human|json|jsonl Structured output (non-TTY default: jsonl)",
|
|
450
|
+
" --no-input Prohibit prompts",
|
|
451
|
+
" --profile NAME Credential profile",
|
|
452
|
+
" --merchant ID Assert the target merchant",
|
|
453
|
+
" --mode test|live Assert the command mode",
|
|
454
|
+
" --api-base URL Proxy API base URL",
|
|
455
|
+
" --schema Print a command's machine-readable schema",
|
|
456
|
+
" --llms-full Print the complete agent-facing command reference",
|
|
457
|
+
" --help Show help",
|
|
458
|
+
" --version Show version",
|
|
459
|
+
].join("\n");
|
|
460
|
+
}
|
|
461
|
+
function commandHelp(command) {
|
|
462
|
+
return [
|
|
463
|
+
`Usage: proxy ${command.path} [options]`,
|
|
464
|
+
"",
|
|
465
|
+
command.description,
|
|
466
|
+
"",
|
|
467
|
+
...command.options.map((option) => ` ${option.name.padEnd(24)} ${option.description}`),
|
|
468
|
+
].join("\n");
|
|
469
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type CommandOptionType = "boolean" | "integer" | "string";
|
|
2
|
+
export interface CommandOptionSchema {
|
|
3
|
+
description: string;
|
|
4
|
+
env?: string;
|
|
5
|
+
name: `--${string}`;
|
|
6
|
+
required?: boolean;
|
|
7
|
+
sensitive?: boolean;
|
|
8
|
+
type: CommandOptionType;
|
|
9
|
+
}
|
|
10
|
+
export interface CommandSchema {
|
|
11
|
+
capabilities: string[];
|
|
12
|
+
description: string;
|
|
13
|
+
interactive: boolean;
|
|
14
|
+
modes: Array<"test" | "live">;
|
|
15
|
+
options: CommandOptionSchema[];
|
|
16
|
+
output: string;
|
|
17
|
+
path: string;
|
|
18
|
+
streaming?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare const commandSchemas: readonly CommandSchema[];
|
|
21
|
+
export declare function findCommandSchema(path: string): CommandSchema | undefined;
|
|
22
|
+
export declare function commandSchemaDocument(path?: string): unknown;
|
|
23
|
+
export declare function llmsFullDocument(): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type CommandOptionType = "boolean" | "integer" | "string";
|
|
2
|
+
export interface CommandOptionSchema {
|
|
3
|
+
description: string;
|
|
4
|
+
env?: string;
|
|
5
|
+
name: `--${string}`;
|
|
6
|
+
required?: boolean;
|
|
7
|
+
sensitive?: boolean;
|
|
8
|
+
type: CommandOptionType;
|
|
9
|
+
}
|
|
10
|
+
export interface CommandSchema {
|
|
11
|
+
capabilities: string[];
|
|
12
|
+
description: string;
|
|
13
|
+
interactive: boolean;
|
|
14
|
+
modes: Array<"test" | "live">;
|
|
15
|
+
options: CommandOptionSchema[];
|
|
16
|
+
output: string;
|
|
17
|
+
path: string;
|
|
18
|
+
streaming?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare const commandSchemas: readonly CommandSchema[];
|
|
21
|
+
export declare function findCommandSchema(path: string): CommandSchema | undefined;
|
|
22
|
+
export declare function commandSchemaDocument(path?: string): unknown;
|
|
23
|
+
export declare function llmsFullDocument(): string;
|