@amaretto-software-labs/borealis-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.
Files changed (52) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +112 -0
  3. package/dist/api-client.d.ts +36 -0
  4. package/dist/api-client.js +673 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/app.d.ts +6 -0
  7. package/dist/app.js +344 -0
  8. package/dist/app.js.map +1 -0
  9. package/dist/auth.d.ts +16 -0
  10. package/dist/auth.js +506 -0
  11. package/dist/auth.js.map +1 -0
  12. package/dist/catalog.d.ts +6 -0
  13. package/dist/catalog.js +15 -0
  14. package/dist/catalog.js.map +1 -0
  15. package/dist/command-grammar.d.ts +3 -0
  16. package/dist/command-grammar.js +274 -0
  17. package/dist/command-grammar.js.map +1 -0
  18. package/dist/completion.d.ts +1 -0
  19. package/dist/completion.js +18 -0
  20. package/dist/completion.js.map +1 -0
  21. package/dist/config.d.ts +11 -0
  22. package/dist/config.js +55 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/credential-file.d.ts +1 -0
  25. package/dist/credential-file.js +41 -0
  26. package/dist/credential-file.js.map +1 -0
  27. package/dist/http-timeout.d.ts +5 -0
  28. package/dist/http-timeout.js +10 -0
  29. package/dist/http-timeout.js.map +1 -0
  30. package/dist/interactive.d.ts +4 -0
  31. package/dist/interactive.js +158 -0
  32. package/dist/interactive.js.map +1 -0
  33. package/dist/invocation.d.ts +13 -0
  34. package/dist/invocation.js +526 -0
  35. package/dist/invocation.js.map +1 -0
  36. package/dist/main.d.ts +2 -0
  37. package/dist/main.js +14 -0
  38. package/dist/main.js.map +1 -0
  39. package/dist/operations.json +1127 -0
  40. package/dist/output.d.ts +1 -0
  41. package/dist/output.js +32 -0
  42. package/dist/output.js.map +1 -0
  43. package/dist/secret-file.d.ts +1 -0
  44. package/dist/secret-file.js +19 -0
  45. package/dist/secret-file.js.map +1 -0
  46. package/dist/session-store.d.ts +54 -0
  47. package/dist/session-store.js +470 -0
  48. package/dist/session-store.js.map +1 -0
  49. package/dist/types.d.ts +67 -0
  50. package/dist/types.js +28 -0
  51. package/dist/types.js.map +1 -0
  52. package/package.json +54 -0
