@brass-build/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 (70) hide show
  1. package/AGENTS.md +170 -0
  2. package/CHANGELOG.md +12 -0
  3. package/LICENSE +21 -0
  4. package/README.md +172 -0
  5. package/dist/api.d.ts +73 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +97 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/args.d.ts +10 -0
  10. package/dist/args.d.ts.map +1 -0
  11. package/dist/args.js +94 -0
  12. package/dist/args.js.map +1 -0
  13. package/dist/auth.d.ts +5 -0
  14. package/dist/auth.d.ts.map +1 -0
  15. package/dist/auth.js +12 -0
  16. package/dist/auth.js.map +1 -0
  17. package/dist/bin/brass.d.ts +3 -0
  18. package/dist/bin/brass.d.ts.map +1 -0
  19. package/dist/bin/brass.js +11 -0
  20. package/dist/bin/brass.js.map +1 -0
  21. package/dist/cli.d.ts +4 -0
  22. package/dist/cli.d.ts.map +1 -0
  23. package/dist/cli.js +364 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/commands.d.ts +94 -0
  26. package/dist/commands.d.ts.map +1 -0
  27. package/dist/commands.js +559 -0
  28. package/dist/commands.js.map +1 -0
  29. package/dist/config.d.ts +40 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +76 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/log.d.ts +9 -0
  34. package/dist/log.d.ts.map +1 -0
  35. package/dist/log.js +32 -0
  36. package/dist/log.js.map +1 -0
  37. package/dist/login.d.ts +21 -0
  38. package/dist/login.d.ts.map +1 -0
  39. package/dist/login.js +158 -0
  40. package/dist/login.js.map +1 -0
  41. package/dist/project.d.ts +32 -0
  42. package/dist/project.d.ts.map +1 -0
  43. package/dist/project.js +129 -0
  44. package/dist/project.js.map +1 -0
  45. package/dist/session.d.ts +47 -0
  46. package/dist/session.d.ts.map +1 -0
  47. package/dist/session.js +224 -0
  48. package/dist/session.js.map +1 -0
  49. package/dist/store.d.ts +17 -0
  50. package/dist/store.d.ts.map +1 -0
  51. package/dist/store.js +90 -0
  52. package/dist/store.js.map +1 -0
  53. package/dist/version.d.ts +3 -0
  54. package/dist/version.d.ts.map +1 -0
  55. package/dist/version.js +8 -0
  56. package/dist/version.js.map +1 -0
  57. package/package.json +42 -0
  58. package/src/api.ts +195 -0
  59. package/src/args.ts +107 -0
  60. package/src/auth.ts +16 -0
  61. package/src/bin/brass.ts +11 -0
  62. package/src/cli.ts +422 -0
  63. package/src/commands.ts +864 -0
  64. package/src/config.ts +132 -0
  65. package/src/log.ts +41 -0
  66. package/src/login.ts +211 -0
  67. package/src/project.ts +176 -0
  68. package/src/session.ts +319 -0
  69. package/src/store.ts +123 -0
  70. package/src/version.ts +8 -0
