@doist/automations-cli 1.17.1 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6899,7 +6899,7 @@ import { fileURLToPath } from "node:url";
6899
6899
  // package.json
6900
6900
  var package_default = {
6901
6901
  name: "@doist/automations-cli",
6902
- version: "1.17.1",
6902
+ version: "1.18.0",
6903
6903
  description: "Command-line client for Todoist Automations",
6904
6904
  type: "module",
6905
6905
  bin: {
@@ -6953,13 +6953,13 @@ var package_default = {
6953
6953
  devDependencies: {
6954
6954
  "@doist/automations-core": "*",
6955
6955
  "@doist/automations-sdk": "*",
6956
- "@types/node": "24.13.6",
6956
+ "@types/node": "24.19.1",
6957
6957
  "conventional-changelog-conventionalcommits": "9.3.1",
6958
6958
  esbuild: "0.28.2",
6959
6959
  "semantic-release": "25.0.9",
6960
6960
  "semantic-release-monorepo": "8.0.2",
6961
6961
  typescript: "6.0.3",
6962
- vitest: "4.1.11"
6962
+ vitest: "5.0.3"
6963
6963
  },
6964
6964
  engines: {
6965
6965
  node: ">=24"
@@ -7037,6 +7037,10 @@ var API_SCOPES = {
7037
7037
  };
7038
7038
  var API_SCOPE_CODES = Object.keys(API_SCOPES);
7039
7039
 
7040
+ // ../../packages/core/dist/esm/constants/cli-client.constants.js
7041
+ var AUTOMATIONS_CLI_CLIENT_NAME = "Todoist Automations CLI";
7042
+ var AUTOMATIONS_CLI_LOGO_URL = "https://todoist.b-cdn.net/agentist-icons/service_automations-cli_color_192px.png";
7043
+
7040
7044
  // ../../packages/core/dist/esm/constants/connection.constants.js
7041
7045
  var CONNECTION_STATUSES = ["pending", "authorized", "expired", "error"];
7042
7046
  var CONNECTION_TYPES = ["mcp", "trigger", "api"];
@@ -7124,71 +7128,98 @@ var MODEL_CATALOG = {
7124
7128
  "gemini-2.5-flash-lite": {
7125
7129
  provider: "gemini",
7126
7130
  family: "2.5",
7127
- providerModelId: "gemini-2.5-flash-lite"
7131
+ providerModelId: "gemini-2.5-flash-lite",
7132
+ manifestSelectable: true
7128
7133
  },
7129
7134
  "gemini-2.5-flash": {
7130
7135
  provider: "gemini",
7131
7136
  family: "2.5",
7132
- providerModelId: "gemini-2.5-flash"
7137
+ providerModelId: "gemini-2.5-flash",
7138
+ manifestSelectable: true
7133
7139
  },
7134
7140
  "gemini-3.1-pro": {
7135
7141
  provider: "gemini",
7136
7142
  family: "3",
7137
- providerModelId: "gemini-3.1-pro-preview"
7143
+ providerModelId: "gemini-3.1-pro-preview",
7144
+ manifestSelectable: true
7138
7145
  },
7139
7146
  "gemini-3.8-flash": {
7140
7147
  provider: "gemini",
7141
7148
  family: "3",
7142
- providerModelId: "gemini-3.8-flash"
7149
+ providerModelId: "gemini-3.8-flash",
7150
+ manifestSelectable: true
7143
7151
  },
7144
7152
  "claude-opus-4-6": {
7145
7153
  provider: "anthropic",
7146
7154
  family: "4.6",
7147
- providerModelId: "claude-opus-4-6"
7155
+ providerModelId: "claude-opus-4-6",
7156
+ manifestSelectable: true
7148
7157
  },
7149
7158
  "claude-sonnet-5": {
7150
7159
  provider: "anthropic",
7151
7160
  family: "5",
7152
- providerModelId: "claude-sonnet-5"
7161
+ providerModelId: "claude-sonnet-5",
7162
+ manifestSelectable: true
7163
+ },
7164
+ "claude-sonnet-5-5": {
7165
+ provider: "anthropic",
7166
+ family: "5",
7167
+ providerModelId: "claude-sonnet-5-5",
7168
+ manifestSelectable: false
7169
+ },
7170
+ "claude-haiku-5-5": {
7171
+ provider: "anthropic",
7172
+ family: "5",
7173
+ providerModelId: "claude-haiku-5-5",
7174
+ manifestSelectable: false
7153
7175
  },
7154
7176
  "claude-sonnet-4-6": {
7155
7177
  provider: "anthropic",
7156
7178
  family: "4.6",
7157
- providerModelId: "claude-sonnet-4-6"
7179
+ providerModelId: "claude-sonnet-4-6",
7180
+ manifestSelectable: true
7158
7181
  },
7159
7182
  "claude-haiku-4-5": {
7160
7183
  provider: "anthropic",
7161
7184
  family: "4.5",
7162
- providerModelId: "claude-haiku-4-5"
7185
+ providerModelId: "claude-haiku-4-5",
7186
+ manifestSelectable: true
7163
7187
  },
7164
7188
  "deepseek-v4-flash": {
7165
7189
  provider: "openrouter",
7166
7190
  family: "deepseek",
7167
- providerModelId: "deepseek/deepseek-v4-flash-0731"
7191
+ providerModelId: "deepseek/deepseek-v4-flash-0731",
7192
+ manifestSelectable: true
7168
7193
  },
7169
7194
  "deepseek-v4-pro": {
7170
7195
  provider: "openrouter",
7171
7196
  family: "deepseek",
7172
- providerModelId: "deepseek/deepseek-v4-pro"
7197
+ providerModelId: "deepseek/deepseek-v4-pro",
7198
+ manifestSelectable: true
7173
7199
  },
7174
7200
  "mimo-v2.5": {
7175
7201
  provider: "openrouter",
7176
7202
  family: "mimo",
7177
- providerModelId: "xiaomi/mimo-v2.5"
7203
+ providerModelId: "xiaomi/mimo-v2.5",
7204
+ manifestSelectable: true
7178
7205
  },
7179
7206
  "mimo-v2.5-pro": {
7180
7207
  provider: "openrouter",
7181
7208
  family: "mimo",
7182
- providerModelId: "xiaomi/mimo-v2.5-pro"
7209
+ providerModelId: "xiaomi/mimo-v2.5-pro",
7210
+ manifestSelectable: true
7183
7211
  },
7184
7212
  "glm-5.2": {
7185
7213
  provider: "openrouter",
7186
7214
  family: "glm",
7187
- providerModelId: "z-ai/glm-5.2"
7215
+ providerModelId: "z-ai/glm-5.2",
7216
+ manifestSelectable: true
7188
7217
  }
7189
7218
  };
7190
7219
  var SUPPORTED_LLM_MODELS = Object.keys(MODEL_CATALOG);
7191
7220
  var SUPPORTED_SEARCH_MODELS = SUPPORTED_LLM_MODELS.filter(supportsWebSearch);
7221
+ var MANIFEST_LLM_MODELS = SUPPORTED_LLM_MODELS.filter((modelId) => MODEL_CATALOG[modelId].manifestSelectable);
7222
+ var MANIFEST_SEARCH_MODELS = MANIFEST_LLM_MODELS.filter((modelId) => supportsWebSearch(modelId));
7192
7223
  function supportsWebSearch(modelId) {
7193
7224
  const { provider } = MODEL_CATALOG[modelId];
7194
7225
  return provider === "gemini" || provider === "anthropic";
@@ -27675,7 +27706,12 @@ var ConnectorSchema = external_exports.object({
27675
27706
  * connection types — one onboarding covers both action and trigger uses.
27676
27707
  * The FE collapses per-type rows into a single account when this is true.
27677
27708
  */
27678
- isManaged: external_exports.boolean().optional()
27709
+ isManaged: external_exports.boolean().optional(),
27710
+ /**
27711
+ * The service only admits loopback OAuth clients, so account setup runs in
27712
+ * the Automations CLI on the user's machine instead of the web app.
27713
+ */
27714
+ connectsViaCli: external_exports.boolean().optional()
27679
27715
  });
27680
27716
  var GetConnectorsQuerySchema = external_exports.object({
27681
27717
  query: external_exports.string().optional()
@@ -27701,6 +27737,11 @@ var connectorListResponseSchema = external_exports.object({
27701
27737
  nextCursor: external_exports.string().nullable()
27702
27738
  });
27703
27739
 
27740
+ // ../../packages/core/dist/esm/utils/cli-command.js
27741
+ function connectViaCliCommand(connectorId, capability) {
27742
+ return `tda connector connect ${connectorId} --capability ${capability}`;
27743
+ }
27744
+
27704
27745
  // ../../packages/core/dist/esm/utils/duration.js
27705
27746
  var durationUnits = ["ms", "s", "m", "h", "d", "w"];
27706
27747
  var createDurationPattern = (units) => units.join("|");
@@ -28068,7 +28109,7 @@ var baseStepSchema = external_exports.object({
28068
28109
  })
28069
28110
  });
28070
28111
  var MODEL_TIERS = ["lite", "flash", "pro"];
28071
- var SUPPORTED_MODEL_REFERENCES = [...MODEL_TIERS, ...SUPPORTED_LLM_MODELS];
28112
+ var SUPPORTED_MODEL_REFERENCES = [...MODEL_TIERS, ...MANIFEST_LLM_MODELS];
28072
28113
  var modelReferenceSchema = external_exports.enum(SUPPORTED_MODEL_REFERENCES).meta({
28073
28114
  description: "A stable model tier (lite, flash, pro) or a supported literal model override."
28074
28115
  });
@@ -28124,7 +28165,7 @@ var searchStepSchema = baseStepSchema.merge(external_exports.object({
28124
28165
  description: "The search prompt to execute using web search."
28125
28166
  }),
28126
28167
  outputSchema: searchStepOutputSchema,
28127
- model: external_exports.enum([...MODEL_TIERS, ...SUPPORTED_SEARCH_MODELS]).optional().meta({
28168
+ model: external_exports.enum([...MODEL_TIERS, ...MANIFEST_SEARCH_MODELS]).optional().meta({
28128
28169
  description: "A stable tier (lite, flash, pro) or a supported search-enabled literal model override."
28129
28170
  })
28130
28171
  }));
@@ -28753,6 +28794,29 @@ var CreateConnectionParamsSchema = external_exports.object({
28753
28794
  var CreateConnectionBodySchema = external_exports.object({
28754
28795
  automationIds: external_exports.array(external_exports.uuid()).optional()
28755
28796
  });
28797
+ var ImportLocalOAuthConnectionBodySchema = external_exports.object({
28798
+ /** The public client the CLI registered; the server bound the grant to it. */
28799
+ clientId: external_exports.string().min(1),
28800
+ accessToken: external_exports.string().min(1),
28801
+ refreshToken: external_exports.string().min(1).optional(),
28802
+ /** Seconds until `accessToken` expires, as the token endpoint reported it. */
28803
+ expiresIn: external_exports.number().int().positive().optional(),
28804
+ /**
28805
+ * A broken connection of the caller's, for the same connector, whose
28806
+ * automation bindings move to the new grant when the account cannot be
28807
+ * matched to it.
28808
+ */
28809
+ repairConnectionId: external_exports.uuid().optional()
28810
+ });
28811
+ var LocalOAuthSetupSchema = external_exports.object({
28812
+ /** RFC 7591 registration endpoint; null when the server offers none. */
28813
+ registrationEndpoint: external_exports.string().url().nullable(),
28814
+ authorizationEndpoint: external_exports.string().url(),
28815
+ tokenEndpoint: external_exports.string().url(),
28816
+ /** RFC 8707 resource indicator for the MCP server, when it advertises one. */
28817
+ resource: external_exports.string().url().nullable(),
28818
+ scopes: external_exports.array(external_exports.string())
28819
+ });
28756
28820
  var OAuthConnectionSetupSchema = external_exports.object({
28757
28821
  kind: external_exports.literal("oauth"),
28758
28822
  authorizationUrl: external_exports.string().url()
@@ -29572,7 +29636,9 @@ var FRONTEND_COHORT_EVENTS = [
29572
29636
  "chat:sent",
29573
29637
  "automation:repaired",
29574
29638
  "template:used",
29575
- "top-up:completed"
29639
+ "top-up:completed",
29640
+ "guided-creation:started",
29641
+ "guided-creation:completed"
29576
29642
  ];
29577
29643
  var BACKEND_COHORT_EVENTS = [
29578
29644
  // API-process (publish lifecycle)
@@ -31326,6 +31392,7 @@ var connectionsEndpoints = {
31326
31392
  token: (id) => `${root10}/${encodeURIComponent(id)}/token`,
31327
31393
  dependentAutomations: (connectorId) => `${root10}/${encodeURIComponent(connectorId)}/automations`,
31328
31394
  create: (connectorId, capability) => `${root10}/${encodeURIComponent(connectorId)}/${encodeURIComponent(capability)}`,
31395
+ localOAuth: (connectorId, capability) => `${root10}/${encodeURIComponent(connectorId)}/${encodeURIComponent(capability)}/local-oauth`,
31329
31396
  checkManifest: `${root10}/check-manifest`
31330
31397
  };
31331
31398
 
@@ -31405,6 +31472,41 @@ var ConnectionsClient = class extends BaseClient {
31405
31472
  });
31406
31473
  return CreateConnectionResponseSchema.parse(data);
31407
31474
  }
31475
+ /**
31476
+ * The authorization server endpoints and scopes for running a
31477
+ * `connectsViaCli` connector's OAuth flow with a loopback client.
31478
+ */
31479
+ async getLocalOAuthSetup(args, options) {
31480
+ const { connectorId, capability } = CreateConnectionParamsSchema.parse({
31481
+ connectorId: IdSchema.parse(args.connectorId),
31482
+ capability: args.capability
31483
+ });
31484
+ const data = await this.request({
31485
+ method: "GET",
31486
+ path: connectionsEndpoints.localOAuth(connectorId, capability),
31487
+ options
31488
+ });
31489
+ return LocalOAuthSetupSchema.parse(data);
31490
+ }
31491
+ /**
31492
+ * Stores a grant the CLI obtained with a loopback OAuth client, for a
31493
+ * connector whose authorization server admits no hosted clients
31494
+ * (`connectsViaCli`). The connection comes back already authorized.
31495
+ */
31496
+ async importLocalOAuth(args, options) {
31497
+ const { connectorId, capability } = CreateConnectionParamsSchema.parse({
31498
+ connectorId: IdSchema.parse(args.connectorId),
31499
+ capability: args.capability
31500
+ });
31501
+ const body = ImportLocalOAuthConnectionBodySchema.parse(args.grant);
31502
+ const data = await this.request({
31503
+ method: "POST",
31504
+ path: connectionsEndpoints.localOAuth(connectorId, capability),
31505
+ body,
31506
+ options
31507
+ });
31508
+ return CreateConnectionResponseSchema.parse(data);
31509
+ }
31408
31510
  async checkManifest(manifest, options) {
31409
31511
  const parsedManifest = partialManifestSchema.parse(manifest);
31410
31512
  const data = await this.request({
@@ -35815,6 +35917,13 @@ async function* streamConnectorNdjsonItems(api, options, signal) {
35815
35917
  }
35816
35918
  yield { _meta: true, connectionsIncluded: options.connections };
35817
35919
  }
35920
+ async function findListedConnector(api, connectorId, signal) {
35921
+ for await (const page of iterateConnectorPages(api, void 0, { signal })) {
35922
+ const connector = page.data.find((candidate) => candidate.id === connectorId);
35923
+ if (connector) return connector;
35924
+ }
35925
+ return void 0;
35926
+ }
35818
35927
  function findConnector2(api, connectorId, signal) {
35819
35928
  return findConnector(api, connectorId, { signal });
35820
35929
  }
@@ -35842,6 +35951,8 @@ async function runAuthorizationCommand(command, operation) {
35842
35951
  return operation({
35843
35952
  api,
35844
35953
  signal,
35954
+ output: output2,
35955
+ openBrowser: options.open,
35845
35956
  authorizer: new ApiConnectionAuthorizer({
35846
35957
  connections: api.connections,
35847
35958
  output: output2,
@@ -35931,17 +36042,172 @@ function summarizeAffectedAutomation(automation) {
35931
36042
  };
35932
36043
  }
35933
36044
 
36045
+ // src/commands/connector/local-oauth-connect.ts
36046
+ import { createDcrProvider, runOAuthFlow } from "@doist/cli-core/auth";
36047
+ var PREFERRED_CALLBACK_PORT = 24369;
36048
+ async function connectViaLocalOAuth({
36049
+ api,
36050
+ connector,
36051
+ capability,
36052
+ repairConnectionId,
36053
+ output: output2,
36054
+ openBrowser,
36055
+ signal
36056
+ }) {
36057
+ const setup = await api.connections.getLocalOAuthSetup(
36058
+ { connectorId: connector.id, capability },
36059
+ { signal }
36060
+ );
36061
+ const { registrationEndpoint } = setup;
36062
+ if (!registrationEndpoint) {
36063
+ throw new Error(
36064
+ `${connector.name} does not support dynamic client registration, so the CLI cannot connect it.`
36065
+ );
36066
+ }
36067
+ const grant = await runLoopbackGrant({
36068
+ connector,
36069
+ capability,
36070
+ setup,
36071
+ registrationEndpoint,
36072
+ output: output2,
36073
+ openBrowser,
36074
+ signal
36075
+ });
36076
+ const created = await api.connections.importLocalOAuth(
36077
+ {
36078
+ connectorId: connector.id,
36079
+ capability,
36080
+ grant: {
36081
+ clientId: grant.account.clientId,
36082
+ accessToken: grant.bundle.accessToken,
36083
+ refreshToken: grant.bundle.refreshToken,
36084
+ expiresIn: expiresInSeconds(grant.bundle.accessTokenExpiresAt),
36085
+ ...repairConnectionId ? { repairConnectionId } : {}
36086
+ }
36087
+ },
36088
+ { signal }
36089
+ );
36090
+ output2.emit({
36091
+ type: "connection_authorized",
36092
+ connectionId: created.connectionId,
36093
+ connectorId: connector.id,
36094
+ serviceName: connector.name,
36095
+ connectionType: capability,
36096
+ state: "completed",
36097
+ terminal: false
36098
+ });
36099
+ return created.connectionId;
36100
+ }
36101
+ async function runLoopbackGrant({
36102
+ connector,
36103
+ capability,
36104
+ setup,
36105
+ registrationEndpoint,
36106
+ output: output2,
36107
+ openBrowser,
36108
+ signal
36109
+ }) {
36110
+ const retryHint = `Try again: ${connectViaCliCommand(connector.id, capability)}`;
36111
+ const provider = createDcrProvider({
36112
+ registrationUrl: registrationEndpoint,
36113
+ authorizeUrl: setup.authorizationEndpoint,
36114
+ tokenUrl: setup.tokenEndpoint,
36115
+ resource: setup.resource ?? void 0,
36116
+ clientMetadata: {
36117
+ clientName: AUTOMATIONS_CLI_CLIENT_NAME,
36118
+ logoUri: AUTOMATIONS_CLI_LOGO_URL,
36119
+ applicationType: "native",
36120
+ // The backend refreshes with the client id alone, so the client
36121
+ // must be public: no secret to copy across.
36122
+ tokenEndpointAuthMethod: "none",
36123
+ grantTypes: ["authorization_code", "refresh_token"]
36124
+ },
36125
+ // The grant is handed to the backend as-is; here the "account" only
36126
+ // carries the client id the server bound it to.
36127
+ validate: async ({ handshake }) => ({
36128
+ id: connector.id,
36129
+ label: connector.name,
36130
+ clientId: requireClientId(handshake)
36131
+ }),
36132
+ errorHints: [retryHint]
36133
+ });
36134
+ let captured;
36135
+ const store2 = {
36136
+ active: async () => null,
36137
+ set: async () => {
36138
+ },
36139
+ setBundle: async (account, bundle) => {
36140
+ captured = { account, bundle };
36141
+ },
36142
+ clear: async () => null,
36143
+ list: async () => [],
36144
+ setDefault: async () => {
36145
+ }
36146
+ };
36147
+ await runOAuthFlow({
36148
+ provider,
36149
+ store: store2,
36150
+ scopes: setup.scopes,
36151
+ readOnly: false,
36152
+ flags: {},
36153
+ preferredPort: PREFERRED_CALLBACK_PORT,
36154
+ renderSuccess: renderAuthSuccessPage,
36155
+ renderError: renderAuthErrorPage,
36156
+ ...openBrowser ? {} : { openBrowser: async () => {
36157
+ } },
36158
+ onAuthorizeUrl: (url2) => {
36159
+ output2.emit({
36160
+ type: "connection_authorization_started",
36161
+ connectorId: connector.id,
36162
+ serviceName: connector.name,
36163
+ connectionType: capability,
36164
+ state: "waiting_for_user",
36165
+ terminal: false,
36166
+ setupKind: "oauth",
36167
+ authorizationUrl: url2
36168
+ });
36169
+ },
36170
+ timeoutMs: CONNECTION_AUTHORIZATION_TIMEOUT_MS,
36171
+ signal
36172
+ });
36173
+ if (!captured) {
36174
+ throw new Error(`${connector.name} sign-in finished without a token. ${retryHint}`);
36175
+ }
36176
+ return captured;
36177
+ }
36178
+ function requireClientId(handshake) {
36179
+ const clientId = handshake.clientId;
36180
+ if (typeof clientId !== "string" || clientId.length === 0) {
36181
+ throw new Error("The authorization server did not return a client id.");
36182
+ }
36183
+ return clientId;
36184
+ }
36185
+ function expiresInSeconds(expiresAt) {
36186
+ if (expiresAt === void 0) return void 0;
36187
+ const seconds = Math.floor((expiresAt - Date.now()) / 1e3);
36188
+ return seconds > 0 ? seconds : void 0;
36189
+ }
36190
+
35934
36191
  // src/commands/connector/mutation-commands.ts
35935
36192
  function registerConnectorMutationCommands(connector) {
35936
36193
  connector.command("connect").description("Create a service connection and wait for authorization").argument("<connector-id>", "Connector ID").addOption(
35937
36194
  new Option4("--capability <capability>", "Capability to authorize").choices(["mcp", "trigger"]).makeOptionMandatory()
35938
36195
  ).action(async (connectorId, options, command) => {
35939
- await runAuthorizationCommand(command, async ({ api, authorizer, signal }) => {
36196
+ await runAuthorizationCommand(command, async (context) => {
36197
+ const { api, authorizer, signal } = context;
35940
36198
  const selected2 = await findConnector2(api, connectorId, signal);
35941
36199
  assertConnectorSupportsCapability(selected2, options.capability);
35942
36200
  if (!selected2.requiresConnection) {
35943
36201
  throw new Error(`${selected2.name} does not require a connection.`);
35944
36202
  }
36203
+ if (selected2.connectsViaCli) {
36204
+ const connectionId2 = await connectViaLocalOAuth({
36205
+ ...context,
36206
+ connector: selected2,
36207
+ capability: options.capability
36208
+ });
36209
+ return { action: "connected", connectionId: connectionId2 };
36210
+ }
35945
36211
  const connectionId = await authorizer.authorize(
35946
36212
  {
35947
36213
  connectorId: selected2.id,
@@ -35978,7 +36244,8 @@ function registerConnectorMutationCommands(connector) {
35978
36244
  });
35979
36245
  });
35980
36246
  connector.command("repair").description("Start a replacement setup for a broken or expired connection").argument("<connection-id>", "Connection ID").action(async (connectionId, _options, command) => {
35981
- await runAuthorizationCommand(command, async ({ api, authorizer, signal }) => {
36247
+ await runAuthorizationCommand(command, async (context) => {
36248
+ const { api, authorizer, signal } = context;
35982
36249
  const connection = await api.connections.get(connectionId, { signal });
35983
36250
  if (connection.status === "authorized") {
35984
36251
  throw new Error(`Connection ${connectionId} is already authorized.`);
@@ -35992,7 +36259,19 @@ function registerConnectorMutationCommands(connector) {
35992
36259
  await authorizer.resume(request2, connection.id, connection.setup, signal);
35993
36260
  return { action: "connected", connectionId };
35994
36261
  }
35995
- const affectedAutomations = await findAffectedAutomations(api, connectionId, signal);
36262
+ const [selected2, affectedAutomations] = await Promise.all([
36263
+ findListedConnector(api, connection.connectorId, signal),
36264
+ findAffectedAutomations(api, connectionId, signal)
36265
+ ]);
36266
+ if (selected2?.connectsViaCli) {
36267
+ const repairedConnectionId2 = await connectViaLocalOAuth({
36268
+ ...context,
36269
+ connector: selected2,
36270
+ capability: request2.connectionType,
36271
+ repairConnectionId: connection.id
36272
+ });
36273
+ return { action: "connected", connectionId: repairedConnectionId2 };
36274
+ }
35996
36275
  const repairedConnectionId = await authorizer.authorize(
35997
36276
  {
35998
36277
  ...request2,