package/dist/auth.js ADDED
@@ -0,0 +1,506 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { createServer } from "node:http";
3
+ import { execFile } from "node:child_process";
4
+ import { promisify } from "node:util";
5
+ import { z } from "zod";
6
+ import { defaults, validateLoginScope, validateOrigin } from "./config.js";
7
+ import { loadSession, saveSession } from "./session-store.js";
8
+ import { readOwnerOnlySecretFile } from "./secret-file.js";
9
+ import { createRequestDeadline } from "./http-timeout.js";
10
+ const execFileAsync = promisify(execFile);
11
+ const tokenSchema = z.object({
12
+ access_token: z.string().min(1),
13
+ token_type: z.string().refine((value) => value.toLowerCase() === "bearer"),
14
+ expires_in: z.number().int().positive(),
15
+ refresh_token: z.string().min(1).optional(),
16
+ scope: z.string().default(""),
17
+ });
18
+ function base64Url(value) {
19
+ return value.toString("base64url");
20
+ }
21
+ const callbackPageStyles = `
22
+ :root {
23
+ color-scheme: dark;
24
+ --color-bg: #06131f;
25
+ --color-panel: #0b1b2b;
26
+ --color-border: #1d3b4d;
27
+ --color-text: #c9dce3;
28
+ --color-text-muted: #91aab5;
29
+ --color-text-bright: #eaf7fa;
30
+ --color-accent: #38f5c8;
31
+ --color-success: #4ade80;
32
+ --color-error: #fb7185;
33
+ --color-input: #102638;
34
+ --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4);
35
+ --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
36
+ --font-mono: Consolas, Monaco, "Courier New", monospace;
37
+ }
38
+
39
+ * { box-sizing: border-box; }
40
+
41
+ html, body { min-height: 100%; }
42
+
43
+ body {
44
+ margin: 0;
45
+ min-width: 320px;
46
+ color: var(--color-text);
47
+ background:
48
+ radial-gradient(circle at 50% -15%, rgba(78, 223, 245, 0.13), transparent 38rem),
49
+ radial-gradient(circle at 90% 100%, rgba(56, 245, 200, 0.08), transparent 30rem),
50
+ var(--color-bg);
51
+ font-family: var(--font-sans);
52
+ font-size: 14px;
53
+ line-height: 1.5;
54
+ -webkit-font-smoothing: antialiased;
55
+ }
56
+
57
+ .shell {
58
+ min-height: 100vh;
59
+ display: grid;
60
+ place-items: center;
61
+ padding: 24px 16px;
62
+ }
63
+
64
+ .card {
65
+ width: min(100%, 480px);
66
+ padding: 32px;
67
+ border: 1px solid var(--color-border);
68
+ border-radius: 8px;
69
+ background: var(--color-panel);
70
+ background: color-mix(in srgb, var(--color-panel) 96%, transparent);
71
+ box-shadow: var(--shadow-lg);
72
+ }
73
+
74
+ .brand {
75
+ display: flex;
76
+ align-items: center;
77
+ gap: 10px;
78
+ margin-bottom: 32px;
79
+ color: var(--color-text-bright);
80
+ font-size: 13px;
81
+ font-weight: 600;
82
+ letter-spacing: 0.12em;
83
+ text-transform: uppercase;
84
+ }
85
+
86
+ .brand-mark { width: 32px; height: 32px; flex: none; }
87
+
88
+ .status-icon {
89
+ width: 48px;
90
+ height: 48px;
91
+ display: grid;
92
+ place-items: center;
93
+ margin-bottom: 20px;
94
+ border: 1px solid var(--color-border);
95
+ border-color: color-mix(in srgb, var(--status-color) 55%, var(--color-border));
96
+ border-radius: 999px;
97
+ color: var(--status-color);
98
+ background: var(--color-panel);
99
+ background: color-mix(in srgb, var(--status-color) 10%, transparent);
100
+ }
101
+
102
+ .status-icon svg { width: 22px; height: 22px; }
103
+ .success { --status-color: var(--color-success); }
104
+ .error { --status-color: var(--color-error); }
105
+
106
+ .eyebrow {
107
+ margin: 0 0 4px;
108
+ color: var(--color-accent);
109
+ font-size: 12px;
110
+ font-weight: 600;
111
+ letter-spacing: 0.08em;
112
+ text-transform: uppercase;
113
+ }
114
+
115
+ h1 {
116
+ margin: 0;
117
+ color: var(--color-text-bright);
118
+ font-size: clamp(24px, 7vw, 30px);
119
+ font-weight: 600;
120
+ line-height: 1.2;
121
+ letter-spacing: -0.02em;
122
+ }
123
+
124
+ .description {
125
+ margin: 12px 0 24px;
126
+ color: var(--color-text-muted);
127
+ font-size: 15px;
128
+ line-height: 1.65;
129
+ }
130
+
131
+ .cli-status {
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 10px;
135
+ min-height: 44px;
136
+ padding: 10px 12px;
137
+ border: 1px solid var(--color-border);
138
+ border-radius: 4px;
139
+ color: var(--color-text);
140
+ background: var(--color-input);
141
+ font-family: var(--font-mono);
142
+ font-size: 13px;
143
+ }
144
+
145
+ .status-dot {
146
+ width: 8px;
147
+ height: 8px;
148
+ flex: none;
149
+ border-radius: 999px;
150
+ background: var(--status-color);
151
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--status-color) 14%, transparent);
152
+ }
153
+
154
+ .hint {
155
+ margin: 16px 0 0;
156
+ color: var(--color-text-muted);
157
+ font-size: 12px;
158
+ }
159
+
160
+ @media (prefers-color-scheme: light) {
161
+ :root {
162
+ color-scheme: light;
163
+ --color-bg: #f4f9fb;
164
+ --color-panel: #ffffff;
165
+ --color-border: #d8e5ea;
166
+ --color-text: #294653;
167
+ --color-text-muted: #5e7580;
168
+ --color-text-bright: #102a38;
169
+ --color-accent: #0f766e;
170
+ --color-success: #15803d;
171
+ --color-error: #be123c;
172
+ --color-input: #eaf3f6;
173
+ --shadow-lg: 0 8px 24px rgba(16, 42, 56, 0.12);
174
+ }
175
+ }
176
+
177
+ @media (max-width: 480px) {
178
+ .shell { padding: 0; place-items: stretch; }
179
+ .card {
180
+ min-height: 100vh;
181
+ padding: 28px 24px;
182
+ border: 0;
183
+ border-radius: 0;
184
+ display: flex;
185
+ flex-direction: column;
186
+ justify-content: center;
187
+ }
188
+ }
189
+
190
+ @media (prefers-reduced-motion: reduce) {
191
+ *, *::before, *::after { scroll-behavior: auto !important; }
192
+ }`;
193
+ const callbackPageStyleHash = createHash("sha256")
194
+ .update(callbackPageStyles, "utf8")
195
+ .digest("base64");
196
+ export const oauthCallbackResponseHeaders = Object.freeze({
197
+ "content-type": "text/html; charset=utf-8",
198
+ "cache-control": "no-store",
199
+ "referrer-policy": "no-referrer",
200
+ "x-content-type-options": "nosniff",
201
+ "content-security-policy": `default-src 'none'; style-src 'sha256-${callbackPageStyleHash}'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'`,
202
+ });
203
+ export function renderOAuthCallbackPage(kind) {
204
+ const success = kind === "success";
205
+ const content = success
206
+ ? {
207
+ title: "Authorization complete",
208
+ description: "Borealis CLI is connected. You can close this window and return to your terminal.",
209
+ status: "CLI session authorized",
210
+ hint: "This page does not need to remain open.",
211
+ }
212
+ : kind === "invalid"
213
+ ? {
214
+ title: "Invalid authorization response",
215
+ description: "Borealis could not verify this callback. Return to your terminal and start the sign-in flow again.",
216
+ status: "CLI session not authorized",
217
+ hint: "Run borealis auth login to retry.",
218
+ }
219
+ : {
220
+ title: "Authorization incomplete",
221
+ description: "Borealis did not receive an authorization code. Return to your terminal and start the sign-in flow again.",
222
+ status: "CLI session not authorized",
223
+ hint: "Run borealis auth login to retry.",
224
+ };
225
+ const icon = success
226
+ ? '<path d="m5 12 4 4L19 6" />'
227
+ : '<path d="M6 6l12 12M18 6 6 18" />';
228
+ const statusClass = success ? "success" : "error";
229
+ const liveRole = success ? "status" : "alert";
230
+ return `<!doctype html>
231
+ <html lang="en">
232
+ <head>
233
+ <meta charset="utf-8">
234
+ <meta name="viewport" content="width=device-width, initial-scale=1">
235
+ <meta name="color-scheme" content="dark light">
236
+ <title>${content.title} · Borealis CLI</title>
237
+ <style>${callbackPageStyles}</style>
238
+ </head>
239
+ <body>
240
+ <main class="shell">
241
+ <section class="card ${statusClass}" aria-labelledby="callback-title" role="${liveRole}">
242
+ <div class="brand">
243
+ <svg class="brand-mark" viewBox="0 0 49 48" fill="none" aria-hidden="true">
244
+ <path d="M1.984 29.29a17.21 17.21 0 0 1 17.21-17.21v17.21H1.984Z" fill="#0b1b3d" />
245
+ <path d="M1.984 29.29A17.21 17.21 0 0 0 19.194 46.5V29.29H1.984Z" fill="#38f5c8" />
246
+ <path d="M36.404 29.29A17.21 17.21 0 0 1 19.194 46.5V29.29h17.21Z" fill="#4edff5" />
247
+ <path d="M47.016 14.422a12.922 12.922 0 0 1-12.922 12.922H21.172V14.422a12.922 12.922 0 1 1 25.844 0Z" fill="#6a5cff" />
248
+ </svg>
249
+ <span>Borealis</span>
250
+ </div>
251
+ <div class="status-icon" aria-hidden="true">
252
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${icon}</svg>
253
+ </div>
254
+ <p class="eyebrow">CLI authorization</p>
255
+ <h1 id="callback-title">${content.title}</h1>
256
+ <p class="description">${content.description}</p>
257
+ <div class="cli-status">
258
+ <span class="status-dot" aria-hidden="true"></span>
259
+ <span>${content.status}</span>
260
+ </div>
261
+ <p class="hint">${content.hint}</p>
262
+ </section>
263
+ </main>
264
+ </body>
265
+ </html>`;
266
+ }
267
+ async function openBrowser(url) {
268
+ const [executable, args] = process.platform === "darwin"
269
+ ? ["open", [url]]
270
+ : process.platform === "win32"
271
+ ? ["rundll32.exe", ["url.dll,FileProtocolHandler", url]]
272
+ : ["xdg-open", [url]];
273
+ await execFileAsync(executable, args, { windowsHide: true });
274
+ }
275
+ async function requestToken(identity, body, signal) {
276
+ const deadline = createRequestDeadline(signal, 30_000);
277
+ try {
278
+ const response = await fetch(`${identity}/connect/token`, {
279
+ method: "POST",
280
+ headers: { "content-type": "application/x-www-form-urlencoded" },
281
+ body,
282
+ redirect: "error",
283
+ signal: deadline.signal,
284
+ });
285
+ const text = await readBoundedResponse(response, 65_536, deadline.signal);
286
+ if (!response.ok)
287
+ throw new Error(`Token endpoint failed (${response.status}).`);
288
+ const mediaType = response.headers.get("content-type")?.split(";", 1)[0];
289
+ if (!mediaType ||
290
+ (mediaType !== "application/json" && !mediaType.endsWith("+json")))
291
+ throw new Error(`Token endpoint returned an unexpected media type '${mediaType ?? "(missing)"}'.`);
292
+ return tokenSchema.parse(JSON.parse(text));
293
+ }
294
+ finally {
295
+ deadline.dispose();
296
+ }
297
+ }
298
+ export async function login(options, loginHint, scope = defaults.scope, signal) {
299
+ signal?.throwIfAborted();
300
+ const identity = validateOrigin(options.identity, "Identity URL");
301
+ const app = validateOrigin(options.app, "Application URL");
302
+ const api = validateOrigin(options.api, "API URL");
303
+ scope = validateLoginScope(scope);
304
+ const verifier = base64Url(randomBytes(32));
305
+ const challenge = base64Url(createHash("sha256").update(verifier, "ascii").digest());
306
+ const state = base64Url(randomBytes(24));
307
+ const port = 17_890;
308
+ const redirectUri = defaults.redirectUri;
309
+ const server = createServer();
310
+ const callback = new Promise((resolve, reject) => {
311
+ server.on("request", (request, response) => {
312
+ const url = new URL(request.url ?? "/", redirectUri);
313
+ if (url.pathname !== "/callback/" ||
314
+ url.searchParams.get("state") !== state) {
315
+ response
316
+ .writeHead(400, oauthCallbackResponseHeaders)
317
+ .end(renderOAuthCallbackPage("invalid"));
318
+ return;
319
+ }
320
+ const code = url.searchParams.get("code");
321
+ if (!code) {
322
+ response
323
+ .writeHead(400, oauthCallbackResponseHeaders)
324
+ .end(renderOAuthCallbackPage("failed"));
325
+ reject(new Error("Authorization callback did not contain a code."));
326
+ }
327
+ else {
328
+ response
329
+ .writeHead(200, oauthCallbackResponseHeaders)
330
+ .end(renderOAuthCallbackPage("success"));
331
+ resolve(code);
332
+ }
333
+ });
334
+ server.on("error", reject);
335
+ server.listen(port, "127.0.0.1");
336
+ });
337
+ const authorize = new URL("/auth/client/start", app);
338
+ for (const [key, value] of Object.entries({
339
+ client_type: "cli",
340
+ client_id: defaults.clientId,
341
+ redirect_uri: redirectUri,
342
+ scope,
343
+ state,
344
+ code_challenge: challenge,
345
+ code_challenge_method: "S256",
346
+ }))
347
+ authorize.searchParams.set(key, value);
348
+ if (loginHint)
349
+ authorize.searchParams.set("login_hint", loginHint);
350
+ process.stderr.write(`Opening ${authorize.origin} for authentication…\n`);
351
+ let code;
352
+ let callbackTimeout;
353
+ let rejectForAbort;
354
+ try {
355
+ if (!server.listening) {
356
+ await new Promise((resolve, reject) => {
357
+ server.once("listening", resolve);
358
+ server.once("error", reject);
359
+ });
360
+ }
361
+ await openBrowser(authorize.toString());
362
+ code = await Promise.race([
363
+ callback,
364
+ new Promise((_, reject) => {
365
+ rejectForAbort = () => reject(signal?.reason ?? new DOMException("Aborted", "AbortError"));
366
+ signal?.addEventListener("abort", rejectForAbort, { once: true });
367
+ }),
368
+ new Promise((_, reject) => {
369
+ callbackTimeout = setTimeout(() => reject(new Error("OAuth callback timed out after five minutes.")), 5 * 60 * 1000);
370
+ callbackTimeout.unref();
371
+ }),
372
+ ]);
373
+ }
374
+ finally {
375
+ if (callbackTimeout)
376
+ clearTimeout(callbackTimeout);
377
+ if (rejectForAbort)
378
+ signal?.removeEventListener("abort", rejectForAbort);
379
+ server.close();
380
+ }
381
+ const token = await requestToken(identity, new URLSearchParams({
382
+ grant_type: "authorization_code",
383
+ code,
384
+ client_id: defaults.clientId,
385
+ redirect_uri: redirectUri,
386
+ code_verifier: verifier,
387
+ }), signal);
388
+ if (!token.refresh_token)
389
+ throw new Error("The authorization server did not return a refresh token.");
390
+ const contextDeadline = createRequestDeadline(signal, 30_000);
391
+ let contextResponse;
392
+ let contextText;
393
+ try {
394
+ contextResponse = await fetch(`${api}/api/v1/context`, {
395
+ headers: {
396
+ authorization: `Bearer ${token.access_token}`,
397
+ accept: "application/json",
398
+ ...(options.organization
399
+ ? { "x-organization-id": options.organization }
400
+ : {}),
401
+ },
402
+ redirect: "error",
403
+ signal: contextDeadline.signal,
404
+ });
405
+ contextText = await readBoundedResponse(contextResponse, 1024 * 1024, contextDeadline.signal);
406
+ }
407
+ finally {
408
+ contextDeadline.dispose();
409
+ }
410
+ if (!contextResponse.ok)
411
+ throw new Error(`Borealis context validation failed (${contextResponse.status}).`);
412
+ const context = z
413
+ .object({
414
+ selectedOrganizationId: z.string().min(1).nullable().optional(),
415
+ organizations: z.array(z.object({ organizationId: z.string().min(1) })),
416
+ })
417
+ .parse(JSON.parse(contextText));
418
+ if (options.organization &&
419
+ !context.organizations.some((membership) => membership.organizationId === options.organization))
420
+ throw new Error(`The authenticated user is not a member of organization '${options.organization}'.`);
421
+ const organization = options.organization ?? context.selectedOrganizationId ?? undefined;
422
+ const session = {
423
+ accessToken: token.access_token,
424
+ refreshToken: token.refresh_token,
425
+ expiresAt: new Date(Date.now() + token.expires_in * 1000).toISOString(),
426
+ scope: token.scope,
427
+ clientId: defaults.clientId,
428
+ api,
429
+ identity,
430
+ app,
431
+ ...(organization ? { organization } : {}),
432
+ };
433
+ await saveSession(options.profile, session, signal);
434
+ return session;
435
+ }
436
+ async function readBoundedResponse(response, limit, signal) {
437
+ const reader = response.body?.getReader();
438
+ if (!reader)
439
+ throw new Error("HTTP response did not contain a body.");
440
+ const chunks = [];
441
+ let total = 0;
442
+ while (true) {
443
+ const { value, done } = signal
444
+ ? await readWithSignal(reader, signal)
445
+ : await reader.read();
446
+ if (done)
447
+ break;
448
+ total += value.byteLength;
449
+ if (total > limit) {
450
+ await reader.cancel();
451
+ throw new Error(`HTTP response exceeded ${limit} bytes.`);
452
+ }
453
+ chunks.push(value);
454
+ }
455
+ return Buffer.concat(chunks).toString("utf8");
456
+ }
457
+ async function readWithSignal(reader, signal) {
458
+ signal.throwIfAborted();
459
+ return await new Promise((resolve, reject) => {
460
+ const rejectForAbort = () => reject(signal.reason);
461
+ signal.addEventListener("abort", rejectForAbort, { once: true });
462
+ reader.read().then((result) => {
463
+ signal.removeEventListener("abort", rejectForAbort);
464
+ resolve(result);
465
+ }, (error) => {
466
+ signal.removeEventListener("abort", rejectForAbort);
467
+ reject(error);
468
+ });
469
+ });
470
+ }
471
+ export async function resolveAccessToken(options, signal) {
472
+ signal?.throwIfAborted();
473
+ const environment = process.env.BOREALIS_ACCESS_TOKEN;
474
+ const supplied = [environment, options.token, options.tokenFile].filter(Boolean);
475
+ if (supplied.length > 1)
476
+ throw new Error("Specify only one of BOREALIS_ACCESS_TOKEN, --token, or --token-file.");
477
+ if (options.token)
478
+ process.stderr.write("Warning: --token may expose credentials in shell history and process listings; prefer BOREALIS_ACCESS_TOKEN or --token-file.\n");
479
+ if (options.tokenFile) {
480
+ return { token: await readOwnerOnlySecretFile(options.tokenFile) };
481
+ }
482
+ if (environment || options.token)
483
+ return { token: (environment ?? options.token) };
484
+ const session = await loadSession(options.profile, signal);
485
+ if (!session)
486
+ throw new Error(`No authentication found for profile '${options.profile}'. Run 'borealis auth login'.`);
487
+ if (Date.parse(session.expiresAt) > Date.now() + 60_000)
488
+ return { token: session.accessToken, session };
489
+ if (!session.refreshToken)
490
+ throw new Error("The saved session expired and has no refresh token.");
491
+ const refreshed = await requestToken(session.identity, new URLSearchParams({
492
+ grant_type: "refresh_token",
493
+ refresh_token: session.refreshToken,
494
+ client_id: session.clientId,
495
+ }), signal);
496
+ const updated = {
497
+ ...session,
498
+ accessToken: refreshed.access_token,
499
+ refreshToken: refreshed.refresh_token ?? session.refreshToken,
500
+ expiresAt: new Date(Date.now() + refreshed.expires_in * 1000).toISOString(),
501
+ scope: refreshed.scope,
502
+ };
503
+ await saveSession(options.profile, updated, signal);
504
+ return { token: updated.accessToken, session: updated };
505
+ }
506
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type Operation } from "./types.js";
2
+ export declare const operations: readonly Operation[];
3
+ export declare function resolveOperation(args: readonly string[]): {
4
+ operation: Operation;
5
+ rest: string[];
6
+ } | undefined;
@@ -0,0 +1,15 @@
1
+ import operationData from "./operations.json" with { type: "json" };
2
+ import { operationSchema } from "./types.js";
3
+ export const operations = Object.freeze(operationData.map((operation) => operationSchema.parse(operation)));
4
+ export function resolveOperation(args) {
5
+ return operations
6
+ .map((operation) => ({ operation, tokens: operation.command.split(" ") }))
7
+ .filter(({ tokens }) => tokens.every((token, index) => args[index]?.toLowerCase() === token))
8
+ .sort((left, right) => right.tokens.length - left.tokens.length)
9
+ .map(({ operation, tokens }) => ({
10
+ operation,
11
+ rest: args.slice(tokens.length),
12
+ }))
13
+ .at(0);
14
+ }
15
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,mBAAmB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACpE,OAAO,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAE7D,MAAM,CAAC,MAAM,UAAU,GAAyB,MAAM,CAAC,MAAM,CAC3D,aAAa,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CACnE,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAC9B,IAAuB;IAEvB,OAAO,UAAU;SACd,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACzE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CACrB,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,KAAK,KAAK,CAAC,CACrE;SACA,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;SAC/D,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,SAAS;QACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;KAChC,CAAC,CAAC;SACF,EAAE,CAAC,CAAC,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function createCommandGrammar(): Command;
3
+ export declare function validateCommandGrammar(argv: readonly string[]): void;