@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/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command, CommanderError, Option } from 'commander';
3
3
  import { z } from 'zod';
4
- import { definePlugin, createPluginMethod, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, ZapierReleaseTriggerMessageSignal, injectCliLogin, BaseSdkOptionsSchema, getOrCreateApiClient, isPermanentHttpError, invalidateCachedToken, batch, toSnakeCase, ZapierAbortDrainSignal, createZapierSdkStack as createZapierSdkStack$1, createSdk as createSdk$1, defineLegacyMerge as defineLegacyMerge$1, zapierSdkPlugin as zapierSdkPlugin$1, addPlugin as addPlugin$1, ZapierError, isCredentialsObject, buildApplicationLifecycleEvent, AuthMechanism, ZapierAuthenticationError, DEPRECATION_NOTICE_EVENT, runWithCallerContext, isPositional, createController, CoreCancelledSignal, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId, ZapierApprovalError } from '@zapier/zapier-sdk';
4
+ import { definePlugin, createPluginMethod, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, ZapierReleaseTriggerMessageSignal, injectCliLogin, BaseSdkOptionsSchema, isPermanentHttpError, invalidateCachedToken, batch, toSnakeCase, ZapierAbortDrainSignal, createZapierSdkStack as createZapierSdkStack$1, createSdk as createSdk$1, defineLegacyMerge as defineLegacyMerge$1, zapierSdkPlugin as zapierSdkPlugin$1, addPlugin as addPlugin$1, ZapierError, getOrCreateApiClient, isCredentialsObject, ZapierAuthenticationError, buildApplicationLifecycleEvent, AuthMechanism, DEPRECATION_NOTICE_EVENT, runWithCallerContext, isPositional, createController, CoreCancelledSignal, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId, ZapierApprovalError } from '@zapier/zapier-sdk';
5
5
  import inquirer from 'inquirer';
6
6
  import search from '@inquirer/search';
7
7
  import chalk from 'chalk';
@@ -9,7 +9,7 @@ import ora from 'ora';
9
9
  import util from 'util';
10
10
  import wrapAnsi from 'wrap-ansi';
11
11
  import * as jwt from 'jsonwebtoken';
12
- import { deletePassword, setPassword, getKeyring, getPassword } from 'cross-keychain';
12
+ import { deletePassword, getKeyring, setPassword, getPassword } from 'cross-keychain';
13
13
  import Conf from 'conf';
14
14
  import * as fs from 'fs';
15
15
  import { promises, createWriteStream, existsSync, readdirSync, rmSync, mkdirSync, writeFileSync, copyFileSync, readFileSync } from 'fs';
@@ -1684,7 +1684,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
1684
1684
 
1685
1685
  // package.json
1686
1686
  var package_default = {
1687
- version: "0.62.0"};
1687
+ version: "0.63.0"};
1688
1688
 
1689
1689
  // src/telemetry/builders.ts
