@zapier/zapier-sdk-cli 0.62.0 → 0.63.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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @zapier/zapier-sdk-cli
2
2
 
3
+ ## 0.63.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d96b5f6: Added `--callback-url` to `zapier-sdk login` and `zapier-sdk signup` for resuming pending non-interactive OAuth flows. Non-interactive login and signup now save pending state and exit immediately; run the same command later with `--callback-url <url>` to complete authentication from the browser callback URL.
8
+
9
+ Login and signup telemetry now includes `used_non_interactive_mode` and `is_headless` on CLI command and auth lifecycle events.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [d96b5f6]
14
+ - @zapier/zapier-sdk@0.81.1
15
+ - @zapier/zapier-sdk-mcp@0.17.1
16
+
3
17
  ## 0.62.0
4
18
 
5
19
  ### Minor Changes
package/README.md CHANGED
@@ -209,11 +209,12 @@ Log in to Zapier to access your account
209
209
  | `--use-approvals` | `boolean` | ❌ | — | — | Require approvals for actions performed with these credentials |
210
210
  | `--non-interactive` | `boolean` | ❌ | — | — | Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable. |
211
211
  | `--headless` | `boolean` | ❌ | — | — | Use when logging in from a machine that has no browser. Prints a login link to open elsewhere, then accepts the pasted loopback callback URL. |
212
+ | `--callback-url` | `string` | ❌ | — | — | Resume a pending non-interactive login with the final OAuth callback URL from your browser. |
212
213
 
213
214
  **Usage:**
214
215
 
215
216
  ```bash
216
- npx zapier-sdk login [--name] [--timeout] [--use-approvals] [--non-interactive] [--headless]
217
+ npx zapier-sdk login [--name] [--timeout] [--use-approvals] [--non-interactive] [--headless] [--callback-url]
217
218
  ```
218
219
 
219
220
  #### `logout`
@@ -238,11 +239,12 @@ Set up Zapier account access and SDK credentials
238
239
  | `--use-approvals` | `boolean` | ❌ | — | — | Require approvals for actions performed with these credentials |
239
240
  | `--non-interactive` | `boolean` | ❌ | — | — | Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable. |
240
241
  | `--headless` | `boolean` | ❌ | — | — | Use when signing up from a machine that has no browser. Prints a signup link to open elsewhere, then accepts the pasted loopback callback URL. |
242
+ | `--callback-url` | `string` | ❌ | — | — | Resume a pending non-interactive signup with the final OAuth callback URL from your browser. |
241
243
 
242
244
  **Usage:**
243
245
 
244
246
  ```bash
245
- npx zapier-sdk signup [--timeout] [--use-approvals] [--non-interactive] [--headless]
247
+ npx zapier-sdk signup [--timeout] [--use-approvals] [--non-interactive] [--headless] [--callback-url]
246
248
  ```
247
249
 
248
250
  ### Actions
package/dist/cli.cjs CHANGED
@@ -1727,7 +1727,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
1727
1727
 
1728
1728
  // package.json
1729
1729
  var package_default = {
1730
- version: "0.62.0"};
1730
+ version: "0.63.0"};
1731
1731
 
1732
1732
  // src/telemetry/builders.ts