@@ -0,0 +1,559 @@
1
+ // The command implementations, each taking an already-authenticated
2
+ // `BrassApi` plus its inputs and returning a structured result (or throwing
3
+ // `BrassApiError` / `Error`). The bin layer wires real IO; tests drive these
4
+ // directly against a mocked client, including the full publish sequence.
5
+ import { BrassApi, BrassApiError, putPresigned, } from './api.js';
6
+ import { mergeSchemaIntoManifest, readManifest, writeManifest, writeProjectAppId, writeTextFile, collectZipEntries, contentHash, zipEntries, isDirectory, } from './project.js';
7
+ import { basename } from 'node:path';
8
+ const DEFAULT_POLL_ATTEMPTS = 60;
9
+ const DEFAULT_POLL_INTERVAL_MS = 2000;
10
+ const realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
11
+ export async function publish(ctx, opts) {
12
+ if (!(await isDirectory(opts.dir))) {
13
+ throw new Error(`Publish directory not found: ${opts.dir}`);
14
+ }
15
+ const resolved = await resolveOrCreateApp(ctx, opts);
16
+ const appId = resolved.appId;
17
+ if (opts.visibility !== undefined) {
18
+ await ensureVisibility(ctx, appId, opts.visibility, resolved.detail?.visibility);
19
+ }
20
+ const hosting = await ensureHosting(ctx, appId, opts.slug);
21
+ if (opts.requireAccess !== undefined) {
22
+ await ensureGate(ctx, appId, opts.requireAccess, hosting);
23
+ }
24
+ const entries = await collectZipEntries(opts.dir);
25
+ if (Object.keys(entries).length === 0) {
26
+ throw new Error(`No files found to publish under ${opts.dir}`);
27
+ }
28
+ const hash = contentHash(entries);
29
+ // Skip the upload + unpack-wait when the app already serves this exact
30
+ // bundle. The posture reconcile above still ran, so an unchanged re-publish
31
+ // converges visibility / gate / slug and returns the live URL for the price
32
+ // of a couple of reads instead of an upload and a poll loop.
33
+ const unchanged = await activeVersionMatches(ctx, appId, hash);
34
+ if (unchanged !== null) {
35
+ const status = await ctx.api.get(`/apps/${encodeURIComponent(appId)}/hosting`);
36
+ ctx.log.success(`Already up to date${status.url ? `: ${status.url}` : ''}`);
37
+ // Refreshed here too, so publishing twice says the same thing both times.
38
+ // A publisher acting on a warning re-runs publish to check, and a signal
39
+ // that appears only on the run that happened to upload reads as fixed.
40
+ const warnings = await refreshCapabilities(ctx, appId);
41
+ return { app_id: appId, version_id: unchanged.version_id, url: status.url, warnings };
42
+ }
43
+ ctx.log.info('Packaging the bundle...');
44
+ const bundle = zipEntries(entries);
45
+ ctx.log.info('Uploading...');
46
+ const upload = await ctx.api.post(`/apps/${encodeURIComponent(appId)}/hosting/upload-url`, { content_hash: hash });
47
+ await putPresigned(upload.upload_url, bundle, 'application/zip');
48
+ const completed = await ctx.api.post(`/apps/${encodeURIComponent(appId)}/hosting/versions/${encodeURIComponent(upload.version_id)}/complete`, {});
49
+ const version = await waitForVersion(ctx, appId, completed, opts);
50
+ // Only an explicit `ready` is success. `waitForVersion` returns solely on a
51
+ // terminal status (or throws on timeout), so a `!== 'ready'` here is `failed`
52
+ // (or a future terminal-failure status): treat it as a failed deploy rather
53
+ // than falling through to a success the CLI would report with exit 0.
54
+ if (version.status !== 'ready') {
55
+ throw new Error(`Deploy failed: ${version.failure_reason ?? 'unknown reason'}`);
56
+ }
57
+ // Best-effort: the platform crawls the served manifest after a deploy on
58
+ // its own, but an explicit refresh surfaces capability warnings (e.g. a
59
+ // schema missing `family`) right here instead of silently later.
60
+ const warnings = await refreshCapabilities(ctx, appId);
61
+ const status = await ctx.api.get(`/apps/${encodeURIComponent(appId)}/hosting`);
62
+ if (status.url)
63
+ ctx.log.success(`Deployed: ${status.url}`);
64
+ return { app_id: appId, version_id: version.version_id, url: status.url, warnings };
65
+ }
66
+ async function resolveOrCreateApp(ctx, opts) {
67
+ if (opts.appId !== undefined)
68
+ return { appId: opts.appId };
69
+ const manifest = await readManifest(opts.manifestPath);
70
+ const name = opts.name ?? manifest?.name;
71
+ if (name === undefined || name.trim() === '') {
72
+ throw new Error('No app to publish to. Pass --name to create one, or --app / BRASS_APP_ID / a .brass/project.json for an existing app.');
73
+ }
74
+ // A `client_token` makes create idempotent, so a repeated create-from-
75
+ // scratch (ephemeral CI has no persisted project.json) resolves the same
76
+ // app rather than minting a duplicate.
77
+ const clientToken = opts.clientToken ?? manifest?.client_token;
78
+ const organizationId = await resolveCreateOrganizationId(ctx, opts.organizationId);
79
+ const body = {
80
+ name: name.trim(),
81
+ };
82
+ if (organizationId !== undefined)
83
+ body.organization_id = organizationId;
84
+ if (typeof clientToken === 'string' && clientToken.trim() !== '') {
85
+ body.client_token = clientToken.trim();
86
+ }
87
+ const app = await ctx.api.post('/apps', body);
88
+ await writeProjectAppId(ctx.cwd, ctx.profile, app.app_id);
89
+ // With a key the call resolves-or-creates, so avoid asserting it was new.
90
+ ctx.log.info(`${body.client_token !== undefined ? 'Using' : 'Created'} app ${app.app_id} (saved to .brass/project.json)`);
91
+ return { appId: app.app_id, detail: app };
92
+ }
93
+ // Set the app's visibility when `--visibility` asks for one it does not
94
+ // already hold. `current` is the value from the create/resolve response when
95
+ // known; otherwise the app is read to avoid a redundant write (and the audit
96
+ // event a no-op change would emit) on every re-publish.
97
+ async function ensureVisibility(ctx, appId, want, current) {
98
+ let have = current;
99
+ if (have === undefined) {
100
+ const detail = await ctx.api.get(`/apps/${encodeURIComponent(appId)}`);
101
+ have = detail.visibility;
102
+ }
103
+ if (have === want)
104
+ return;
105
+ await ctx.api.patch(`/apps/${encodeURIComponent(appId)}`, { visibility: want });
106
+ ctx.log.info(`Set visibility to ${want}.`);
107
+ }
108
+ // Converge the hosted load gate to `want` (`true` = gated to the audience,
109
+ // `false` = world-loadable). Always PATCH, even when the DDB flag already
110
+ // reads `want`: the PATCH is what reaches the server-side reconcile that
111
+ // repairs a wedged edge marker (a prior toggle whose flag write landed but
112
+ // whose marker write lost every ETag race leaves the flag reading correct
113
+ // while the marker disagrees). Skipping the PATCH on a matching flag would
114
+ // leave such a gate wedged forever, since every later publish would skip it
115
+ // too. `status` is the state `ensureHosting` just observed, used only to word
116
+ // the log line. (`require_access` absent === off.)
117
+ async function ensureGate(ctx, appId, want, status) {
118
+ const changed = (status.require_access === true) !== want;
119
+ await ctx.api.patch(`/apps/${encodeURIComponent(appId)}/hosting`, {
120
+ require_access: want,
121
+ });
122
+ if (changed) {
123
+ ctx.log.info(want ? 'Enabled the load gate.' : 'Disabled the load gate (bundle is world-loadable).');
124
+ }
125
+ else {
126
+ ctx.log.info(want ? 'Load gate is on.' : 'Load gate is off (bundle is world-loadable).');
127
+ }
128
+ }
129
+ async function ensureHosting(ctx, appId, slug) {
130
+ const status = await ctx.api.get(`/apps/${encodeURIComponent(appId)}/hosting`);
131
+ if (status.enabled)
132
+ return status;
133
+ const body = {};
134
+ if (slug !== undefined)
135
+ body.slug = slug;
136
+ const enabled = await ctx.api.post(`/apps/${encodeURIComponent(appId)}/hosting`, body);
137
+ if (enabled.slug)
138
+ ctx.log.info(`Enabled hosting at ${enabled.slug}`);
139
+ return enabled;
140
+ }
141
+ // The currently-served version when it is `ready` and already carries
142
+ // `hash`, else null. A null (no active version, a non-ready active version, or
143
+ // a hash mismatch) means `publish` must upload. A first deploy has no active
144
+ // version, so it always uploads; a version predating content hashing has no
145
+ // recorded hash and so never matches, forcing one re-upload that self-heals.
146
+ async function activeVersionMatches(ctx, appId, hash) {
147
+ const { versions } = await ctx.api.get(`/apps/${encodeURIComponent(appId)}/hosting/versions`);
148
+ const active = versions.find((v) => v.active);
149
+ if (active && active.status === 'ready' && active.content_hash === hash)
150
+ return active;
151
+ return null;
152
+ }
153
+ // Poll until the version reaches a KNOWN terminal state (`ready` / `failed`),
154
+ // then return it; time out otherwise. Deliberately loops while the status is
155
+ // anything other than a known terminal — `pending` OR any status this pinned
156
+ // CLI does not recognize — rather than returning on `!== 'pending'`. That way
157
+ // a future server status (a finer-grained non-terminal like `unpacking`, or a
158
+ // new terminal-failure like `rejected`) is not mistaken for "done": an
159
+ // unrecognized non-terminal keeps polling, and an unrecognized terminal
160
+ // failure ends as a timeout (a non-zero exit) instead of a false success.
161
+ function isTerminalVersionStatus(status) {
162
+ return status === 'ready' || status === 'failed';
163
+ }
164
+ async function waitForVersion(ctx, appId, completed, opts) {
165
+ if (isTerminalVersionStatus(completed.status))
166
+ return completed;
167
+ const attempts = opts.pollAttempts ?? DEFAULT_POLL_ATTEMPTS;
168
+ const intervalMs = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
169
+ const sleep = opts.sleep ?? realSleep;
170
+ for (let i = 0; i < attempts; i++) {
171
+ await sleep(intervalMs);
172
+ const { versions } = await ctx.api.get(`/apps/${encodeURIComponent(appId)}/hosting/versions`);
173
+ const current = versions.find((v) => v.version_id === completed.version_id);
174
+ if (current && isTerminalVersionStatus(current.status))
175
+ return current;
176
+ }
177
+ throw new Error('Timed out waiting for the deploy to finish unpacking.');
178
+ }
179
+ async function refreshCapabilities(ctx, appId) {
180
+ try {
181
+ const refreshed = await ctx.api.post(`/apps/${encodeURIComponent(appId)}/capabilities/refresh`, {});
182
+ const warnings = refreshed.warnings ?? [];
183
+ for (const warning of warnings)
184
+ ctx.log.warn(warning);
185
+ return warnings;
186
+ }
187
+ catch (err) {
188
+ // A capability refresh is a convenience read on top of the deploy; the
189
+ // platform re-crawls the manifest regardless, so a transient failure
190
+ // here must not fail an otherwise-successful publish.
191
+ const detail = err instanceof BrassApiError ? err.message : String(err);
192
+ const warning = `Could not read capabilities yet: ${detail}`;
193
+ ctx.log.warn(warning);
194
+ return [warning];
195
+ }
196
+ }
197
+ export async function schemaPull(ctx, opts) {
198
+ const docPath = `/documents/${encodeURIComponent(opts.docId)}`;
199
+ const [held, summary] = await Promise.all([
200
+ ctx.api.get(`${docPath}/schema`),
201
+ ctx.api.get(docPath),
202
+ ]);
203
+ // An app manifest is a CLAIM the developer is about to author: a family
204
+ // plus a body per stream. The document holds no such thing, only streams,
205
+ // so the manifest is ASSEMBLED here rather than read off the document.
206
+ // Each published body goes in verbatim; the family is the document's own
207
+ // type, the same token open-routing matches on. A stream the document
208
+ // holds with no published contract is left out: a manifest entry is a
209
+ // shape the app declares it works with, and there is no shape to declare.
210
+ const family = summary.schema_type ?? '';
211
+ if (family === '') {
212
+ throw new Error(`Document ${opts.docId} carries no type, so there is no family to declare. Pull from a document an importer or app produced.`);
213
+ }
214
+ const streams = {};
215
+ for (const entry of held.streams) {
216
+ if (entry.schema !== undefined)
217
+ streams[entry.name] = entry.schema;
218
+ }
219
+ const manifest = (await readManifest(opts.outPath)) ?? {};
220
+ await writeManifest(opts.outPath, mergeSchemaIntoManifest(manifest, { family, streams }));
221
+ ctx.log.success(`Wrote the "${family}" schema to ${opts.outPath}`);
222
+ return { family, out_path: opts.outPath };
223
+ }
224
+ // Pull an organization's agentic-coding instructions (its AGENTS.md /
225
+ // CLAUDE.md body). Needs a human sign-in (`brass login`): the instructions
226
+ // read is org-membership gated, which a service token does not carry.
227
+ // Resolves the org from the caller's single membership when `--org` is
228
+ // omitted. The body is emitted verbatim, so it round-trips byte-for-byte with
229
+ // what the dashboard stored, either to a file (default) or to stdout
230
+ // (`--stdout`, for an agent that reads it inline and caches nothing).
231
+ export async function agentsPull(ctx, opts) {
232
+ const organizationId = opts.organizationId ?? (await resolveSingleOrganization(ctx));
233
+ const instructions = await ctx.api.get(`/organizations/${encodeURIComponent(organizationId)}/agent-instructions`);
234
+ const bytes = Buffer.byteLength(instructions.content, 'utf8');
235
+ const empty = instructions.content === '';
236
+ if (opts.stdout) {
237
+ // Body straight to stdout (verbatim); an empty org prints nothing so a
238
+ // consumer reads an empty stream, with the reason on stderr.
239
+ if (empty)
240
+ ctx.log.warn(`No agent instructions set for ${organizationId}.`);
241
+ else
242
+ ctx.log.write(instructions.content);
243
+ return { organization_id: organizationId, out_path: null, bytes, empty };
244
+ }
245
+ if (empty) {
246
+ ctx.log.warn(`No agent instructions set for ${organizationId}. Nothing written.`);
247
+ return { organization_id: organizationId, out_path: opts.outPath, bytes, empty: true };
248
+ }
249
+ await writeTextFile(opts.outPath, instructions.content);
250
+ ctx.log.success(`Wrote agent instructions to ${opts.outPath} (${bytes} bytes)`);
251
+ // Claude Code reads CLAUDE.md, not AGENTS.md (the cross-agent default this
252
+ // writes). Point the user at the official one-line bridge so the pulled
253
+ // instructions are actually picked up there; skip it when they already
254
+ // pulled straight to a CLAUDE.md.
255
+ const outName = basename(opts.outPath);
256
+ if (outName.toLowerCase() !== 'claude.md') {
257
+ ctx.log.info(`Claude Code reads CLAUDE.md, not ${outName}. To use these there, add a CLAUDE.md containing "@${outName}".`);
258
+ }
259
+ return {
260
+ organization_id: organizationId,
261
+ out_path: opts.outPath,
262
+ bytes,
263
+ empty: false,
264
+ };
265
+ }
266
+ async function listCallerOrganizations(ctx) {
267
+ const { organizations } = await ctx.api.get('/organizations');
268
+ return organizations;
269
+ }
270
+ // Resolve the caller's single organization, or throw guidance to pass
271
+ // `--org`. A caller with zero orgs (or a service-token credential, which
272
+ // lists none) also gets a clear message rather than an opaque request error.
273
+ async function resolveSingleOrganization(ctx) {
274
+ const organizations = await listCallerOrganizations(ctx);
275
+ if (organizations.length === 1 && organizations[0] !== undefined) {
276
+ return organizations[0].organization_id;
277
+ }
278
+ if (organizations.length === 0) {
279
+ throw new Error('No organizations for this credential. Pass --org <organizationId>, and sign in with `brass login` (agent instructions need a member sign-in, not a service token).');
280
+ }
281
+ const names = organizations
282
+ .map((o) => `${o.organization_id} (${o.name})`)
283
+ .join(', ');
284
+ throw new Error(`Multiple organizations; pass --org <organizationId>. Available: ${names}`);
285
+ }
286
+ // The owning org for a first `publish` create. Every app is owned by an org.
287
+ // An explicit `--org` wins. A signed-in human resolves to their single
288
+ // membership (asked to choose when they belong to several, or to create/join
289
+ // one when they have none). A service token returns undefined: the API binds
290
+ // the app to the token's own org, and the token lists no memberships anyway.
291
+ async function resolveCreateOrganizationId(ctx, explicit) {
292
+ if (explicit !== undefined)
293
+ return explicit;
294
+ if (ctx.credentialKind !== 'session')
295
+ return undefined;
296
+ const organizations = await listCallerOrganizations(ctx);
297
+ if (organizations.length === 1 && organizations[0] !== undefined) {
298
+ const orgId = organizations[0].organization_id;
299
+ ctx.log.info(`Owning organization ${orgId} (your only one; pass --org to choose another).`);
300
+ return orgId;
301
+ }
302
+ if (organizations.length === 0) {
303
+ throw new Error('You do not belong to any organization, so there is nothing to own the app. Create or join one in the dashboard, then publish.');
304
+ }
305
+ const names = organizations
306
+ .map((o) => `${o.organization_id} (${o.name})`)
307
+ .join(', ');
308
+ throw new Error(`You belong to multiple organizations; pass --org <organizationId> to choose which one owns the app. Available: ${names}`);
309
+ }
310
+ // Confirm the resolved credential authenticates, over the `apps:write`-gated
311
+ // probe (`GET /health`) both credential kinds can reach: a service token is an
312
+ // org-scoped identity that enumerates no membership, so it has no org id to
313
+ // address an org-scoped read with. A 401 (rejected credential) or 403 (a token
314
+ // without the publish capability) surfaces as a thrown BrassApiError the CLI
315
+ // turns into a non-zero exit.
316
+ export async function whoami(ctx) {
317
+ await ctx.api.get('/health');
318
+ ctx.log.success('Authenticated. This credential can publish.');
319
+ return { authenticated: true };
320
+ }
321
+ // Report the publish readiness of the current directory + credential and,
322
+ // crucially, the one command to run next. `whoami` answers "does my token
323
+ // work"; `status` answers "what do I do now", so an agent follows its output
324
+ // instead of re-deriving the publish flow from prose under friction. It never
325
+ // throws on a missing or rejected credential: those are first-class states it
326
+ // reports and turns into a next step, not errors.
327
+ export async function status(inp) {
328
+ const publishCmd = `brass publish ./${inp.publishDir}`;
329
+ const kind = inp.credential === null ? 'none' : inp.credential.kind;
330
+ // No credential yet. Only the human can approve, but starting the sign-in,
331
+ // relaying the code, and polling it through are the caller's steps, so the
332
+ // next line names the command to run rather than an instruction to pass on.
333
+ if (inp.api === null || inp.credential === null) {
334
+ const pending = inp.pendingLogin;
335
+ return finish(inp, {
336
+ signed_in: false,
337
+ credential: 'none',
338
+ authenticated: null,
339
+ email: null,
340
+ hosting: null,
341
+ ready_to_publish: false,
342
+ next: pending !== null
343
+ ? `a sign-in for ${inp.profile} is waiting for approval: give the user ` +
344
+ `${pending.verificationUrl} and the code ${pending.userCode}, then run ` +
345
+ `'brass login --check --wait'. It polls until they approve and renews ` +
346
+ `the code if it lapses, so there is no need to start a second sign-in.`
347
+ : `no credential for ${inp.profile}. Run 'brass login --start' to begin a ` +
348
+ `sign-in, give the user the URL and short code it prints, then run ` +
349
+ `'brass login --check --wait' until it reports approved (or set ` +
350
+ `BRASS_SERVICE_TOKEN). The session feeds the build steps ` +
351
+ `('brass agents pull' for the organization's instructions, ` +
352
+ `'brass schema pull' for your example document's schema) as well as ` +
353
+ `the eventual '${publishCmd}'.`,
354
+ });
355
+ }
356
+ // Probe the credential against the live API (the same read a publish makes),
357
+ // so "signed in" means verified, not just "a token is present".
358
+ const probe = await probeAuth(inp.api);
359
+ if (probe.state === 'unreachable' || probe.state === 'fault') {
360
+ return finish(inp, {
361
+ signed_in: false,
362
+ credential: kind,
363
+ authenticated: null,
364
+ unverified_reason: probe.error,
365
+ email: null,
366
+ hosting: null,
367
+ ready_to_publish: false,
368
+ next: probe.state === 'unreachable'
369
+ ? `could not reach the Brass API (${probe.error}). Check connectivity, ` +
370
+ `then run 'brass status' again.`
371
+ : `the Brass API answered, but the credential could not be verified ` +
372
+ `(${probe.error}). The credential was not rejected and the API is ` +
373
+ `reachable, so run 'brass status' again.`,
374
+ });
375
+ }
376
+ if (probe.state === 'rejected') {
377
+ return finish(inp, {
378
+ signed_in: false,
379
+ credential: kind,
380
+ authenticated: false,
381
+ email: null,
382
+ hosting: null,
383
+ ready_to_publish: false,
384
+ next: kind === 'session'
385
+ ? `the stored sign-in was rejected. Run 'brass login --start' to begin a ` +
386
+ `new one, relay the printed URL + code, then 'brass login --check --wait'.`
387
+ : `the service token was rejected. Check BRASS_SERVICE_TOKEN or --token.`,
388
+ });
389
+ }
390
+ const email = kind === 'session' ? await probeEmail(inp.api) : null;
391
+ // Verified. What would `publish` target? A service token's create binds to
392
+ // the token's own org by default, so no `--org` is needed to stand one up.
393
+ if (inp.appId === null) {
394
+ const next = inp.manifestName !== null
395
+ ? `signed in. No app yet; run '${publishCmd}' to create ` +
396
+ `"${inp.manifestName}" and deploy it.`
397
+ : `signed in. No app yet; run '${publishCmd} --name "<app name>"' ` +
398
+ `to create and deploy one (or add a "name" to brass-app.json).`;
399
+ return finish(inp, {
400
+ signed_in: true,
401
+ credential: kind,
402
+ authenticated: true,
403
+ email,
404
+ hosting: null,
405
+ ready_to_publish: true,
406
+ next,
407
+ });
408
+ }
409
+ const hostingProbe = await probeHosting(inp.api, inp.appId);
410
+ if (hostingProbe.missing) {
411
+ return finish(inp, {
412
+ signed_in: true,
413
+ credential: kind,
414
+ authenticated: true,
415
+ email,
416
+ hosting: null,
417
+ ready_to_publish: false,
418
+ next: `signed in, but the saved app id ${inp.appId} is not one this credential ` +
419
+ `can publish to. Remove .brass/project.json (or pass --app), then run ` +
420
+ `'${publishCmd}' to create a fresh app.`,
421
+ });
422
+ }
423
+ const h = hostingProbe.hosting;
424
+ const hosting = h === null ? null : { enabled: h.enabled, deployed: h.deployed, url: h.url };
425
+ if (h !== null && h.deployed && h.url !== null) {
426
+ return finish(inp, {
427
+ signed_in: true,
428
+ credential: kind,
429
+ authenticated: true,
430
+ email,
431
+ hosting,
432
+ ready_to_publish: true,
433
+ next: `your app is live at ${h.url}. Open it and confirm sign-in works there.`,
434
+ });
435
+ }
436
+ return finish(inp, {
437
+ signed_in: true,
438
+ credential: kind,
439
+ authenticated: true,
440
+ email,
441
+ hosting,
442
+ ready_to_publish: true,
443
+ next: `signed in with app ${inp.appId} ready. Run '${publishCmd}' to deploy.`,
444
+ });
445
+ }
446
+ // Auth check shared by every credential kind: `GET /health` is the
447
+ // `apps:write`-gated probe a session and a service token can both reach with
448
+ // nothing but their own credential (see `whoami`).
449
+ //
450
+ // Classify by what the probe observed. A 401/403 is a rejected credential,
451
+ // from the API or from the session refresh that runs first. Only status 0
452
+ // means the request never completed, which is the one state that says
453
+ // anything about reachability. Every other status is a fault the server
454
+ // answered, so it is not a bad credential either. The distinction is
455
+ // load-bearing: labelling a status the server returned "unreachable" points
456
+ // the next step at connectivity, and a reader acting on that goes looking
457
+ // for blocked egress instead of signing in.
458
+ async function probeAuth(api) {
459
+ try {
460
+ await api.get('/health');
461
+ return { state: 'ok' };
462
+ }
463
+ catch (err) {
464
+ if (err instanceof BrassApiError) {
465
+ if (err.status === 401 || err.status === 403)
466
+ return { state: 'rejected' };
467
+ if (err.status === 0)
468
+ return { state: 'unreachable', error: err.message };
469
+ return { state: 'fault', error: err.message };
470
+ }
471
+ return { state: 'fault', error: err instanceof Error ? err.message : String(err) };
472
+ }
473
+ }
474
+ // The signed-in email for the friendly "signed in as ..." line, best-effort.
475
+ // `/users/me` carries an identity only for a session; a failure (a service
476
+ // token, or any error) just omits the email.
477
+ async function probeEmail(api) {
478
+ try {
479
+ const me = await api.get('/users/me');
480
+ return typeof me.email === 'string' && me.email.trim() !== '' ? me.email : null;
481
+ }
482
+ catch {
483
+ return null;
484
+ }
485
+ }
486
+ // Read an app's hosting so the next step is exact (deploy vs. open the live
487
+ // URL). A 404/403 means the saved app id is stale or not this credential's, a
488
+ // state worth surfacing; any other error is swallowed so it never blocks.
489
+ async function probeHosting(api, appId) {
490
+ try {
491
+ const hosting = await api.get(`/apps/${encodeURIComponent(appId)}/hosting`);
492
+ return { missing: false, hosting };
493
+ }
494
+ catch (err) {
495
+ if (err instanceof BrassApiError && (err.status === 404 || err.status === 403)) {
496
+ return { missing: true, hosting: null };
497
+ }
498
+ return { missing: false, hosting: null };
499
+ }
500
+ }
501
+ // Assemble the result, render the human checklist, and return the structured
502
+ // payload (also emitted verbatim under `--json`).
503
+ // Report an in-flight sign-in only while it is still approvable: a lapsed
504
+ // grant is not a state anyone acts on, and reporting one would send a caller
505
+ // to relay a code the approval page refuses.
506
+ function pendingLoginReport(inp) {
507
+ const pending = inp.pendingLogin;
508
+ if (pending === null)
509
+ return null;
510
+ const remaining = Math.round((pending.expiresAt - Date.now()) / 1000);
511
+ if (remaining <= 0)
512
+ return null;
513
+ return {
514
+ user_code: pending.userCode,
515
+ verification_url: pending.verificationUrl,
516
+ expires_in_seconds: remaining,
517
+ };
518
+ }
519
+ function finish(inp, rest) {
520
+ const result = {
521
+ profile: inp.profile,
522
+ app_id: inp.appId,
523
+ pending_login: pendingLoginReport(inp),
524
+ ...rest,
525
+ };
526
+ const cred = result.credential === 'none'
527
+ ? 'none'
528
+ : result.authenticated === false
529
+ ? `${credentialLabel(result.credential)} (rejected)`
530
+ : result.authenticated === null
531
+ ? `${credentialLabel(result.credential)} (unverified: ${result.unverified_reason ?? 'not probed'})`
532
+ : result.email !== null
533
+ ? `signed in as ${result.email}`
534
+ : `signed in (${credentialLabel(result.credential)})`;
535
+ inp.log.info(`Brass status (${result.profile})`);
536
+ inp.log.info(` credential: ${cred}`);
537
+ if (result.pending_login !== null) {
538
+ const p = result.pending_login;
539
+ inp.log.info(` sign-in: awaiting approval, code ${p.user_code} at ${p.verification_url} ` +
540
+ `(${Math.ceil(p.expires_in_seconds / 60)} min left)`);
541
+ }
542
+ inp.log.info(` app: ${result.app_id ?? 'none (a first publish creates one)'}`);
543
+ if (result.hosting !== null) {
544
+ const h = result.hosting;
545
+ const hostingLine = h.url
546
+ ? `${h.url}${h.deployed ? ' (deployed)' : ''}`
547
+ : h.enabled
548
+ ? 'enabled, not deployed'
549
+ : 'not enabled';
550
+ inp.log.info(` hosting: ${hostingLine}`);
551
+ }
552
+ inp.log.info('');
553
+ inp.log.success(`Next: ${result.next}`);
554
+ return result;
555
+ }
556
+ function credentialLabel(kind) {
557
+ return kind === 'service' ? 'service token' : kind === 'session' ? 'session' : 'none';
558
+ }
559
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,4EAA4E;AAC5E,6EAA6E;AAC7E,yEAAyE;AAEzE,OAAO,EACL,QAAQ,EACR,aAAa,EAYb,YAAY,GACb,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,WAAW,GAEZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AA8DrC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACjC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,SAAS,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAEvF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAmB,EAAE,IAAoB;IACrE,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC7B,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAElC,uEAAuE;IACvE,4EAA4E;IAC5E,4EAA4E;IAC5E,6DAA6D;IAC7D,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/D,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAgB,SAAS,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC9F,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,qBAAqB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5E,0EAA0E;QAC1E,yEAAyE;QACzE,uEAAuE;QACvE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;IACxF,CAAC;IAED,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAEnC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAC/B,SAAS,kBAAkB,CAAC,KAAK,CAAC,qBAAqB,EACvD,EAAE,YAAY,EAAE,IAAI,EAAE,CACvB,CAAC;IACF,MAAM,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAEjE,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAClC,SAAS,kBAAkB,CAAC,KAAK,CAAC,qBAAqB,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,EACvG,EAAE,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAClE,4EAA4E;IAC5E,8EAA8E;IAC9E,4EAA4E;IAC5E,sEAAsE;IACtE,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,CAAC,cAAc,IAAI,gBAAgB,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,yEAAyE;IACzE,wEAAwE;IACxE,iEAAiE;IACjE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAgB,SAAS,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC9F,IAAI,MAAM,CAAC,GAAG;QAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;AACtF,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,GAAmB,EACnB,IAAoB;IAEpB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,IAAI,CAAC;IACzC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,uHAAuH,CACxH,CAAC;IACJ,CAAC;IACD,uEAAuE;IACvE,yEAAyE;IACzE,uCAAuC;IACvC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,QAAQ,EAAE,YAAY,CAAC;IAC/D,MAAM,cAAc,GAAG,MAAM,2BAA2B,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IACnF,MAAM,IAAI,GAAsE;QAC9E,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;KAClB,CAAC;IACF,IAAI,cAAc,KAAK,SAAS;QAAE,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;IACxE,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjE,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAY,OAAO,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1D,0EAA0E;IAC1E,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,GAAG,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,MAAM,iCAAiC,CAC5G,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC5C,CAAC;AAED,wEAAwE;AACxE,6EAA6E;AAC7E,6EAA6E;AAC7E,wDAAwD;AACxD,KAAK,UAAU,gBAAgB,CAC7B,GAAmB,EACnB,KAAa,EACb,IAAmB,EACnB,OAAkC;IAElC,IAAI,IAAI,GAAG,OAAO,CAAC;IACnB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAY,SAAS,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClF,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;IAC3B,CAAC;IACD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAC1B,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,CAAY,SAAS,kBAAkB,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,2EAA2E;AAC3E,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,mDAAmD;AACnD,KAAK,UAAU,UAAU,CACvB,GAAmB,EACnB,KAAa,EACb,IAAa,EACb,MAAqB;IAErB,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;IAC1D,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,CAAgB,SAAS,kBAAkB,CAAC,KAAK,CAAC,UAAU,EAAE;QAC/E,cAAc,EAAE,IAAI;KACrB,CAAC,CAAC;IACH,IAAI,OAAO,EAAE,CAAC;QACZ,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,oDAAoD,CACvF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,GAAmB,EACnB,KAAa,EACb,IAAa;IAEb,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAgB,SAAS,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC9F,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAClC,MAAM,IAAI,GAAsB,EAAE,CAAC;IACnC,IAAI,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAChC,SAAS,kBAAkB,CAAC,KAAK,CAAC,UAAU,EAC5C,IAAI,CACL,CAAC;IACF,IAAI,OAAO,CAAC,IAAI;QAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,sEAAsE;AACtE,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,KAAK,UAAU,oBAAoB,CACjC,GAAmB,EACnB,KAAa,EACb,IAAY;IAEZ,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CACpC,SAAS,kBAAkB,CAAC,KAAK,CAAC,mBAAmB,CACtD,CAAC;IACF,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IACvF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,SAAS,uBAAuB,CAAC,MAA4B;IAC3D,OAAO,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,QAAQ,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,GAAmB,EACnB,KAAa,EACb,SAAyB,EACzB,IAAoB;IAEpB,IAAI,uBAAuB,CAAC,SAAS,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,IAAI,qBAAqB,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,IAAI,wBAAwB,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CACpC,SAAS,kBAAkB,CAAC,KAAK,CAAC,mBAAmB,CACtD,CAAC;QACF,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU,CAAC,CAAC;QAC5E,IAAI,OAAO,IAAI,uBAAuB,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,OAAO,CAAC;IACzE,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;AAC3E,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,GAAmB,EACnB,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAClC,SAAS,kBAAkB,CAAC,KAAK,CAAC,uBAAuB,EACzD,EAAE,CACH,CAAC;QACF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ;YAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,uEAAuE;QACvE,qEAAqE;QACrE,sDAAsD;QACtD,MAAM,MAAM,GAAG,GAAG,YAAY,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,oCAAoC,MAAM,EAAE,CAAC;QAC7D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AAaD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAmB,EACnB,IAAuB;IAEvB,MAAM,OAAO,GAAG,cAAc,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/D,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAkB,GAAG,OAAO,SAAS,CAAC;QACjD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAsB,OAAO,CAAC;KAC1C,CAAC,CAAC;IACH,wEAAwE;IACxE,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,sEAAsE;IACtE,sEAAsE;IACtE,0EAA0E;IAC1E,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IACzC,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,CAAC,KAAK,uGAAuG,CAC9H,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAA4C,EAAE,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IACrE,CAAC;IACD,MAAM,QAAQ,GAAgB,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACvE,MAAM,aAAa,CACjB,IAAI,CAAC,OAAO,EACZ,uBAAuB,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CACvD,CAAC;IACF,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,MAAM,eAAe,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;AAC5C,CAAC;AAwBD,sEAAsE;AACtE,2EAA2E;AAC3E,sEAAsE;AACtE,uEAAuE;AACvE,8EAA8E;AAC9E,qEAAqE;AACrE,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAmB,EACnB,IAAuB;IAEvB,MAAM,cAAc,GAClB,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,yBAAyB,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CACpC,kBAAkB,kBAAkB,CAAC,cAAc,CAAC,qBAAqB,CAC1E,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,KAAK,EAAE,CAAC;IAE1C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,uEAAuE;QACvE,6DAA6D;QAC7D,IAAI,KAAK;YAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,iCAAiC,cAAc,GAAG,CAAC,CAAC;;YACvE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC3E,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,iCAAiC,cAAc,oBAAoB,CACpE,CAAC;QACF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzF,CAAC;IACD,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IACxD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,+BAA+B,IAAI,CAAC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC;IAChF,2EAA2E;IAC3E,wEAAwE;IACxE,uEAAuE;IACvE,kCAAkC;IAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,WAAW,EAAE,CAAC;QAC1C,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,oCAAoC,OAAO,sDAAsD,OAAO,IAAI,CAC7G,CAAC;IACJ,CAAC;IACD,OAAO;QACL,eAAe,EAAE,cAAc;QAC/B,QAAQ,EAAE,IAAI,CAAC,OAAO;QACtB,KAAK;QACL,KAAK,EAAE,KAAK;KACb,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,GAAmB;IAEnB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAExC,gBAAgB,CAAC,CAAC;IACrB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,sEAAsE;AACtE,yEAAyE;AACzE,6EAA6E;AAC7E,KAAK,UAAU,yBAAyB,CAAC,GAAmB;IAC1D,MAAM,aAAa,GAAG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACzD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACjE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;IAC1C,CAAC;IACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,oKAAoK,CACrK,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,aAAa;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,eAAe,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;SAC9C,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,IAAI,KAAK,CACb,mEAAmE,KAAK,EAAE,CAC3E,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,uEAAuE;AACvE,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,KAAK,UAAU,2BAA2B,CACxC,GAAmB,EACnB,QAA4B;IAE5B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,IAAI,GAAG,CAAC,cAAc,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACvD,MAAM,aAAa,GAAG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACzD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACjE,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;QAC/C,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,uBAAuB,KAAK,iDAAiD,CAC9E,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,+HAA+H,CAChI,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,aAAa;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,eAAe,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;SAC9C,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,IAAI,KAAK,CACb,kHAAkH,KAAK,EAAE,CAC1H,CAAC;AACJ,CAAC;AAMD,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAC/E,6EAA6E;AAC7E,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAmB;IAC9C,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAe,SAAS,CAAC,CAAC;IAC3C,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;IAC/D,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AA0DD,0EAA0E;AAC1E,0EAA0E;AAC1E,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,kDAAkD;AAClD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAiB;IAC5C,MAAM,UAAU,GAAG,mBAAmB,GAAG,CAAC,UAAU,EAAE,CAAC;IACvD,MAAM,IAAI,GAAmB,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;IAEpF,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC;QACjC,OAAO,MAAM,CAAC,GAAG,EAAE;YACjB,SAAS,EAAE,KAAK;YAChB,UAAU,EAAE,MAAM;YAClB,aAAa,EAAE,IAAI;YACnB,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,KAAK;YACvB,IAAI,EACF,OAAO,KAAK,IAAI;gBACd,CAAC,CAAC,iBAAiB,GAAG,CAAC,OAAO,0CAA0C;oBACtE,GAAG,OAAO,CAAC,eAAe,iBAAiB,OAAO,CAAC,QAAQ,aAAa;oBACxE,uEAAuE;oBACvE,uEAAuE;gBACzE,CAAC,CAAC,qBAAqB,GAAG,CAAC,OAAO,yCAAyC;oBACzE,oEAAoE;oBACpE,iEAAiE;oBACjE,0DAA0D;oBAC1D,4DAA4D;oBAC5D,qEAAqE;oBACrE,iBAAiB,UAAU,IAAI;SACtC,CAAC,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,gEAAgE;IAChE,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAC,GAAG,EAAE;YACjB,SAAS,EAAE,KAAK;YAChB,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,IAAI;YACnB,iBAAiB,EAAE,KAAK,CAAC,KAAK;YAC9B,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,KAAK;YACvB,IAAI,EACF,KAAK,CAAC,KAAK,KAAK,aAAa;gBAC3B,CAAC,CAAC,kCAAkC,KAAK,CAAC,KAAK,yBAAyB;oBACtE,gCAAgC;gBAClC,CAAC,CAAC,mEAAmE;oBACnE,IAAI,KAAK,CAAC,KAAK,oDAAoD;oBACnE,yCAAyC;SAChD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,GAAG,EAAE;YACjB,SAAS,EAAE,KAAK;YAChB,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,KAAK;YACvB,IAAI,EACF,IAAI,KAAK,SAAS;gBAChB,CAAC,CAAC,wEAAwE;oBACxE,2EAA2E;gBAC7E,CAAC,CAAC,uEAAuE;SAC9E,CAAC,CAAC;IACL,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEpE,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GACR,GAAG,CAAC,YAAY,KAAK,IAAI;YACvB,CAAC,CAAC,+BAA+B,UAAU,cAAc;gBACvD,IAAI,GAAG,CAAC,YAAY,kBAAkB;YACxC,CAAC,CAAC,+BAA+B,UAAU,wBAAwB;gBACjE,+DAA+D,CAAC;QACtE,OAAO,MAAM,CAAC,GAAG,EAAE;YACjB,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,IAAI;YACnB,KAAK;YACL,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,IAAI;YACtB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,GAAG,EAAE;YACjB,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,IAAI;YACnB,KAAK;YACL,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,KAAK;YACvB,IAAI,EACF,mCAAmC,GAAG,CAAC,KAAK,8BAA8B;gBAC1E,uEAAuE;gBACvE,IAAI,UAAU,0BAA0B;SAC3C,CAAC,CAAC;IACL,CAAC;IACD,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC;IAC/B,MAAM,OAAO,GACX,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAC/E,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC,GAAG,EAAE;YACjB,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,IAAI;YACnB,KAAK;YACL,OAAO;YACP,gBAAgB,EAAE,IAAI;YACtB,IAAI,EAAE,uBAAuB,CAAC,CAAC,GAAG,4CAA4C;SAC/E,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,EAAE;QACjB,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,KAAK;QACL,OAAO;QACP,gBAAgB,EAAE,IAAI;QACtB,IAAI,EAAE,sBAAsB,GAAG,CAAC,KAAK,gBAAgB,UAAU,cAAc;KAC9E,CAAC,CAAC;AACL,CAAC;AAWD,mEAAmE;AACnE,6EAA6E;AAC7E,mDAAmD;AACnD,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,sEAAsE;AACtE,wEAAwE;AACxE,qEAAqE;AACrE,4EAA4E;AAC5E,0EAA0E;AAC1E,4CAA4C;AAC5C,KAAK,UAAU,SAAS,CAAC,GAAa;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,GAAG,CAAe,SAAS,CAAC,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;YAC3E,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;YAC1E,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAChD,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACrF,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,2EAA2E;AAC3E,6CAA6C;AAC7C,KAAK,UAAU,UAAU,CAAC,GAAa;IACrC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAqB,WAAW,CAAC,CAAC;QAC1D,OAAO,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAC1E,KAAK,UAAU,YAAY,CACzB,GAAa,EACb,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,GAAG,CAAgB,SAAS,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC3F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC;YAC/E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,kDAAkD;AAClD,0EAA0E;AAC1E,6EAA6E;AAC7E,6CAA6C;AAC7C,SAAS,kBAAkB,CAAC,GAAiB;IAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC;IACjC,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,QAAQ;QAC3B,gBAAgB,EAAE,OAAO,CAAC,eAAe;QACzC,kBAAkB,EAAE,SAAS;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CACb,GAAiB,EACjB,IAAgE;IAEhE,MAAM,MAAM,GAAiB;QAC3B,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,MAAM,EAAE,GAAG,CAAC,KAAK;QACjB,aAAa,EAAE,kBAAkB,CAAC,GAAG,CAAC;QACtC,GAAG,IAAI;KACR,CAAC;IACF,MAAM,IAAI,GACR,MAAM,CAAC,UAAU,KAAK,MAAM;QAC1B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,MAAM,CAAC,aAAa,KAAK,KAAK;YAC9B,CAAC,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa;YACpD,CAAC,CAAC,MAAM,CAAC,aAAa,KAAK,IAAI;gBAC7B,CAAC,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,iBAAiB,MAAM,CAAC,iBAAiB,IAAI,YAAY,GAAG;gBACnG,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI;oBACrB,CAAC,CAAC,gBAAgB,MAAM,CAAC,KAAK,EAAE;oBAChC,CAAC,CAAC,cAAc,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;IAChE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC;QAC/B,GAAG,CAAC,GAAG,CAAC,IAAI,CACV,0CAA0C,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,gBAAgB,GAAG;YAC/E,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,GAAG,EAAE,CAAC,YAAY,CACvD,CAAC;IACJ,CAAC;IACD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,MAAM,IAAI,oCAAoC,EAAE,CAAC,CAAC;IACxF,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;QACzB,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG;YACvB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE;YAC9C,CAAC,CAAC,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,uBAAuB;gBACzB,CAAC,CAAC,aAAa,CAAC;QACpB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,WAAW,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,eAAe,CAAC,IAAoB;IAC3C,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AACxF,CAAC"}
@@ -0,0 +1,40 @@
1
+ export interface Origins {
2
+ apiBaseUrl: string;
3
+ authBaseUrl: string;
4
+ dashboardBaseUrl: string;
5
+ }
6
+ export interface OriginOverrides {
7
+ apiBaseUrl?: string;
8
+ authBaseUrl?: string;
9
+ dashboardBaseUrl?: string;
10
+ }
11
+ export declare function resolveOrigins(overrides: OriginOverrides): Origins;
12
+ export type Profile = string;
13
+ export interface StoredCredential {
14
+ token?: string;
15
+ session?: {
16
+ sid: string;
17
+ };
18
+ }
19
+ export interface CredentialsFile {
20
+ version: 1;
21
+ credentials: Record<Profile, StoredCredential>;
22
+ }
23
+ export interface CredentialInputs {
24
+ flagToken?: string;
25
+ envToken?: string;
26
+ file?: CredentialsFile;
27
+ profile: Profile;
28
+ }
29
+ export type ResolvedCredential = {
30
+ kind: 'service';
31
+ token: string;
32
+ source: 'flag' | 'env' | 'file';
33
+ } | {
34
+ kind: 'session';
35
+ sid: string;
36
+ source: 'file';
37
+ };
38
+ export declare function resolveCredential(inputs: CredentialInputs): ResolvedCredential | null;
39
+ export declare function profileForOrigins(origins: Origins): Profile;
40
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAYD,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAKD,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAQlE;AASD,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAM7B,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B;AACD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAC;IACX,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAE/B,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAMrD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,IAAI,CAerF;AAWD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAI3D"}