@autohq/cli 0.1.100 → 0.1.101

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 (2) hide show
  1. package/dist/index.js +137 -71
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21761,7 +21761,7 @@ var init_package = __esm({
21761
21761
  "package.json"() {
21762
21762
  package_default = {
21763
21763
  name: "@autohq/cli",
21764
- version: "0.1.100",
21764
+ version: "0.1.101",
21765
21765
  license: "SEE LICENSE IN README.md",
21766
21766
  publishConfig: {
21767
21767
  access: "public"
@@ -29221,6 +29221,66 @@ function createGithubConnectionApi(context) {
29221
29221
  };
29222
29222
  }
29223
29223
 
29224
+ // src/commands/connections/wait.ts
29225
+ init_browser();
29226
+ var ConnectionWaitTimeoutError = class extends Error {
29227
+ };
29228
+ async function finishConnectionAuthorization(input) {
29229
+ const knownGrantIds = input.wait ? await activeGrantIds(input) : void 0;
29230
+ if (input.openInBrowser) {
29231
+ (input.openBrowser ?? openBrowser)(input.authorizationUrl);
29232
+ }
29233
+ if (!knownGrantIds) {
29234
+ return void 0;
29235
+ }
29236
+ input.writeOutput(
29237
+ `Waiting for the ${input.provider} authorization to complete in the browser...`
29238
+ );
29239
+ return waitForNewGrant(input, knownGrantIds);
29240
+ }
29241
+ var POLL_INTERVAL_MS = 2e3;
29242
+ var POLL_TIMEOUT_MS = 5 * 6e4;
29243
+ async function activeGrantIds(input) {
29244
+ const result = await input.client.listConnections({
29245
+ provider: input.provider,
29246
+ apiBaseUrl: input.apiBaseUrl
29247
+ });
29248
+ return new Set(
29249
+ result.connections.flatMap(
29250
+ (connection) => connection.grants.map((grant) => grant.id)
29251
+ )
29252
+ );
29253
+ }
29254
+ async function waitForNewGrant(input, knownGrantIds) {
29255
+ const sleep3 = input.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
29256
+ const now3 = input.now ?? Date.now;
29257
+ const deadline = now3() + (input.pollTimeoutMs ?? POLL_TIMEOUT_MS);
29258
+ while (now3() < deadline) {
29259
+ await sleep3(input.pollIntervalMs ?? POLL_INTERVAL_MS);
29260
+ const result = await input.client.listConnections({
29261
+ provider: input.provider,
29262
+ apiBaseUrl: input.apiBaseUrl
29263
+ });
29264
+ for (const connection of result.connections) {
29265
+ for (const grant of connection.grants) {
29266
+ if (knownGrantIds.has(grant.id)) {
29267
+ continue;
29268
+ }
29269
+ input.writeOutput(
29270
+ `connected ${input.provider} connection/${grant.name} account/${connection.externalAccount.loginOrName}`
29271
+ );
29272
+ return {
29273
+ connection: grant.name,
29274
+ account: connection.externalAccount.loginOrName
29275
+ };
29276
+ }
29277
+ }
29278
+ }
29279
+ throw new ConnectionWaitTimeoutError(
29280
+ `Timed out waiting for the ${input.provider} connection to complete. The authorization may still land (or may have re-authorized an existing connection); check \`auto connections list --provider ${input.provider}\`, or re-run with --no-wait to skip waiting.`
29281
+ );
29282
+ }
29283
+
29224
29284
  // src/commands/connections/github.ts
29225
29285
  async function connectGithub(context, commandOptions) {
29226
29286
  const githubApi = createGithubConnectionApi(context);
@@ -29265,17 +29325,25 @@ async function connectGithub(context, commandOptions) {
29265
29325
  await startGithubInstallFlow(context, commandOptions);
29266
29326
  }
29267
29327
  async function startGithubInstallFlow(context, commandOptions) {
29268
- const result = await createConnectionServiceClient(context).startConnection(
29269
- "github",
29270
- {
29271
- allowProjectId: commandOptions.allow,
29272
- apiBaseUrl: commandOptions.apiBaseUrl
29273
- }
29274
- );
29328
+ const client = createConnectionServiceClient(context);
29329
+ const result = await client.startConnection("github", {
29330
+ allowProjectId: commandOptions.allow,
29331
+ apiBaseUrl: commandOptions.apiBaseUrl
29332
+ });
29275
29333
  context.writeOutput(result.message);
29276
- if (result.authorizationUrl) {
29277
- context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29334
+ if (!result.authorizationUrl) {
29335
+ return;
29278
29336
  }
29337
+ context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29338
+ await finishConnectionAuthorization({
29339
+ apiBaseUrl: commandOptions.apiBaseUrl,
29340
+ authorizationUrl: result.authorizationUrl,
29341
+ client,
29342
+ provider: "github",
29343
+ openInBrowser: commandOptions.browser !== false && context.io.isTTY,
29344
+ wait: commandOptions.wait !== false,
29345
+ writeOutput: context.writeOutput
29346
+ });
29279
29347
  }
29280
29348
  async function selectGithubInstallation(input) {
29281
29349
  if (input.selector) {
@@ -29559,27 +29627,40 @@ async function connectProviderAction(context, provider, commandOptions) {
29559
29627
  });
29560
29628
  return;
29561
29629
  }
29630
+ if (commandOptions.configRefreshToken && commandOptions.wait === false) {
29631
+ throw new Error(
29632
+ "--config-refresh-token registers the token once the connection completes; it cannot be combined with --no-wait."
29633
+ );
29634
+ }
29562
29635
  const client = createConnectionServiceClient(context);
29563
- const knownGrants = commandOptions.configRefreshToken ? await slackGrantNames(client, apiBaseUrl) : void 0;
29564
29636
  const result = await client.startConnection(provider, {
29565
29637
  allowProjectId: commandOptions.allow,
29566
29638
  apiBaseUrl
29567
29639
  });
29568
29640
  context.writeOutput(result.message);
29569
- if (result.authorizationUrl) {
29570
- context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29641
+ if (!result.authorizationUrl) {
29642
+ return;
29571
29643
  }
29572
- if (commandOptions.configRefreshToken && knownGrants) {
29573
- context.writeOutput(
29574
- "Waiting for the Slack connection to complete before registering the config token..."
29575
- );
29576
- const connection = await waitForNewSlackGrant(
29577
- client,
29578
- apiBaseUrl,
29579
- knownGrants
29580
- );
29644
+ context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29645
+ const connected = await finishConnectionAuthorization({
29646
+ apiBaseUrl,
29647
+ authorizationUrl: result.authorizationUrl,
29648
+ client,
29649
+ provider,
29650
+ openInBrowser: commandOptions.browser !== false && context.io.isTTY,
29651
+ wait: commandOptions.wait !== false,
29652
+ writeOutput: context.writeOutput
29653
+ }).catch((error51) => {
29654
+ if (error51 instanceof ConnectionWaitTimeoutError && commandOptions.configRefreshToken) {
29655
+ throw new Error(
29656
+ `${error51.message} Register the config token afterwards with \`auto connections config-token slack\`.`
29657
+ );
29658
+ }
29659
+ throw error51;
29660
+ });
29661
+ if (commandOptions.configRefreshToken && connected) {
29581
29662
  const registered = await client.registerSlackConfigToken({
29582
- connection,
29663
+ connection: connected.connection,
29583
29664
  refreshToken: commandOptions.configRefreshToken,
29584
29665
  apiBaseUrl
29585
29666
  });
@@ -29588,36 +29669,6 @@ async function connectProviderAction(context, provider, commandOptions) {
29588
29669
  );
29589
29670
  }
29590
29671
  }
29591
- var NEW_GRANT_POLL_INTERVAL_MS = 2e3;
29592
- var NEW_GRANT_POLL_TIMEOUT_MS = 5 * 6e4;
29593
- async function slackGrantNames(client, apiBaseUrl) {
29594
- const result = await client.listConnections({
29595
- provider: "slack",
29596
- apiBaseUrl
29597
- });
29598
- return new Set(
29599
- result.connections.flatMap(
29600
- (connection) => connection.grants.map((grant) => grant.name)
29601
- )
29602
- );
29603
- }
29604
- async function waitForNewSlackGrant(client, apiBaseUrl, knownGrants) {
29605
- const deadline = Date.now() + NEW_GRANT_POLL_TIMEOUT_MS;
29606
- while (Date.now() < deadline) {
29607
- await new Promise(
29608
- (resolve2) => setTimeout(resolve2, NEW_GRANT_POLL_INTERVAL_MS)
29609
- );
29610
- const current = await slackGrantNames(client, apiBaseUrl);
29611
- for (const name of current) {
29612
- if (!knownGrants.has(name)) {
29613
- return name;
29614
- }
29615
- }
29616
- }
29617
- throw new Error(
29618
- "Timed out waiting for the Slack connection to complete. Register the config token afterwards with `auto connections config-token slack`."
29619
- );
29620
- }
29621
29672
  async function registerConfigTokenAction(context, provider, commandOptions) {
29622
29673
  if (provider !== "slack") {
29623
29674
  throw new Error(
@@ -29684,21 +29735,30 @@ async function replaceConnectionAction(context, provider, commandOptions) {
29684
29735
  yes: commandOptions.yes
29685
29736
  });
29686
29737
  }
29687
- const result = await createConnectionServiceClient(context).startConnection(
29688
- provider,
29689
- {
29690
- allowProjectId: commandOptions.allow,
29691
- apiBaseUrl: apiUrlFromOptions(context, commandOptions),
29692
- replace: {
29693
- connection: commandOptions.connection,
29694
- removeFirst: commandOptions.removeFirst === true
29695
- }
29738
+ const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
29739
+ const client = createConnectionServiceClient(context);
29740
+ const result = await client.startConnection(provider, {
29741
+ allowProjectId: commandOptions.allow,
29742
+ apiBaseUrl,
29743
+ replace: {
29744
+ connection: commandOptions.connection,
29745
+ removeFirst: commandOptions.removeFirst === true
29696
29746
  }
29697
- );
29747
+ });
29698
29748
  context.writeOutput(result.message);
29699
- if (result.authorizationUrl) {
29700
- context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29749
+ if (!result.authorizationUrl) {
29750
+ return;
29701
29751
  }
29752
+ context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29753
+ await finishConnectionAuthorization({
29754
+ apiBaseUrl,
29755
+ authorizationUrl: result.authorizationUrl,
29756
+ client,
29757
+ provider,
29758
+ openInBrowser: commandOptions.browser !== false && context.io.isTTY,
29759
+ wait: commandOptions.wait !== false,
29760
+ writeOutput: context.writeOutput
29761
+ });
29702
29762
  }
29703
29763
 
29704
29764
  // src/commands/connections/commands.ts
@@ -29725,7 +29785,10 @@ function registerConnectionCommands(program, context) {
29725
29785
  ).option(
29726
29786
  "--remove-first",
29727
29787
  "remove the old connection before the replacement authorization completes"
29728
- ).option("-y, --yes", "skip confirmation prompt when using --remove-first").option("--allow <project>", "project id to allow after connecting").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (provider, commandOptions) => {
29788
+ ).option("-y, --yes", "skip confirmation prompt when using --remove-first").option("--allow <project>", "project id to allow after connecting").option(
29789
+ "--no-wait",
29790
+ "print the authorization URL and exit without waiting for the replacement to complete"
29791
+ ).option("--no-browser", "do not open the authorization URL in a browser").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (provider, commandOptions) => {
29729
29792
  await replaceConnectionAction(context, provider, commandOptions);
29730
29793
  });
29731
29794
  program.command("connect").description("Start a provider connection flow.").argument("<provider>", "provider name").option("--allow <project>", "project id to allow after connecting").option(
@@ -29746,7 +29809,10 @@ function registerConnectionCommands(program, context) {
29746
29809
  ).option(
29747
29810
  "--manual",
29748
29811
  "print the setup steps instead of the interactive wizard (telegram only)"
29749
- ).option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (provider, commandOptions) => {
29812
+ ).option(
29813
+ "--no-wait",
29814
+ "print the authorization URL and exit without waiting for the connection to complete"
29815
+ ).option("--no-browser", "do not open the authorization URL in a browser").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (provider, commandOptions) => {
29750
29816
  await connectProviderAction(context, provider, commandOptions);
29751
29817
  });
29752
29818
  program.command("allow").description("Allow a project to use an existing provider connection.").argument("<provider>", "provider name").argument("<project>", "project id").option("--connection <name>", "specific connection or grant name").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(
@@ -31644,8 +31710,8 @@ init_browser();
31644
31710
  import { existsSync as existsSync2, mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync4 } from "fs";
31645
31711
  import { homedir as homedir3, tmpdir as tmpdir2 } from "os";
31646
31712
  import { join as join6 } from "path";
31647
- var POLL_INTERVAL_MS = 2e3;
31648
- var POLL_TIMEOUT_MS = 5 * 6e4;
31713
+ var POLL_INTERVAL_MS2 = 2e3;
31714
+ var POLL_TIMEOUT_MS2 = 5 * 6e4;
31649
31715
  var SLACK_APPS_URL = "https://api.slack.com/apps";
31650
31716
  async function connectSessionPresence2(input) {
31651
31717
  const options = { apiBaseUrl: input.apiBaseUrl };
@@ -31694,8 +31760,8 @@ async function connectSessionPresence2(input) {
31694
31760
  const sleep3 = input.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
31695
31761
  const openBrowser2 = input.openBrowser ?? openBrowser;
31696
31762
  const now3 = input.now ?? Date.now;
31697
- const pollIntervalMs = input.pollIntervalMs ?? POLL_INTERVAL_MS;
31698
- const pollTimeoutMs = input.pollTimeoutMs ?? POLL_TIMEOUT_MS;
31763
+ const pollIntervalMs = input.pollIntervalMs ?? POLL_INTERVAL_MS2;
31764
+ const pollTimeoutMs = input.pollTimeoutMs ?? POLL_TIMEOUT_MS2;
31699
31765
  for (const pending of result.pending) {
31700
31766
  const telegram = Boolean(pending.suggestedUsername);
31701
31767
  input.writeOutput(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.100",
3
+ "version": "0.1.101",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"