1733
1733
  function createCliBaseEvent(context = {}) {
@@ -1782,7 +1782,9 @@ function buildCliCommandExecutedEvent({
1782
1782
  files_created_count: data.files_created_count ?? null,
1783
1783
  files_processed_size_bytes: data.files_processed_size_bytes ?? null,
1784
1784
  cpu_time_ms: data.cpu_time_ms ?? null,
1785
- subprocess_count: data.subprocess_count ?? null
1785
+ subprocess_count: data.subprocess_count ?? null,
1786
+ used_non_interactive_mode: data.used_non_interactive_mode ?? null,
1787
+ is_headless: data.is_headless ?? null
1786
1788
  };
1787
1789
  }
1788
1790
  function getApprovalReason(error) {
@@ -2151,14 +2153,13 @@ function createInteractiveRenderer(context = {}) {
2151
2153
  };
2152
2154
  }
2153
2155
 
2154
- // src/utils/cli-generator.ts
2155
- var CLI_COMMAND_EXECUTED_EVENT_SUBJECT = "platform.sdk.CliCommandExecutedEvent";
2156
- var PAGINATION_PARAM_NAMES = /* @__PURE__ */ new Set(["maxItems", "pageSize", "cursor"]);
2156
+ // src/utils/cli-argument-sanitizer.ts
2157
2157
  var SENSITIVE_FLAGS = [
2158
2158
  "--credentials",
2159
2159
  "--credentials-client-secret",
2160
2160
  "--credentials-client-id",
2161
2161
  "--credentials-base-url",
2162
+ "--callback-url",
2162
2163
  "--user",
2163
2164
  "--header",
2164
2165
  "-H",
@@ -2184,6 +2185,15 @@ function sanitizeCliArguments(args) {
2184
2185
  }
2185
2186
  return sanitized;
2186
2187
  }
2188
+
2189
+ // src/utils/non-interactive.ts
2190
+ function resolveNonInteractive(options) {
2191
+ return options.nonInteractive === true || options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
2192
+ }
2193
+
2194
+ // src/utils/cli-generator.ts
2195
+ var CLI_COMMAND_EXECUTED_EVENT_SUBJECT = "platform.sdk.CliCommandExecutedEvent";
2196
+ var PAGINATION_PARAM_NAMES = /* @__PURE__ */ new Set(["maxItems", "pageSize", "cursor"]);
2187
2197
  function getNormalizedResult(result, { isListCommand }) {
2188
2198
  if (result instanceof Response) {
2189
2199
  return { kind: "response", value: result };
@@ -2312,8 +2322,24 @@ function resolveOutputMode({
2312
2322
  if (hasUserSpecifiedMaxItems) return "collect";
2313
2323
  return "paginate";
2314
2324
  }
2325
+ function getSchemaMetadata(schema) {
2326
+ return schema?.meta?.();
2327
+ }
2315
2328
  function getSchemaAliases(schema) {
2316
- return schema?.meta?.()?.aliases;
2329
+ return getSchemaMetadata(schema)?.aliases;
2330
+ }
2331
+ function getAuthFlowTelemetryMetadata(schema) {
2332
+ return getSchemaMetadata(schema)?.cliTelemetry?.authFlow;
2333
+ }
2334
+ function getAuthFlowIsHeadless({
2335
+ options,
2336
+ authFlowTelemetry
2337
+ }) {
2338
+ if (!authFlowTelemetry) return null;
2339
+ const isHeadless = options[authFlowTelemetry.headlessParam] === true;
2340
+ const isCallbackResume = options[authFlowTelemetry.callbackUrlParam] !== void 0;
2341
+ if (isCallbackResume && !isHeadless) return null;
2342
+ return isHeadless;
2317
2343
  }
2318
2344
  function analyzeZodSchema(schema, functionInfo) {
2319
2345
  const parameters = [];
@@ -2745,6 +2771,7 @@ ${confirmMessageAfter}`));
2745
2771
  }
2746
2772
  } finally {
2747
2773
  try {
2774
+ const authFlowTelemetry = getAuthFlowTelemetryMetadata(schema);
2748
2775
  const event = buildCliCommandExecutedEvent({
2749
2776
  data: {
2750
2777
  cli_primary_command: cliCommandName,
@@ -2754,7 +2781,15 @@ ${confirmMessageAfter}`));
2754
2781
  error_message: errorMessage,
2755
2782
  command_category: functionInfo.categories?.[0] ?? null,
2756
2783
  requires_auth: null,
2757
- cli_arguments: sanitizeCliArguments(process.argv.slice(2))
2784
+ cli_arguments: sanitizeCliArguments(process.argv.slice(2)),
2785
+ used_non_interactive_mode: authFlowTelemetry ? options[authFlowTelemetry.callbackUrlParam] !== void 0 || resolveNonInteractive({
2786
+ nonInteractive: options[authFlowTelemetry.nonInteractiveParam] === true,
2787
+ skipPrompts: authFlowTelemetry.skipPromptsParam !== void 0 && options[authFlowTelemetry.skipPromptsParam] === true
2788
+ }) : null,
2789
+ is_headless: getAuthFlowIsHeadless({
2790
+ options,
2791
+ authFlowTelemetry
2792
+ })
2758
2793
  },
2759
2794
  context: {
2760
2795
  selected_api: resolvedParams.app ?? null
@@ -3819,11 +3854,6 @@ async function resolveCredentialsBaseUrl(context) {
3819
3854
  return getBaseUrlFromResolvedCredentials(resolvedCredentials) ?? getBaseUrlFromOptionsCredentials(context.options?.credentials) ?? context.options?.baseUrl;
3820
3855
  }
3821
3856
 
3822
- // src/utils/non-interactive.ts
3823
- function resolveNonInteractive(options) {
3824
- return options.nonInteractive === true || options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
3825
- }
3826
-
3827
3857
  // src/utils/auth/client-credentials.ts
3828
3858
  var CREDENTIALS_SCOPES = ["external", "credentials"];
3829
3859
  var EMPTY_POLICY = {
@@ -4138,6 +4168,14 @@ var client_default = api;
4138
4168
 
4139
4169
  // src/utils/auth/oauth-transaction.ts
4140
4170
  var OAUTH_LOOPBACK_HOST = "localhost";
4171
+ var OauthTransactionSchema = zod.z.object({
4172
+ browserAuthUrl: zod.z.string(),
4173
+ clientId: zod.z.string(),
4174
+ codeVerifier: zod.z.string(),
4175
+ redirectUri: zod.z.string(),
4176
+ state: zod.z.string(),
4177
+ tokenUrl: zod.z.string()
4178
+ });
4141
4179
  function buildBrowserAuthUrl({
4142
4180
  authorizeUrl,
4143
4181
  entryPoint = "login"
@@ -4226,8 +4264,51 @@ async function exchangeOauthCode({
4226
4264
  expiresIn: data.expires_in
4227
4265
  };
4228
4266
  }
4267
+ var PENDING_OAUTH_TRANSACTION_KEY = "pending_oauth_transaction";
4268
+ var PendingOauthTransactionSchema = zod.z.object({
4269
+ version: zod.z.literal(1),
4270
+ entryPoint: zod.z.enum(["login", "signup"]),
4271
+ expiresAt: zod.z.number(),
4272
+ credentialsBaseUrl: zod.z.string().optional(),
4273
+ credentialName: zod.z.string().optional(),
4274
+ useApprovals: zod.z.boolean(),
4275
+ headless: zod.z.boolean().default(false),
4276
+ transaction: OauthTransactionSchema
4277
+ });
4278
+ function savePendingOauthTransaction({
4279
+ entryPoint,
4280
+ transaction,
4281
+ expiresAt,
4282
+ credentialsBaseUrl: credentialsBaseUrl2,
4283
+ credentialName,
4284
+ useApprovals,
4285
+ headless
4286
+ }) {
4287
+ const pendingTransaction = {
4288
+ version: 1,
4289
+ entryPoint,
4290
+ expiresAt,
4291
+ useApprovals,
4292
+ headless,
4293
+ transaction,
4294
+ ...credentialsBaseUrl2 !== void 0 && { credentialsBaseUrl: credentialsBaseUrl2 },
4295
+ ...credentialName !== void 0 && { credentialName }
4296
+ };
4297
+ getConfig().set(PENDING_OAUTH_TRANSACTION_KEY, pendingTransaction);
4298
+ return pendingTransaction;
4299
+ }
4300
+ function getPendingOauthTransaction() {
4301
+ const result = PendingOauthTransactionSchema.safeParse(
4302
+ getConfig().get(PENDING_OAUTH_TRANSACTION_KEY)
4303
+ );
4304
+ return result.success ? result.data : void 0;
4305
+ }
4306
+ function clearPendingOauthTransaction() {
4307
+ getConfig().delete(PENDING_OAUTH_TRANSACTION_KEY);
4308
+ }
4229
4309
 
4230
4310
  // src/utils/auth/oauth-flow.ts
4311
+ var PENDING_OAUTH_RECOVERY_MESSAGE = "Start a new non-interactive login or signup flow to generate a fresh URL.";
4231
4312
  var LOGIN_OAUTH_COPY = {
4232
4313
  flowName: "Login",
4233
4314
  action: "log in",
@@ -4283,6 +4364,95 @@ async function runSignupOauthFlow(options) {
4283
4364
  copy: SIGNUP_OAUTH_COPY
4284
4365
  });
4285
4366
  }
4367
+ async function startPendingOauthFlow({
4368
+ timeoutMs = LOGIN_TIMEOUT_MS,
4369
+ pkceCredentials,
4370
+ baseUrl: baseUrl2,
4371
+ entryPoint,
4372
+ credentialName,
4373
+ useApprovals,
4374
+ headless
4375
+ }) {
4376
+ const copy = entryPoint === "signup" ? SIGNUP_OAUTH_COPY : LOGIN_OAUTH_COPY;
4377
+ const port = LOGIN_PORTS[0];
4378
+ const transaction = await prepareOauthTransaction({
4379
+ pkceCredentials,
4380
+ baseUrl: baseUrl2,
4381
+ redirectUri: `http://${OAUTH_LOOPBACK_HOST}:${port}/oauth`,
4382
+ entryPoint
4383
+ });
4384
+ const pending = savePendingOauthTransaction({
4385
+ entryPoint,
4386
+ transaction,
4387
+ expiresAt: Date.now() + timeoutMs,
4388
+ credentialsBaseUrl: baseUrl2,
4389
+ credentialName,
4390
+ useApprovals,
4391
+ headless
4392
+ });
4393
+ process.stderr.write(
4394
+ `Open this ${copy.urlLabel} in a browser to continue:
4395
+ `
4396
+ );
4397
+ console.log(transaction.browserAuthUrl);
4398
+ if (!headless) {
4399
+ process.stderr.write(`Opening your browser to ${entryPoint}.
4400
+ `);
4401
+ try {
4402
+ await open__default.default(transaction.browserAuthUrl);
4403
+ } catch (error) {
4404
+ const reason = error instanceof Error ? error.message : String(error);
4405
+ process.stderr.write(
4406
+ `Browser did not open automatically to ${entryPoint}: ${reason}
4407
+ `
4408
+ );
4409
+ }
4410
+ }
4411
+ process.stderr.write(
4412
+ `After authorizing, finish with \`zapier-sdk ${entryPoint} --callback-url <final-url>\`.
4413
+ `
4414
+ );
4415
+ return pending;
4416
+ }
4417
+ function getPendingOauthFlow({
4418
+ entryPoint
4419
+ }) {
4420
+ const pending = getPendingOauthTransaction();
4421
+ if (!pending) {
4422
+ throw new ZapierCliValidationError(
4423
+ `No pending ${entryPoint} OAuth flow found. ${PENDING_OAUTH_RECOVERY_MESSAGE}`
4424
+ );
4425
+ }
4426
+ if (Date.now() > pending.expiresAt) {
4427
+ clearPendingOauthTransaction();
4428
+ throw new ZapierCliValidationError(
4429
+ `Pending ${pending.entryPoint} OAuth flow has expired. ${PENDING_OAUTH_RECOVERY_MESSAGE}`
4430
+ );
4431
+ }
4432
+ if (pending.entryPoint !== entryPoint) {
4433
+ throw new ZapierCliValidationError(
4434
+ `Pending OAuth flow is for ${pending.entryPoint}, not ${entryPoint}. ${PENDING_OAUTH_RECOVERY_MESSAGE}`
4435
+ );
4436
+ }
4437
+ return pending;
4438
+ }
4439
+ async function resumePendingOauthFlow({
4440
+ pending,
4441
+ callbackUrl,
4442
+ onProgress
4443
+ }) {
4444
+ const code = getCallbackCode({
4445
+ callbackUrl,
4446
+ transaction: pending.transaction
4447
+ });
4448
+ onProgress?.({ type: "callback_accepted" });
4449
+ process.stderr.write("Exchanging authorization code for tokens...\n");
4450
+ onProgress?.({ type: "token_exchange_started" });
4451
+ const tokens = await exchangeOauthCode({ ...pending.transaction, code });
4452
+ clearPendingOauthTransaction();
4453
+ onProgress?.({ type: "token_exchange_completed" });
4454
+ return tokens;
4455
+ }
4286
4456
  function runOauthFlowForEntryPoint({
4287
4457
  options,
4288
4458
  entryPoint,
@@ -4818,12 +4988,19 @@ async function saveClientCredentials({
4818
4988
  function emitAccountAuthSuccess({
4819
4989
  sdk,
4820
4990
  profile,
4821
- clientId
4991
+ clientId,
4992
+ isNonInteractive,
4993
+ isHeadless
4822
4994
  }) {
4823
4995
  sdk.context.eventEmission.emit(
4824
4996
  "platform.sdk.ApplicationLifecycleEvent",
4825
4997
  zapierSdk.buildApplicationLifecycleEvent(
4826
- { lifecycle_event_type: "login_success" },
4998
+ {
4999
+ lifecycle_event_type: "login_success",
5000
+ used_non_interactive_mode: isNonInteractive,
5001
+ is_headless: isHeadless,
5002
+ process_argv: sanitizeCliArguments(process.argv.slice(2))
5003
+ },
4827
5004
  {
4828
5005
  customuser_id: profile.user_id,
4829
5006
  account_id: profile.roles[0]?.account_id ?? null,
@@ -4834,11 +5011,18 @@ function emitAccountAuthSuccess({
4834
5011
  );
4835
5012
  }
4836
5013
  function emitSignupSuccess({
4837
- sdk
5014
+ sdk,
5015
+ isNonInteractive,
5016
+ isHeadless
4838
5017
  }) {
4839
5018
  sdk.context.eventEmission.emit(
4840
5019
  "platform.sdk.ApplicationLifecycleEvent",
4841
- zapierSdk.buildApplicationLifecycleEvent({ lifecycle_event_type: "signup_success" })
5020
+ zapierSdk.buildApplicationLifecycleEvent({
5021
+ lifecycle_event_type: "signup_success",
5022
+ used_non_interactive_mode: isNonInteractive,
5023
+ is_headless: isHeadless,
5024
+ process_argv: sanitizeCliArguments(process.argv.slice(2))
5025
+ })
4842
5026
  );
4843
5027
  }
4844
5028
  async function runOauthWithRedaction(runOauth) {
@@ -4869,7 +5053,11 @@ async function runOauthForEntryPoint({
4869
5053
  recoveryMessage: headless ? HEADLESS_SIGNUP_RECOVERY_MESSAGE : SIGNUP_RECOVERY_MESSAGE,
4870
5054
  onProgress: (event) => {
4871
5055
  if (event.type === "callback_accepted") {
4872
- emitSignupSuccess({ sdk });
5056
+ emitSignupSuccess({
5057
+ sdk,
5058
+ isNonInteractive: false,
5059
+ isHeadless: headless === true
5060
+ });
4873
5061
  }
4874
5062
  }
4875
5063
  })
@@ -4886,11 +5074,124 @@ async function runOauthForEntryPoint({
4886
5074
  })
4887
5075
  );
4888
5076
  }
5077
+ async function provisionAccountCredentials({
5078
+ sdk,
5079
+ entryPoint,
5080
+ accessToken,
5081
+ credentialsBaseUrl: credentialsBaseUrl2,
5082
+ credentialName,
5083
+ interactive,
5084
+ useApprovals,
5085
+ isNonInteractive,
5086
+ isHeadless
5087
+ }) {
5088
+ const scopedApi = zapierSdk.getOrCreateApiClient({
5089
+ credentials: accessToken,
5090
+ baseUrl: credentialsBaseUrl2,
5091
+ callerPackage: sdk.context.options?.callerPackage
5092
+ });
5093
+ const profile = await getProfile(scopedApi);
5094
+ process.stderr.write(`${getProfileMessage(entryPoint, profile.email)}
5095
+ `);
5096
+ process.stderr.write(
5097
+ "\nGenerating credentials so this machine can make authenticated requests on your behalf.\n"
5098
+ );
5099
+ const resolvedCredentialName = credentialName ?? await resolveCredentialName({
5100
+ email: profile.email,
5101
+ interactive,
5102
+ baseUrl: credentialsBaseUrl2,
5103
+ entryPoint
5104
+ });
5105
+ const { clientId } = await saveClientCredentials({
5106
+ api: scopedApi,
5107
+ name: resolvedCredentialName,
5108
+ credentialsBaseUrl: credentialsBaseUrl2,
5109
+ useApprovals,
5110
+ cleanupLogPrefix: entryPoint
5111
+ });
5112
+ process.stderr.write(
5113
+ `\u2705 Credentials "${resolvedCredentialName}" created and set as default. You are ready to use the Zapier SDK.
5114
+ `
5115
+ );
5116
+ if (useApprovals) {
5117
+ process.stderr.write("\u{1F510} Approvals are enabled for these credentials.\n");
5118
+ }
5119
+ emitAccountAuthSuccess({
5120
+ sdk,
5121
+ profile,
5122
+ clientId,
5123
+ isNonInteractive,
5124
+ isHeadless
5125
+ });
5126
+ }
4889
5127
  async function runAccountAuth({
4890
5128
  sdk,
4891
5129
  options,
4892
5130
  entryPoint
4893
5131
  }) {
5132
+ if (options.callbackUrl !== void 0) {
5133
+ const { callbackUrl } = options;
5134
+ const pending = getPendingOauthFlow({ entryPoint });
5135
+ const finishName = options.name !== void 0 ? validateCredentialsName(options.name) : void 0;
5136
+ if (finishName !== void 0 && finishName !== pending.credentialName) {
5137
+ throw new ZapierCliValidationError(
5138
+ "Cannot change --name while completing a pending OAuth flow. Start a new non-interactive login with the desired --name."
5139
+ );
5140
+ }
5141
+ if (options.useApprovals === true && !pending.useApprovals) {
5142
+ throw new ZapierCliValidationError(
5143
+ "Cannot add --use-approvals while completing a pending OAuth flow. Start a new non-interactive flow with --use-approvals."
5144
+ );
5145
+ }
5146
+ if (pending.credentialName !== void 0) {
5147
+ const activeCredentials = getActiveCredentials({
5148
+ baseUrl: pending.credentialsBaseUrl
5149
+ });
5150
+ if (activeCredentials?.name !== pending.credentialName && credentialNameExists({
5151
+ name: pending.credentialName,
5152
+ baseUrl: pending.credentialsBaseUrl
5153
+ })) {
5154
+ throw new ZapierCliValidationError(
5155
+ `A credential named "${pending.credentialName}" already exists. Choose a different --name.`
5156
+ );
5157
+ }
5158
+ }
5159
+ if (!await clearExistingAuthState({
5160
+ sdk,
5161
+ baseUrl: pending.credentialsBaseUrl,
5162
+ interactive: false,
5163
+ entryPoint
5164
+ })) {
5165
+ return;
5166
+ }
5167
+ const { accessToken: accessToken2 } = await runOauthWithRedaction(async () => {
5168
+ return resumePendingOauthFlow({
5169
+ callbackUrl,
5170
+ pending,
5171
+ onProgress: (event) => {
5172
+ if (entryPoint === "signup" && event.type === "callback_accepted") {
5173
+ emitSignupSuccess({
5174
+ sdk,
5175
+ isNonInteractive: true,
5176
+ isHeadless: pending.headless
5177
+ });
5178
+ }
5179
+ }
5180
+ });
5181
+ });
5182
+ await provisionAccountCredentials({
5183
+ sdk,
5184
+ entryPoint,
5185
+ accessToken: accessToken2,
5186
+ credentialsBaseUrl: pending.credentialsBaseUrl,
5187
+ credentialName: pending.credentialName,
5188
+ interactive: false,
5189
+ useApprovals: pending.useApprovals,
5190
+ isNonInteractive: true,
5191
+ isHeadless: pending.headless
5192
+ });
5193
+ return;
5194
+ }
4894
5195
  const timeoutSeconds = parseTimeoutSeconds(options.timeout);
4895
5196
  const interactive = !resolveNonInteractive(options);
4896
5197
  const resolvedCredentials = await sdk.context.resolveCredentials();
@@ -4919,6 +5220,19 @@ async function runAccountAuth({
4919
5220
  })) {
4920
5221
  return;
4921
5222
  }
5223
+ const useApprovals = options.useApprovals === true;
5224
+ if (!interactive) {
5225
+ await startPendingOauthFlow({
5226
+ entryPoint,
5227
+ timeoutMs: timeoutSeconds * 1e3,
5228
+ pkceCredentials,
5229
+ baseUrl: credentialsBaseUrl2,
5230
+ credentialName: providedName,
5231
+ useApprovals,
5232
+ headless
5233
+ });
5234
+ return;
5235
+ }
4922
5236
  const { accessToken } = await runOauthForEntryPoint({
4923
5237
  sdk,
4924
5238
  entryPoint,
@@ -4928,39 +5242,17 @@ async function runAccountAuth({
4928
5242
  headless,
4929
5243
  interactive
4930
5244
  });
4931
- const scopedApi = zapierSdk.getOrCreateApiClient({
4932
- credentials: accessToken,
4933
- baseUrl: credentialsBaseUrl2,
4934
- callerPackage: sdk.context.options?.callerPackage
4935
- });
4936
- const profile = await getProfile(scopedApi);
4937
- process.stderr.write(`${getProfileMessage(entryPoint, profile.email)}
4938
- `);
4939
- process.stderr.write(
4940
- "\nGenerating credentials so this machine can make authenticated requests on your behalf.\n"
4941
- );
4942
- const credentialName = providedName ?? await resolveCredentialName({
4943
- email: profile.email,
4944
- interactive,
4945
- baseUrl: credentialsBaseUrl2,
4946
- entryPoint
4947
- });
4948
- const useApprovals = options.useApprovals === true;
4949
- const { clientId } = await saveClientCredentials({
4950
- api: scopedApi,
4951
- name: credentialName,
5245
+ await provisionAccountCredentials({
5246
+ sdk,
5247
+ entryPoint,
5248
+ accessToken,
4952
5249
  credentialsBaseUrl: credentialsBaseUrl2,
5250
+ credentialName: providedName,
5251
+ interactive,
4953
5252
  useApprovals,
4954
- cleanupLogPrefix: entryPoint
5253
+ isNonInteractive: false,
5254
+ isHeadless: headless
4955
5255
  });
4956
- process.stderr.write(
4957
- `\u2705 Credentials "${credentialName}" created and set as default. You are ready to use the Zapier SDK.
4958
- `
4959
- );
4960
- if (useApprovals) {
4961
- process.stderr.write("\u{1F510} Approvals are enabled for these credentials.\n");
4962
- }
4963
- emitAccountAuthSuccess({ sdk, profile, clientId });
4964
5256
  }
4965
5257
  var LoginSchema = zod.z.object({
4966
5258
  name: zod.z.string().optional().describe(
@@ -4980,8 +5272,20 @@ var LoginSchema = zod.z.object({
4980
5272
  }),
4981
5273
  headless: zod.z.boolean().optional().describe(
4982
5274
  "Use when logging in from a machine that has no browser. Prints a login link to open elsewhere, then accepts the pasted loopback callback URL."
5275
+ ),
5276
+ callbackUrl: zod.z.string().optional().describe(
5277
+ "Resume a pending non-interactive login with the final OAuth callback URL from your browser."
4983
5278
  )
4984
- }).describe("Log in to Zapier to access your account");
5279
+ }).describe("Log in to Zapier to access your account").meta({
5280
+ cliTelemetry: {
5281
+ authFlow: {
5282
+ callbackUrlParam: "callbackUrl",
5283
+ headlessParam: "headless",
5284
+ nonInteractiveParam: "nonInteractive",
5285
+ skipPromptsParam: "skipPrompts"
5286
+ }
5287
+ }
5288
+ });
4985
5289
 
4986
5290
  // src/plugins/login/index.ts
4987
5291
  var loginPlugin = zapierSdk.definePlugin(
@@ -5010,8 +5314,20 @@ var SignupSchema = zod.z.object({
5010
5314
  }),
5011
5315
  headless: zod.z.boolean().optional().describe(
5012
5316
  "Use when signing up from a machine that has no browser. Prints a signup link to open elsewhere, then accepts the pasted loopback callback URL."
5317
+ ),
5318
+ callbackUrl: zod.z.string().optional().describe(
5319
+ "Resume a pending non-interactive signup with the final OAuth callback URL from your browser."
5013
5320
  )
5014
- }).describe("Set up Zapier account access and SDK credentials");
5321
+ }).describe("Set up Zapier account access and SDK credentials").meta({
5322
+ cliTelemetry: {
5323
+ authFlow: {
5324
+ callbackUrlParam: "callbackUrl",
5325
+ headlessParam: "headless",
5326
+ nonInteractiveParam: "nonInteractive",
5327
+ skipPromptsParam: "skipPrompts"
5328
+ }
5329
+ }
5330
+ });
5015
5331
 
5016
5332
  // src/plugins/signup/index.ts
5017
5333
  var signupPlugin = zapierSdk.definePlugin(
@@ -7612,7 +7928,7 @@ function buildBoxLines(message) {
7612
7928
  // package.json with { type: 'json' }
7613
7929
  var package_default2 = {
7614
7930
  name: "@zapier/zapier-sdk-cli",
7615
- version: "0.62.0"};
7931
+ version: "0.63.0"};
7616
7932
 
7617
7933
  // src/sdk.ts
7618
7934
  zapierSdk.injectCliLogin(login_exports);