1690
1690
  function createCliBaseEvent(context = {}) {
@@ -1739,7 +1739,9 @@ function buildCliCommandExecutedEvent({
1739
1739
  files_created_count: data.files_created_count ?? null,
1740
1740
  files_processed_size_bytes: data.files_processed_size_bytes ?? null,
1741
1741
  cpu_time_ms: data.cpu_time_ms ?? null,
1742
- subprocess_count: data.subprocess_count ?? null
1742
+ subprocess_count: data.subprocess_count ?? null,
1743
+ used_non_interactive_mode: data.used_non_interactive_mode ?? null,
1744
+ is_headless: data.is_headless ?? null
1743
1745
  };
1744
1746
  }
1745
1747
  function getApprovalReason(error) {
@@ -2108,14 +2110,13 @@ function createInteractiveRenderer(context = {}) {
2108
2110
  };
2109
2111
  }
2110
2112
 
2111
- // src/utils/cli-generator.ts
2112
- var CLI_COMMAND_EXECUTED_EVENT_SUBJECT = "platform.sdk.CliCommandExecutedEvent";
2113
- var PAGINATION_PARAM_NAMES = /* @__PURE__ */ new Set(["maxItems", "pageSize", "cursor"]);
2113
+ // src/utils/cli-argument-sanitizer.ts
2114
2114
  var SENSITIVE_FLAGS = [
2115
2115
  "--credentials",
2116
2116
  "--credentials-client-secret",
2117
2117
  "--credentials-client-id",
2118
2118
  "--credentials-base-url",
2119
+ "--callback-url",
2119
2120
  "--user",
2120
2121
  "--header",
2121
2122
  "-H",
@@ -2141,6 +2142,15 @@ function sanitizeCliArguments(args) {
2141
2142
  }
2142
2143
  return sanitized;
2143
2144
  }
2145
+
2146
+ // src/utils/non-interactive.ts
2147
+ function resolveNonInteractive(options) {
2148
+ return options.nonInteractive === true || options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
2149
+ }
2150
+
2151
+ // src/utils/cli-generator.ts
2152
+ var CLI_COMMAND_EXECUTED_EVENT_SUBJECT = "platform.sdk.CliCommandExecutedEvent";
2153
+ var PAGINATION_PARAM_NAMES = /* @__PURE__ */ new Set(["maxItems", "pageSize", "cursor"]);
2144
2154
  function getNormalizedResult(result, { isListCommand }) {
2145
2155
  if (result instanceof Response) {
2146
2156
  return { kind: "response", value: result };
@@ -2269,8 +2279,24 @@ function resolveOutputMode({
2269
2279
  if (hasUserSpecifiedMaxItems) return "collect";
2270
2280
  return "paginate";
2271
2281
  }
2282
+ function getSchemaMetadata(schema) {
2283
+ return schema?.meta?.();
2284
+ }
2272
2285
  function getSchemaAliases(schema) {
2273
- return schema?.meta?.()?.aliases;
2286
+ return getSchemaMetadata(schema)?.aliases;
2287
+ }
2288
+ function getAuthFlowTelemetryMetadata(schema) {
2289
+ return getSchemaMetadata(schema)?.cliTelemetry?.authFlow;
2290
+ }
2291
+ function getAuthFlowIsHeadless({
2292
+ options,
2293
+ authFlowTelemetry
2294
+ }) {
2295
+ if (!authFlowTelemetry) return null;
2296
+ const isHeadless = options[authFlowTelemetry.headlessParam] === true;
2297
+ const isCallbackResume = options[authFlowTelemetry.callbackUrlParam] !== void 0;
2298
+ if (isCallbackResume && !isHeadless) return null;
2299
+ return isHeadless;
2274
2300
  }
2275
2301
  function analyzeZodSchema(schema, functionInfo) {
2276
2302
  const parameters = [];
@@ -2702,6 +2728,7 @@ ${confirmMessageAfter}`));
2702
2728
  }
2703
2729
  } finally {
2704
2730
  try {
2731
+ const authFlowTelemetry = getAuthFlowTelemetryMetadata(schema);
2705
2732
  const event = buildCliCommandExecutedEvent({
2706
2733
  data: {
2707
2734
  cli_primary_command: cliCommandName,
@@ -2711,7 +2738,15 @@ ${confirmMessageAfter}`));
2711
2738
  error_message: errorMessage,
2712
2739
  command_category: functionInfo.categories?.[0] ?? null,
2713
2740
  requires_auth: null,
2714
- cli_arguments: sanitizeCliArguments(process.argv.slice(2))
2741
+ cli_arguments: sanitizeCliArguments(process.argv.slice(2)),
2742
+ used_non_interactive_mode: authFlowTelemetry ? options[authFlowTelemetry.callbackUrlParam] !== void 0 || resolveNonInteractive({
2743
+ nonInteractive: options[authFlowTelemetry.nonInteractiveParam] === true,
2744
+ skipPrompts: authFlowTelemetry.skipPromptsParam !== void 0 && options[authFlowTelemetry.skipPromptsParam] === true
2745
+ }) : null,
2746
+ is_headless: getAuthFlowIsHeadless({
2747
+ options,
2748
+ authFlowTelemetry
2749
+ })
2715
2750
  },
2716
2751
  context: {
2717
2752
  selected_api: resolvedParams.app ?? null
@@ -3776,11 +3811,6 @@ async function resolveCredentialsBaseUrl(context) {
3776
3811
  return getBaseUrlFromResolvedCredentials(resolvedCredentials) ?? getBaseUrlFromOptionsCredentials(context.options?.credentials) ?? context.options?.baseUrl;
3777
3812
  }
3778
3813
 
3779
- // src/utils/non-interactive.ts
3780
- function resolveNonInteractive(options) {
3781
- return options.nonInteractive === true || options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
3782
- }
3783
-
3784
3814
  // src/utils/auth/client-credentials.ts
3785
3815
  var CREDENTIALS_SCOPES = ["external", "credentials"];
3786
3816
  var EMPTY_POLICY = {
@@ -4095,6 +4125,14 @@ var client_default = api;
4095
4125
 
4096
4126
  // src/utils/auth/oauth-transaction.ts
4097
4127
  var OAUTH_LOOPBACK_HOST = "localhost";
4128
+ var OauthTransactionSchema = z.object({
4129
+ browserAuthUrl: z.string(),
4130
+ clientId: z.string(),
4131
+ codeVerifier: z.string(),
4132
+ redirectUri: z.string(),
4133
+ state: z.string(),
4134
+ tokenUrl: z.string()
4135
+ });
4098
4136
  function buildBrowserAuthUrl({
4099
4137
  authorizeUrl,
4100
4138
  entryPoint = "login"
@@ -4183,8 +4221,51 @@ async function exchangeOauthCode({
4183
4221
  expiresIn: data.expires_in
4184
4222
  };
4185
4223
  }
4224
+ var PENDING_OAUTH_TRANSACTION_KEY = "pending_oauth_transaction";
4225
+ var PendingOauthTransactionSchema = z.object({
4226
+ version: z.literal(1),
4227
+ entryPoint: z.enum(["login", "signup"]),
4228
+ expiresAt: z.number(),
4229
+ credentialsBaseUrl: z.string().optional(),
4230
+ credentialName: z.string().optional(),
4231
+ useApprovals: z.boolean(),
4232
+ headless: z.boolean().default(false),
4233
+ transaction: OauthTransactionSchema
4234
+ });
4235
+ function savePendingOauthTransaction({
4236
+ entryPoint,
4237
+ transaction,
4238
+ expiresAt,
4239
+ credentialsBaseUrl: credentialsBaseUrl2,
4240
+ credentialName,
4241
+ useApprovals,
4242
+ headless
4243
+ }) {
4244
+ const pendingTransaction = {
4245
+ version: 1,
4246
+ entryPoint,
4247
+ expiresAt,
4248
+ useApprovals,
4249
+ headless,
4250
+ transaction,
4251
+ ...credentialsBaseUrl2 !== void 0 && { credentialsBaseUrl: credentialsBaseUrl2 },
4252
+ ...credentialName !== void 0 && { credentialName }
4253
+ };
4254
+ getConfig().set(PENDING_OAUTH_TRANSACTION_KEY, pendingTransaction);
4255
+ return pendingTransaction;
4256
+ }
4257
+ function getPendingOauthTransaction() {
4258
+ const result = PendingOauthTransactionSchema.safeParse(
4259
+ getConfig().get(PENDING_OAUTH_TRANSACTION_KEY)
4260
+ );
4261
+ return result.success ? result.data : void 0;
4262
+ }
4263
+ function clearPendingOauthTransaction() {
4264
+ getConfig().delete(PENDING_OAUTH_TRANSACTION_KEY);
4265
+ }
4186
4266
 
4187
4267
  // src/utils/auth/oauth-flow.ts
4268
+ var PENDING_OAUTH_RECOVERY_MESSAGE = "Start a new non-interactive login or signup flow to generate a fresh URL.";
4188
4269
  var LOGIN_OAUTH_COPY = {
4189
4270
  flowName: "Login",
4190
4271
  action: "log in",
@@ -4240,6 +4321,95 @@ async function runSignupOauthFlow(options) {
4240
4321
  copy: SIGNUP_OAUTH_COPY
4241
4322
  });
4242
4323
  }
4324
+ async function startPendingOauthFlow({
4325
+ timeoutMs = LOGIN_TIMEOUT_MS,
4326
+ pkceCredentials,
4327
+ baseUrl: baseUrl2,
4328
+ entryPoint,
4329
+ credentialName,
4330
+ useApprovals,
4331
+ headless
4332
+ }) {
4333
+ const copy = entryPoint === "signup" ? SIGNUP_OAUTH_COPY : LOGIN_OAUTH_COPY;
4334
+ const port = LOGIN_PORTS[0];
4335
+ const transaction = await prepareOauthTransaction({
4336
+ pkceCredentials,
4337
+ baseUrl: baseUrl2,
4338
+ redirectUri: `http://${OAUTH_LOOPBACK_HOST}:${port}/oauth`,
4339
+ entryPoint
4340
+ });
4341
+ const pending = savePendingOauthTransaction({
4342
+ entryPoint,
4343
+ transaction,
4344
+ expiresAt: Date.now() + timeoutMs,
4345
+ credentialsBaseUrl: baseUrl2,
4346
+ credentialName,
4347
+ useApprovals,
4348
+ headless
4349
+ });
4350
+ process.stderr.write(
4351
+ `Open this ${copy.urlLabel} in a browser to continue:
4352
+ `
4353
+ );
4354
+ console.log(transaction.browserAuthUrl);
4355
+ if (!headless) {
4356
+ process.stderr.write(`Opening your browser to ${entryPoint}.
4357
+ `);
4358
+ try {
4359
+ await open(transaction.browserAuthUrl);
4360
+ } catch (error) {
4361
+ const reason = error instanceof Error ? error.message : String(error);
4362
+ process.stderr.write(
4363
+ `Browser did not open automatically to ${entryPoint}: ${reason}
4364
+ `
4365
+ );
4366
+ }
4367
+ }
4368
+ process.stderr.write(
4369
+ `After authorizing, finish with \`zapier-sdk ${entryPoint} --callback-url <final-url>\`.
4370
+ `
4371
+ );
4372
+ return pending;
4373
+ }
4374
+ function getPendingOauthFlow({
4375
+ entryPoint
4376
+ }) {
4377
+ const pending = getPendingOauthTransaction();
4378
+ if (!pending) {
4379
+ throw new ZapierCliValidationError(
4380
+ `No pending ${entryPoint} OAuth flow found. ${PENDING_OAUTH_RECOVERY_MESSAGE}`
4381
+ );
4382
+ }
4383
+ if (Date.now() > pending.expiresAt) {
4384
+ clearPendingOauthTransaction();
4385
+ throw new ZapierCliValidationError(
4386
+ `Pending ${pending.entryPoint} OAuth flow has expired. ${PENDING_OAUTH_RECOVERY_MESSAGE}`
4387
+ );
4388
+ }
4389
+ if (pending.entryPoint !== entryPoint) {
4390
+ throw new ZapierCliValidationError(
4391
+ `Pending OAuth flow is for ${pending.entryPoint}, not ${entryPoint}. ${PENDING_OAUTH_RECOVERY_MESSAGE}`
4392
+ );
4393
+ }
4394
+ return pending;
4395
+ }
4396
+ async function resumePendingOauthFlow({
4397
+ pending,
4398
+ callbackUrl,
4399
+ onProgress
4400
+ }) {
4401
+ const code = getCallbackCode({
4402
+ callbackUrl,
4403
+ transaction: pending.transaction
4404
+ });
4405
+ onProgress?.({ type: "callback_accepted" });
4406
+ process.stderr.write("Exchanging authorization code for tokens...\n");
4407
+ onProgress?.({ type: "token_exchange_started" });
4408
+ const tokens = await exchangeOauthCode({ ...pending.transaction, code });
4409
+ clearPendingOauthTransaction();
4410
+ onProgress?.({ type: "token_exchange_completed" });
4411
+ return tokens;
4412
+ }
4243
4413
  function runOauthFlowForEntryPoint({
4244
4414
  options,
4245
4415
  entryPoint,
@@ -4775,12 +4945,19 @@ async function saveClientCredentials({
4775
4945
  function emitAccountAuthSuccess({
4776
4946
  sdk,
4777
4947
  profile,
4778
- clientId
4948
+ clientId,
4949
+ isNonInteractive,
4950
+ isHeadless
4779
4951
  }) {
4780
4952
  sdk.context.eventEmission.emit(
4781
4953
  "platform.sdk.ApplicationLifecycleEvent",
4782
4954
  buildApplicationLifecycleEvent(
4783
- { lifecycle_event_type: "login_success" },
4955
+ {
4956
+ lifecycle_event_type: "login_success",
4957
+ used_non_interactive_mode: isNonInteractive,
4958
+ is_headless: isHeadless,
4959
+ process_argv: sanitizeCliArguments(process.argv.slice(2))
4960
+ },
4784
4961
  {
4785
4962
  customuser_id: profile.user_id,
4786
4963
  account_id: profile.roles[0]?.account_id ?? null,
@@ -4791,11 +4968,18 @@ function emitAccountAuthSuccess({
4791
4968
  );
4792
4969
  }
4793
4970
  function emitSignupSuccess({
4794
- sdk
4971
+ sdk,
4972
+ isNonInteractive,
4973
+ isHeadless
4795
4974
  }) {
4796
4975
  sdk.context.eventEmission.emit(
4797
4976
  "platform.sdk.ApplicationLifecycleEvent",
4798
- buildApplicationLifecycleEvent({ lifecycle_event_type: "signup_success" })
4977
+ buildApplicationLifecycleEvent({
4978
+ lifecycle_event_type: "signup_success",
4979
+ used_non_interactive_mode: isNonInteractive,
4980
+ is_headless: isHeadless,
4981
+ process_argv: sanitizeCliArguments(process.argv.slice(2))
4982
+ })
4799
4983
  );
4800
4984
  }
4801
4985
  async function runOauthWithRedaction(runOauth) {
@@ -4826,7 +5010,11 @@ async function runOauthForEntryPoint({
4826
5010
  recoveryMessage: headless ? HEADLESS_SIGNUP_RECOVERY_MESSAGE : SIGNUP_RECOVERY_MESSAGE,
4827
5011
  onProgress: (event) => {
4828
5012
  if (event.type === "callback_accepted") {
4829
- emitSignupSuccess({ sdk });
5013
+ emitSignupSuccess({
5014
+ sdk,
5015
+ isNonInteractive: false,
5016
+ isHeadless: headless === true
5017
+ });
4830
5018
  }
4831
5019
  }
4832
5020
  })
@@ -4843,11 +5031,124 @@ async function runOauthForEntryPoint({
4843
5031
  })
4844
5032
  );
4845
5033
  }
5034
+ async function provisionAccountCredentials({
5035
+ sdk,
5036
+ entryPoint,
5037
+ accessToken,
5038
+ credentialsBaseUrl: credentialsBaseUrl2,
5039
+ credentialName,
5040
+ interactive,
5041
+ useApprovals,
5042
+ isNonInteractive,
5043
+ isHeadless
5044
+ }) {
5045
+ const scopedApi = getOrCreateApiClient({
5046
+ credentials: accessToken,
5047
+ baseUrl: credentialsBaseUrl2,
5048
+ callerPackage: sdk.context.options?.callerPackage
5049
+ });
5050
+ const profile = await getProfile(scopedApi);
5051
+ process.stderr.write(`${getProfileMessage(entryPoint, profile.email)}
5052
+ `);
5053
+ process.stderr.write(
5054
+ "\nGenerating credentials so this machine can make authenticated requests on your behalf.\n"
5055
+ );
5056
+ const resolvedCredentialName = credentialName ?? await resolveCredentialName({
5057
+ email: profile.email,
5058
+ interactive,
5059
+ baseUrl: credentialsBaseUrl2,
5060
+ entryPoint
5061
+ });
5062
+ const { clientId } = await saveClientCredentials({
5063
+ api: scopedApi,
5064
+ name: resolvedCredentialName,
5065
+ credentialsBaseUrl: credentialsBaseUrl2,
5066
+ useApprovals,
5067
+ cleanupLogPrefix: entryPoint
5068
+ });
5069
+ process.stderr.write(
5070
+ `\u2705 Credentials "${resolvedCredentialName}" created and set as default. You are ready to use the Zapier SDK.
5071
+ `
5072
+ );
5073
+ if (useApprovals) {
5074
+ process.stderr.write("\u{1F510} Approvals are enabled for these credentials.\n");
5075
+ }
5076
+ emitAccountAuthSuccess({
5077
+ sdk,
5078
+ profile,
5079
+ clientId,
5080
+ isNonInteractive,
5081
+ isHeadless
5082
+ });
5083
+ }
4846
5084
  async function runAccountAuth({
4847
5085
  sdk,
4848
5086
  options,
4849
5087
  entryPoint
4850
5088
  }) {
5089
+ if (options.callbackUrl !== void 0) {
5090
+ const { callbackUrl } = options;
5091
+ const pending = getPendingOauthFlow({ entryPoint });
5092
+ const finishName = options.name !== void 0 ? validateCredentialsName(options.name) : void 0;
5093
+ if (finishName !== void 0 && finishName !== pending.credentialName) {
5094
+ throw new ZapierCliValidationError(
5095
+ "Cannot change --name while completing a pending OAuth flow. Start a new non-interactive login with the desired --name."
5096
+ );
5097
+ }
5098
+ if (options.useApprovals === true && !pending.useApprovals) {
5099
+ throw new ZapierCliValidationError(
5100
+ "Cannot add --use-approvals while completing a pending OAuth flow. Start a new non-interactive flow with --use-approvals."
5101
+ );
5102
+ }
5103
+ if (pending.credentialName !== void 0) {
5104
+ const activeCredentials = getActiveCredentials({
5105
+ baseUrl: pending.credentialsBaseUrl
5106
+ });
5107
+ if (activeCredentials?.name !== pending.credentialName && credentialNameExists({
5108
+ name: pending.credentialName,
5109
+ baseUrl: pending.credentialsBaseUrl
5110
+ })) {
5111
+ throw new ZapierCliValidationError(
5112
+ `A credential named "${pending.credentialName}" already exists. Choose a different --name.`
5113
+ );
5114
+ }
5115
+ }
5116
+ if (!await clearExistingAuthState({
5117
+ sdk,
5118
+ baseUrl: pending.credentialsBaseUrl,
5119
+ interactive: false,
5120
+ entryPoint
5121
+ })) {
5122
+ return;
5123
+ }
5124
+ const { accessToken: accessToken2 } = await runOauthWithRedaction(async () => {
5125
+ return resumePendingOauthFlow({
5126
+ callbackUrl,
5127
+ pending,
5128
+ onProgress: (event) => {
5129
+ if (entryPoint === "signup" && event.type === "callback_accepted") {
5130
+ emitSignupSuccess({
5131
+ sdk,
5132
+ isNonInteractive: true,
5133
+ isHeadless: pending.headless
5134
+ });
5135
+ }
5136
+ }
5137
+ });
5138
+ });
5139
+ await provisionAccountCredentials({
5140
+ sdk,
5141
+ entryPoint,
5142
+ accessToken: accessToken2,
5143
+ credentialsBaseUrl: pending.credentialsBaseUrl,
5144
+ credentialName: pending.credentialName,
5145
+ interactive: false,
5146
+ useApprovals: pending.useApprovals,
5147
+ isNonInteractive: true,
5148
+ isHeadless: pending.headless
5149
+ });
5150
+ return;
5151
+ }
4851
5152
  const timeoutSeconds = parseTimeoutSeconds(options.timeout);
4852
5153
  const interactive = !resolveNonInteractive(options);
4853
5154
  const resolvedCredentials = await sdk.context.resolveCredentials();
@@ -4876,6 +5177,19 @@ async function runAccountAuth({
4876
5177
  })) {
4877
5178
  return;
4878
5179
  }
5180
+ const useApprovals = options.useApprovals === true;
5181
+ if (!interactive) {
5182
+ await startPendingOauthFlow({
5183
+ entryPoint,
5184
+ timeoutMs: timeoutSeconds * 1e3,
5185
+ pkceCredentials,
5186
+ baseUrl: credentialsBaseUrl2,
5187
+ credentialName: providedName,
5188
+ useApprovals,
5189
+ headless
5190
+ });
5191
+ return;
5192
+ }
4879
5193
  const { accessToken } = await runOauthForEntryPoint({
4880
5194
  sdk,
4881
5195
  entryPoint,
@@ -4885,39 +5199,17 @@ async function runAccountAuth({
4885
5199
  headless,
4886
5200
  interactive
4887
5201
  });
4888
- const scopedApi = getOrCreateApiClient({
4889
- credentials: accessToken,
4890
- baseUrl: credentialsBaseUrl2,
4891
- callerPackage: sdk.context.options?.callerPackage
4892
- });
4893
- const profile = await getProfile(scopedApi);
4894
- process.stderr.write(`${getProfileMessage(entryPoint, profile.email)}
4895
- `);
4896
- process.stderr.write(
4897
- "\nGenerating credentials so this machine can make authenticated requests on your behalf.\n"
4898
- );
4899
- const credentialName = providedName ?? await resolveCredentialName({
4900
- email: profile.email,
4901
- interactive,
4902
- baseUrl: credentialsBaseUrl2,
4903
- entryPoint
4904
- });
4905
- const useApprovals = options.useApprovals === true;
4906
- const { clientId } = await saveClientCredentials({
4907
- api: scopedApi,
4908
- name: credentialName,
5202
+ await provisionAccountCredentials({
5203
+ sdk,
5204
+ entryPoint,
5205
+ accessToken,
4909
5206
  credentialsBaseUrl: credentialsBaseUrl2,
5207
+ credentialName: providedName,
5208
+ interactive,
4910
5209
  useApprovals,
4911
- cleanupLogPrefix: entryPoint
5210
+ isNonInteractive: false,
5211
+ isHeadless: headless
4912
5212
  });
4913
- process.stderr.write(
4914
- `\u2705 Credentials "${credentialName}" created and set as default. You are ready to use the Zapier SDK.
4915
- `
4916
- );
4917
- if (useApprovals) {
4918
- process.stderr.write("\u{1F510} Approvals are enabled for these credentials.\n");
4919
- }
4920
- emitAccountAuthSuccess({ sdk, profile, clientId });
4921
5213
  }
4922
5214
  var LoginSchema = z.object({
4923
5215
  name: z.string().optional().describe(
@@ -4937,8 +5229,20 @@ var LoginSchema = z.object({
4937
5229
  }),
4938
5230
  headless: z.boolean().optional().describe(
4939
5231
  "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."
5232
+ ),
5233
+ callbackUrl: z.string().optional().describe(
5234
+ "Resume a pending non-interactive login with the final OAuth callback URL from your browser."
4940
5235
  )
4941
- }).describe("Log in to Zapier to access your account");
5236
+ }).describe("Log in to Zapier to access your account").meta({
5237
+ cliTelemetry: {
5238
+ authFlow: {
5239
+ callbackUrlParam: "callbackUrl",
5240
+ headlessParam: "headless",
5241
+ nonInteractiveParam: "nonInteractive",
5242
+ skipPromptsParam: "skipPrompts"
5243
+ }
5244
+ }
5245
+ });
4942
5246
 
4943
5247
  // src/plugins/login/index.ts
4944
5248
  var loginPlugin = definePlugin(
@@ -4967,8 +5271,20 @@ var SignupSchema = z.object({
4967
5271
  }),
4968
5272
  headless: z.boolean().optional().describe(
4969
5273
  "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."
5274
+ ),
5275
+ callbackUrl: z.string().optional().describe(
5276
+ "Resume a pending non-interactive signup with the final OAuth callback URL from your browser."
4970
5277
  )
4971
- }).describe("Set up Zapier account access and SDK credentials");
5278
+ }).describe("Set up Zapier account access and SDK credentials").meta({
5279
+ cliTelemetry: {
5280
+ authFlow: {
5281
+ callbackUrlParam: "callbackUrl",
5282
+ headlessParam: "headless",
5283
+ nonInteractiveParam: "nonInteractive",
5284
+ skipPromptsParam: "skipPrompts"
5285
+ }
5286
+ }
5287
+ });
4972
5288
 
4973
5289
  // src/plugins/signup/index.ts
4974
5290
  var signupPlugin = definePlugin(
@@ -7569,7 +7885,7 @@ function buildBoxLines(message) {
7569
7885
  // package.json with { type: 'json' }
7570
7886
  var package_default2 = {
7571
7887
  name: "@zapier/zapier-sdk-cli",
7572
- version: "0.62.0"};
7888
+ version: "0.63.0"};
7573
7889
 
7574
7890
  // src/sdk.ts
7575
7891
  injectCliLogin(login_exports);