@zapier/zapier-sdk-cli 0.86.7 → 0.87.1
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/AGENTS.md +4 -4
- package/CHANGELOG.md +21 -0
- package/README.md +40 -3
- package/dist/cli.cjs +801 -391
- package/dist/cli.mjs +805 -395
- package/dist/experimental.cjs +798 -386
- package/dist/experimental.d.mts +1 -1
- package/dist/experimental.d.ts +1 -1
- package/dist/experimental.mjs +801 -389
- package/dist/{extensions-OFaHmWVC.d.mts → extensions-CrfC6xjA.d.mts} +23 -2
- package/dist/{extensions-OFaHmWVC.d.ts → extensions-CrfC6xjA.d.ts} +23 -2
- package/dist/index.cjs +798 -388
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +802 -392
- package/package.json +4 -4
package/dist/cli.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command, CommanderError, Option, InvalidArgumentError } from 'commander';
|
|
3
|
-
import { STABILITY_LEVELS, getConnectionPlugin, definePlugin, apiPlugin, defineMethod, apiPluginRef, resolveCredentialsPluginRef, eventEmissionPluginRef, sdkOptionsPluginRef, declareOptionalProperty, OutputPropertySchema, ZapierBundleError, isZapierBundleError, DEFAULT_CONFIG_PATH, declareMethod, ZapierValidationError, isZapierValidationError, ZapierUnknownError, manifestPluginRef, defineResolver, isPermanentHttpError, isZapierAuthenticationError, ZapierApiError, defineOverride, fetchPlugin, zapierCoreOptions, injectCliLogin, omitExports, zapierSdkPlugin, BaseSdkOptionsSchema, disposeSdk, invalidateCachedToken, batch, toSnakeCase, ZapierError, isZapierReleaseTriggerMessageSignal, createSdk as createSdk$2, CORE_OPTIONS_ID as CORE_OPTIONS_ID$2, SDK_OPTIONS_ID as SDK_OPTIONS_ID$2, addPlugin as addPlugin$2, formatExtensionPluginFailure as formatExtensionPluginFailure$2, resolvePlugin, isCredentialsObject, getRegistryPlugin, createController, ZapierAbortDrainSignal, ZapierReleaseTriggerMessageSignal, STABILITY_DEFINITIONS, getRegistry, getCoreErrorCode, CoreErrorCode, applyStabilityLabel, buildApplicationLifecycleEvent, AuthMechanism, DEPRECATION_NOTICE_EVENT, runWithCallerContext,
|
|
3
|
+
import { STABILITY_LEVELS, getConnectionPlugin, definePlugin, apiPlugin, defineMethod, apiPluginRef, resolveCredentialsPluginRef, eventEmissionPluginRef, sdkOptionsPluginRef, declareOptionalProperty, OutputPropertySchema, ZapierBundleError, isZapierBundleError, DEFAULT_CONFIG_PATH, declareMethod, ZapierValidationError, isZapierValidationError, ZapierUnknownError, manifestPluginRef, defineResolver, isPermanentHttpError, isZapierAuthenticationError, ZapierApiError, defineOverride, fetchPlugin, zapierCoreOptions, injectCliLogin, omitExports, zapierSdkPlugin, BaseSdkOptionsSchema, disposeSdk, invalidateCachedToken, batch, toSnakeCase, ZapierError, isZapierReleaseTriggerMessageSignal, createSdk as createSdk$2, CORE_OPTIONS_ID as CORE_OPTIONS_ID$2, SDK_OPTIONS_ID as SDK_OPTIONS_ID$2, addPlugin as addPlugin$2, formatExtensionPluginFailure as formatExtensionPluginFailure$2, resolvePlugin, isCredentialsObject, isZapierSignal, getRegistryPlugin, createController, ZapierAbortDrainSignal, ZapierReleaseTriggerMessageSignal, STABILITY_DEFINITIONS, getRegistry, getCoreErrorCode, CoreErrorCode, applyStabilityLabel, buildApplicationLifecycleEvent, AuthMechanism, ZapierSignal, DEPRECATION_NOTICE_EVENT, runWithCallerContext, getNegatable, isInternalField, isPositional, descriptionFor, isCoreCancelledSignal, isZapierError, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, isZapierConflictError, getReleaseId, getCurrentTimestamp, generateEventId, isZapierApprovalError, ZapierAuthenticationError } from '@zapier/zapier-sdk';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
6
|
import chalk10 from 'chalk';
|
|
7
7
|
import { makeTheme, createPrompt, useState, usePrefix, useMemo, useEffect, useKeypress, isEnterKey, isTabKey, isUpKey, isDownKey, usePagination, Separator } from '@inquirer/core';
|
|
8
8
|
import ora from 'ora';
|
|
9
9
|
import * as fs from 'fs';
|
|
10
|
-
import { promises, createWriteStream, existsSync, readdirSync, readFileSync, rmSync, mkdirSync, writeFileSync, copyFileSync } from 'fs';
|
|
10
|
+
import { promises, createWriteStream, existsSync, readdirSync, realpathSync, readFileSync, rmSync, mkdirSync, writeFileSync, copyFileSync } from 'fs';
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
import { resolve, join, dirname, basename, relative, extname } from 'path';
|
|
13
13
|
import isInstalledGlobally from 'is-installed-globally';
|
|
@@ -33,8 +33,9 @@ import { fileURLToPath } from 'url';
|
|
|
33
33
|
import packageJsonLib, { VersionNotFoundError } from 'package-json';
|
|
34
34
|
import semver from 'semver';
|
|
35
35
|
import crossSpawn from 'cross-spawn';
|
|
36
|
+
import { createRequire } from 'module';
|
|
36
37
|
import Table from 'cli-table3';
|
|
37
|
-
import { triggerInboxResolver, DrainTriggerInboxSchema, WatchTriggerInboxSchema,
|
|
38
|
+
import { triggerInboxResolver, DrainTriggerInboxSchema, WatchTriggerInboxSchema, injectCliLogin as injectCliLogin$2, definePlugin as definePlugin$1, omitExports as omitExports$1, zapierExperimentalSdkPlugin, createSdk, CORE_OPTIONS_ID, SDK_OPTIONS_ID, addPlugin, formatExtensionPluginFailure } from '@zapier/zapier-sdk/experimental';
|
|
38
39
|
import { injectCliLogin as injectCliLogin$1, definePlugin as definePlugin$2, omitExports as omitExports$2, zapierBetaSdkPlugin, createSdk as createSdk$1, CORE_OPTIONS_ID as CORE_OPTIONS_ID$1, SDK_OPTIONS_ID as SDK_OPTIONS_ID$1, addPlugin as addPlugin$1, formatExtensionPluginFailure as formatExtensionPluginFailure$1 } from '@zapier/zapier-sdk/beta';
|
|
39
40
|
import * as readline from 'readline';
|
|
40
41
|
|
|
@@ -562,7 +563,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
562
563
|
|
|
563
564
|
// package.json
|
|
564
565
|
var package_default = {
|
|
565
|
-
version: "0.
|
|
566
|
+
version: "0.87.1"};
|
|
566
567
|
var PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
|
|
567
568
|
var LOCKFILES = [
|
|
568
569
|
["pnpm-lock.yaml", "pnpm"],
|
|
@@ -688,7 +689,7 @@ function buildCliCommandExecutedEvent({
|
|
|
688
689
|
is_ci_environment: isCi(),
|
|
689
690
|
ci_platform: getCiPlatform(),
|
|
690
691
|
...getTtyContext(),
|
|
691
|
-
agent: getAgent
|
|
692
|
+
agent: getAgent(),
|
|
692
693
|
package_manager: data.package_manager ?? detectPackageManager(process.cwd()).name,
|
|
693
694
|
made_network_requests: data.made_network_requests ?? null,
|
|
694
695
|
files_modified_count: data.files_modified_count ?? null,
|
|
@@ -1080,6 +1081,7 @@ var SENSITIVE_FLAGS = [
|
|
|
1080
1081
|
"--credentials-client-id",
|
|
1081
1082
|
"--credentials-base-url",
|
|
1082
1083
|
"--callback-url",
|
|
1084
|
+
"--answer",
|
|
1083
1085
|
"--user",
|
|
1084
1086
|
"--header",
|
|
1085
1087
|
"-H",
|
|
@@ -1295,11 +1297,11 @@ function analyzeZodField(name, schema) {
|
|
|
1295
1297
|
let deprecationMessage;
|
|
1296
1298
|
let nullable = false;
|
|
1297
1299
|
while (true) {
|
|
1298
|
-
const meta =
|
|
1300
|
+
const meta = z.globalRegistry.get(baseSchema);
|
|
1299
1301
|
if (meta?.deprecated) {
|
|
1300
1302
|
isDeprecated = true;
|
|
1301
1303
|
}
|
|
1302
|
-
if (meta?.deprecationMessage && !deprecationMessage) {
|
|
1304
|
+
if (typeof meta?.deprecationMessage === "string" && !deprecationMessage) {
|
|
1303
1305
|
deprecationMessage = meta.deprecationMessage;
|
|
1304
1306
|
}
|
|
1305
1307
|
if (baseSchema instanceof z.ZodOptional) {
|
|
@@ -1360,6 +1362,7 @@ function analyzeZodField(name, schema) {
|
|
|
1360
1362
|
elementType,
|
|
1361
1363
|
deprecationMessage,
|
|
1362
1364
|
isDeprecated,
|
|
1365
|
+
isInternal: isInternalField(schema),
|
|
1363
1366
|
negatable: getNegatable(schema),
|
|
1364
1367
|
nullable
|
|
1365
1368
|
};
|
|
@@ -1818,6 +1821,7 @@ function addCommand(program2, commandName, config2) {
|
|
|
1818
1821
|
param.description || `${kebabName} parameter`
|
|
1819
1822
|
);
|
|
1820
1823
|
} else {
|
|
1824
|
+
const hideFromHelp = param.isDeprecated || param.isInternal;
|
|
1821
1825
|
const flags = [];
|
|
1822
1826
|
const alias = config2.aliases?.[param.name];
|
|
1823
1827
|
if (alias && alias.length === 1) {
|
|
@@ -1826,7 +1830,7 @@ function addCommand(program2, commandName, config2) {
|
|
|
1826
1830
|
flags.push(`--${kebabName}`);
|
|
1827
1831
|
if (param.type === "boolean") {
|
|
1828
1832
|
const opt = new Option(flags.join(", "), param.description);
|
|
1829
|
-
if (
|
|
1833
|
+
if (hideFromHelp) opt.hideHelp();
|
|
1830
1834
|
command.addOption(opt);
|
|
1831
1835
|
const negationKebab = negationKebabName(param);
|
|
1832
1836
|
if (negationKebab !== void 0) {
|
|
@@ -1837,7 +1841,7 @@ function addCommand(program2, commandName, config2) {
|
|
|
1837
1841
|
if (!negationKebab.startsWith("no-")) {
|
|
1838
1842
|
negation.conflicts(param.name);
|
|
1839
1843
|
}
|
|
1840
|
-
if (
|
|
1844
|
+
if (hideFromHelp) negation.hideHelp();
|
|
1841
1845
|
command.addOption(negation);
|
|
1842
1846
|
}
|
|
1843
1847
|
booleanFlags2.push({
|
|
@@ -1853,7 +1857,7 @@ function addCommand(program2, commandName, config2) {
|
|
|
1853
1857
|
opt.argParser(
|
|
1854
1858
|
(value, previous) => (previous || []).concat([value])
|
|
1855
1859
|
);
|
|
1856
|
-
if (
|
|
1860
|
+
if (hideFromHelp) opt.hideHelp();
|
|
1857
1861
|
command.addOption(opt);
|
|
1858
1862
|
} else {
|
|
1859
1863
|
const flagSignature = flags.join(", ") + ` <${param.type}>`;
|
|
@@ -1861,7 +1865,7 @@ function addCommand(program2, commandName, config2) {
|
|
|
1861
1865
|
if (param.default !== void 0) {
|
|
1862
1866
|
opt.default(param.default);
|
|
1863
1867
|
}
|
|
1864
|
-
if (
|
|
1868
|
+
if (hideFromHelp) opt.hideHelp();
|
|
1865
1869
|
command.addOption(opt);
|
|
1866
1870
|
}
|
|
1867
1871
|
}
|
|
@@ -3065,6 +3069,7 @@ async function setupClientCredentials({
|
|
|
3065
3069
|
}
|
|
3066
3070
|
return { clientId };
|
|
3067
3071
|
}
|
|
3072
|
+
var CREDENTIALS_PICKER_QUESTION = "Select credentials or add a new account:";
|
|
3068
3073
|
function isSameCredentials(left, right) {
|
|
3069
3074
|
return left.name === right.name && left.baseUrl === right.baseUrl;
|
|
3070
3075
|
}
|
|
@@ -3170,7 +3175,7 @@ async function promptForCredentials({
|
|
|
3170
3175
|
activeCredentials
|
|
3171
3176
|
}) {
|
|
3172
3177
|
return searchSelect({
|
|
3173
|
-
message:
|
|
3178
|
+
message: CREDENTIALS_PICKER_QUESTION,
|
|
3174
3179
|
source: (term) => buildCredentialsChoices({
|
|
3175
3180
|
credentials: credentials2,
|
|
3176
3181
|
activeCredentials,
|
|
@@ -3233,14 +3238,15 @@ async function switchCredentials({
|
|
|
3233
3238
|
async function chooseStoredLoginCredentialsAtBaseUrl({
|
|
3234
3239
|
baseUrl: baseUrl2,
|
|
3235
3240
|
options,
|
|
3236
|
-
resolvedCredentials
|
|
3241
|
+
resolvedCredentials,
|
|
3242
|
+
prompt = promptForCredentials
|
|
3237
3243
|
}) {
|
|
3238
3244
|
if (resolvedCredentials !== void 0 || authFlowOnlyOptions(options).length > 0) {
|
|
3239
3245
|
return "none";
|
|
3240
3246
|
}
|
|
3241
3247
|
const storedCredentials = listStoredCredentials({ baseUrl: baseUrl2 });
|
|
3242
3248
|
if (storedCredentials.length === 0) return "none";
|
|
3243
|
-
const selection = await
|
|
3249
|
+
const selection = await prompt({
|
|
3244
3250
|
credentials: storedCredentials,
|
|
3245
3251
|
activeCredentials: getActiveCredentials({ baseUrl: baseUrl2 })
|
|
3246
3252
|
});
|
|
@@ -3254,7 +3260,8 @@ async function chooseStoredLoginCredentialsAtBaseUrl({
|
|
|
3254
3260
|
}
|
|
3255
3261
|
async function chooseStoredLoginCredentials({
|
|
3256
3262
|
imports,
|
|
3257
|
-
options
|
|
3263
|
+
options,
|
|
3264
|
+
prompt
|
|
3258
3265
|
}) {
|
|
3259
3266
|
const resolvedCredentials = await imports.resolveCredentials();
|
|
3260
3267
|
const credentialsBaseUrl2 = await resolveCredentialsBaseUrl({
|
|
@@ -3264,7 +3271,8 @@ async function chooseStoredLoginCredentials({
|
|
|
3264
3271
|
return chooseStoredLoginCredentialsAtBaseUrl({
|
|
3265
3272
|
baseUrl: credentialsBaseUrl2,
|
|
3266
3273
|
options,
|
|
3267
|
-
resolvedCredentials
|
|
3274
|
+
resolvedCredentials,
|
|
3275
|
+
prompt
|
|
3268
3276
|
});
|
|
3269
3277
|
}
|
|
3270
3278
|
async function confirmNewCredentialsName(name) {
|
|
@@ -3635,6 +3643,7 @@ var PendingOauthTransactionSchema = z.object({
|
|
|
3635
3643
|
credentialName: z.string().optional(),
|
|
3636
3644
|
useApprovals: z.boolean(),
|
|
3637
3645
|
headless: z.boolean().default(false),
|
|
3646
|
+
preserveExistingCredentials: z.boolean().default(false),
|
|
3638
3647
|
transaction: OauthTransactionSchema
|
|
3639
3648
|
});
|
|
3640
3649
|
function savePendingOauthTransaction({
|
|
@@ -3644,7 +3653,8 @@ function savePendingOauthTransaction({
|
|
|
3644
3653
|
credentialsBaseUrl: credentialsBaseUrl2,
|
|
3645
3654
|
credentialName,
|
|
3646
3655
|
useApprovals,
|
|
3647
|
-
headless
|
|
3656
|
+
headless,
|
|
3657
|
+
preserveExistingCredentials = false
|
|
3648
3658
|
}) {
|
|
3649
3659
|
const pendingTransaction = {
|
|
3650
3660
|
version: 1,
|
|
@@ -3652,6 +3662,7 @@ function savePendingOauthTransaction({
|
|
|
3652
3662
|
expiresAt,
|
|
3653
3663
|
useApprovals,
|
|
3654
3664
|
headless,
|
|
3665
|
+
preserveExistingCredentials,
|
|
3655
3666
|
transaction,
|
|
3656
3667
|
...credentialsBaseUrl2 !== void 0 && { credentialsBaseUrl: credentialsBaseUrl2 },
|
|
3657
3668
|
...credentialName !== void 0 && { credentialName }
|
|
@@ -3670,6 +3681,7 @@ function clearPendingOauthTransaction() {
|
|
|
3670
3681
|
}
|
|
3671
3682
|
|
|
3672
3683
|
// src/utils/auth/oauth-flow.ts
|
|
3684
|
+
var OAUTH_CALLBACK_QUESTION = "Paste the final OAuth callback URL:";
|
|
3673
3685
|
var PENDING_OAUTH_RECOVERY_MESSAGE = "Start a new non-interactive login or signup flow to generate a fresh URL.";
|
|
3674
3686
|
var LOGIN_OAUTH_COPY = {
|
|
3675
3687
|
flowName: "Login",
|
|
@@ -3733,7 +3745,9 @@ async function startPendingOauthFlow({
|
|
|
3733
3745
|
entryPoint,
|
|
3734
3746
|
credentialName,
|
|
3735
3747
|
useApprovals,
|
|
3736
|
-
headless
|
|
3748
|
+
headless,
|
|
3749
|
+
preserveExistingCredentials = false,
|
|
3750
|
+
silent = false
|
|
3737
3751
|
}) {
|
|
3738
3752
|
const copy = entryPoint === "signup" ? SIGNUP_OAUTH_COPY : LOGIN_OAUTH_COPY;
|
|
3739
3753
|
const port = LOGIN_PORTS[0];
|
|
@@ -3750,8 +3764,10 @@ async function startPendingOauthFlow({
|
|
|
3750
3764
|
credentialsBaseUrl: baseUrl2,
|
|
3751
3765
|
credentialName,
|
|
3752
3766
|
useApprovals,
|
|
3753
|
-
headless
|
|
3767
|
+
headless,
|
|
3768
|
+
preserveExistingCredentials
|
|
3754
3769
|
});
|
|
3770
|
+
if (silent) return pending;
|
|
3755
3771
|
process.stderr.write(
|
|
3756
3772
|
`Open this ${copy.urlLabel} in a browser to continue:
|
|
3757
3773
|
`
|
|
@@ -3777,23 +3793,24 @@ async function startPendingOauthFlow({
|
|
|
3777
3793
|
return pending;
|
|
3778
3794
|
}
|
|
3779
3795
|
function getPendingOauthFlow({
|
|
3780
|
-
entryPoint
|
|
3796
|
+
entryPoint,
|
|
3797
|
+
recoveryMessage = PENDING_OAUTH_RECOVERY_MESSAGE
|
|
3781
3798
|
}) {
|
|
3782
3799
|
const pending = getPendingOauthTransaction();
|
|
3783
3800
|
if (!pending) {
|
|
3784
3801
|
throw new ZapierCliValidationError(
|
|
3785
|
-
`No pending ${entryPoint} OAuth flow found. ${
|
|
3802
|
+
`No pending ${entryPoint} OAuth flow found. ${recoveryMessage}`
|
|
3786
3803
|
);
|
|
3787
3804
|
}
|
|
3788
3805
|
if (Date.now() > pending.expiresAt) {
|
|
3789
3806
|
clearPendingOauthTransaction();
|
|
3790
3807
|
throw new ZapierCliValidationError(
|
|
3791
|
-
`Pending ${pending.entryPoint} OAuth flow has expired. ${
|
|
3808
|
+
`Pending ${pending.entryPoint} OAuth flow has expired. ${recoveryMessage}`
|
|
3792
3809
|
);
|
|
3793
3810
|
}
|
|
3794
3811
|
if (pending.entryPoint !== entryPoint) {
|
|
3795
3812
|
throw new ZapierCliValidationError(
|
|
3796
|
-
`Pending OAuth flow is for ${pending.entryPoint}, not ${entryPoint}. ${
|
|
3813
|
+
`Pending OAuth flow is for ${pending.entryPoint}, not ${entryPoint}. ${recoveryMessage}`
|
|
3797
3814
|
);
|
|
3798
3815
|
}
|
|
3799
3816
|
return pending;
|
|
@@ -3956,7 +3973,7 @@ async function readHeadlessCallbackUrl({
|
|
|
3956
3973
|
process.once("SIGINT", handleCancellation);
|
|
3957
3974
|
process.once("SIGTERM", handleCancellation);
|
|
3958
3975
|
if (interactive) {
|
|
3959
|
-
void rl.question(
|
|
3976
|
+
void rl.question(`${OAUTH_CALLBACK_QUESTION} `, {
|
|
3960
3977
|
signal: abortController.signal
|
|
3961
3978
|
}).then(settleResolve).catch((error) => {
|
|
3962
3979
|
if (error instanceof Error && error.name === "AbortError") {
|
|
@@ -4443,7 +4460,7 @@ async function runOauthForEntryPoint({
|
|
|
4443
4460
|
if (event.type === "callback_accepted") {
|
|
4444
4461
|
emitSignupSuccess({
|
|
4445
4462
|
imports,
|
|
4446
|
-
isNonInteractive:
|
|
4463
|
+
isNonInteractive: !interactive,
|
|
4447
4464
|
isHeadless: headless === true
|
|
4448
4465
|
});
|
|
4449
4466
|
}
|
|
@@ -4525,7 +4542,9 @@ async function runAccountAuth({
|
|
|
4525
4542
|
options,
|
|
4526
4543
|
entryPoint,
|
|
4527
4544
|
storedCredentialsMode = "choose",
|
|
4528
|
-
preserveExistingCredentials = false
|
|
4545
|
+
preserveExistingCredentials = false,
|
|
4546
|
+
useBrowserCallback = false,
|
|
4547
|
+
silent = false
|
|
4529
4548
|
}) {
|
|
4530
4549
|
if (options.callbackUrl !== void 0) {
|
|
4531
4550
|
const { callbackUrl } = options;
|
|
@@ -4558,7 +4577,8 @@ async function runAccountAuth({
|
|
|
4558
4577
|
imports,
|
|
4559
4578
|
baseUrl: pending.credentialsBaseUrl,
|
|
4560
4579
|
interactive: false,
|
|
4561
|
-
entryPoint
|
|
4580
|
+
entryPoint,
|
|
4581
|
+
preserveExistingCredentials: pending.preserveExistingCredentials
|
|
4562
4582
|
})) {
|
|
4563
4583
|
return;
|
|
4564
4584
|
}
|
|
@@ -4635,7 +4655,7 @@ async function runAccountAuth({
|
|
|
4635
4655
|
);
|
|
4636
4656
|
}
|
|
4637
4657
|
}
|
|
4638
|
-
if (entryPoint === "login" && !interactive && providedName === void 0) {
|
|
4658
|
+
if (entryPoint === "login" && !interactive && providedName === void 0 && !preserveExistingCredentials) {
|
|
4639
4659
|
const activeCredentials = getActiveCredentials({
|
|
4640
4660
|
baseUrl: credentialsBaseUrl2
|
|
4641
4661
|
});
|
|
@@ -4652,7 +4672,7 @@ async function runAccountAuth({
|
|
|
4652
4672
|
}
|
|
4653
4673
|
const timeoutSeconds = parseTimeoutSeconds(options.timeout);
|
|
4654
4674
|
const useApprovals = options.useApprovals === true;
|
|
4655
|
-
if (!interactive) {
|
|
4675
|
+
if (!interactive && (headless || !useBrowserCallback)) {
|
|
4656
4676
|
await startPendingOauthFlow({
|
|
4657
4677
|
entryPoint,
|
|
4658
4678
|
timeoutMs: timeoutSeconds * 1e3,
|
|
@@ -4660,7 +4680,9 @@ async function runAccountAuth({
|
|
|
4660
4680
|
baseUrl: credentialsBaseUrl2,
|
|
4661
4681
|
credentialName: providedName,
|
|
4662
4682
|
useApprovals,
|
|
4663
|
-
headless
|
|
4683
|
+
headless,
|
|
4684
|
+
preserveExistingCredentials,
|
|
4685
|
+
silent
|
|
4664
4686
|
});
|
|
4665
4687
|
return;
|
|
4666
4688
|
}
|
|
@@ -4681,7 +4703,7 @@ async function runAccountAuth({
|
|
|
4681
4703
|
credentialName: providedName,
|
|
4682
4704
|
interactive,
|
|
4683
4705
|
useApprovals,
|
|
4684
|
-
isNonInteractive:
|
|
4706
|
+
isNonInteractive: !interactive,
|
|
4685
4707
|
isHeadless: headless
|
|
4686
4708
|
});
|
|
4687
4709
|
}
|
|
@@ -6521,6 +6543,7 @@ function createProjectDir({
|
|
|
6521
6543
|
var TEMPLATES_DIR = fileURLToPath(
|
|
6522
6544
|
new URL("../templates", import.meta.url)
|
|
6523
6545
|
);
|
|
6546
|
+
var SOURCE_CLI_PATH = import.meta.url.endsWith(".ts") ? fileURLToPath(new URL("./cli.ts", import.meta.url)) : void 0;
|
|
6524
6547
|
|
|
6525
6548
|
// src/plugins/init/steps.ts
|
|
6526
6549
|
var DEFAULT_TEMPLATE = "basic";
|
|
@@ -6981,84 +7004,6 @@ async function checkAndNotifyUpdates({
|
|
|
6981
7004
|
const versionInfo = await checkForUpdates({ packageName, currentVersion });
|
|
6982
7005
|
displayUpdateNotification(versionInfo, packageName);
|
|
6983
7006
|
}
|
|
6984
|
-
var BRAILLE_BLANK = "\u2800";
|
|
6985
|
-
var LIGHTNING_INTERVAL_MILLISECONDS = 140;
|
|
6986
|
-
var boltRows = [
|
|
6987
|
-
"\u2800\u2800\u2880\u28FE\u2800\u2800\u2800\u2800",
|
|
6988
|
-
"\u2800\u2800\u28E0\u28FF\u28FF\u2800\u2800\u2800",
|
|
6989
|
-
"\u2800\u28FC\u28FF\u28FF\u28FF\u28C0\u28C0\u2840",
|
|
6990
|
-
"\u2808\u2809\u2809\u28FF\u28FF\u28FF\u285F\u2800",
|
|
6991
|
-
"\u2800\u2800\u2800\u28FF\u28FF\u280B\u2800\u2800",
|
|
6992
|
-
"\u2800\u2800\u2800\u287F\u2801\u2800\u2800\u2800"
|
|
6993
|
-
];
|
|
6994
|
-
var boltFillOrder = boltRows.flatMap(
|
|
6995
|
-
(row, rowIndex) => [...row].flatMap(
|
|
6996
|
-
(cell, columnIndex) => cell === BRAILLE_BLANK ? [] : rowIndex * row.length + columnIndex
|
|
6997
|
-
)
|
|
6998
|
-
);
|
|
6999
|
-
var fillStages = [
|
|
7000
|
-
...Array.from({ length: boltFillOrder.length + 1 }, (_, index) => index),
|
|
7001
|
-
boltFillOrder.length,
|
|
7002
|
-
0
|
|
7003
|
-
];
|
|
7004
|
-
var boltFillRanks = new Map(
|
|
7005
|
-
boltFillOrder.map((cellIndex, fillIndex) => [cellIndex, fillIndex])
|
|
7006
|
-
);
|
|
7007
|
-
var STATUS_ROW_INDEX = Math.floor(boltRows.length / 2);
|
|
7008
|
-
function formatPhase({ label, detail }) {
|
|
7009
|
-
return detail ? `${chalk10.bold(label)} ${chalk10.dim(detail)}` : chalk10.bold(label);
|
|
7010
|
-
}
|
|
7011
|
-
function formatLoaderFrame({
|
|
7012
|
-
phase,
|
|
7013
|
-
fillStage
|
|
7014
|
-
}) {
|
|
7015
|
-
return boltRows.map((row, rowIndex) => {
|
|
7016
|
-
const bolt = [...row].map((cell, columnIndex) => {
|
|
7017
|
-
if (cell === BRAILLE_BLANK) return cell;
|
|
7018
|
-
const cellIndex = rowIndex * row.length + columnIndex;
|
|
7019
|
-
const fillRank = boltFillRanks.get(cellIndex);
|
|
7020
|
-
const isFilled = fillRank !== void 0 && fillRank < fillStage;
|
|
7021
|
-
return isFilled ? chalk10.bold.yellow(cell) : chalk10.dim.yellow(cell);
|
|
7022
|
-
}).join("");
|
|
7023
|
-
const status = rowIndex === STATUS_ROW_INDEX ? ` ${formatPhase(phase)}` : "";
|
|
7024
|
-
return `${bolt}${status}`;
|
|
7025
|
-
}).join("\n");
|
|
7026
|
-
}
|
|
7027
|
-
async function runWithSetupLoader({
|
|
7028
|
-
promise,
|
|
7029
|
-
...phase
|
|
7030
|
-
}) {
|
|
7031
|
-
const startedAt = Date.now();
|
|
7032
|
-
let fillFrameIndex = 0;
|
|
7033
|
-
const loader = ora({
|
|
7034
|
-
isEnabled: process.stderr.isTTY === true,
|
|
7035
|
-
spinner: { interval: 80, frames: [""] },
|
|
7036
|
-
text: formatLoaderFrame({
|
|
7037
|
-
phase,
|
|
7038
|
-
fillStage: fillStages[fillFrameIndex]
|
|
7039
|
-
})
|
|
7040
|
-
}).start();
|
|
7041
|
-
const animationTimer = setInterval(() => {
|
|
7042
|
-
fillFrameIndex = (fillFrameIndex + 1) % fillStages.length;
|
|
7043
|
-
loader.text = formatLoaderFrame({
|
|
7044
|
-
phase,
|
|
7045
|
-
fillStage: fillStages[fillFrameIndex]
|
|
7046
|
-
});
|
|
7047
|
-
}, LIGHTNING_INTERVAL_MILLISECONDS);
|
|
7048
|
-
animationTimer.unref?.();
|
|
7049
|
-
try {
|
|
7050
|
-
const result = await promise;
|
|
7051
|
-
clearInterval(animationTimer);
|
|
7052
|
-
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
7053
|
-
loader.succeed(`${formatPhase(phase)} ${chalk10.dim(`${elapsedSeconds}s`)}`);
|
|
7054
|
-
return result;
|
|
7055
|
-
} catch (error) {
|
|
7056
|
-
clearInterval(animationTimer);
|
|
7057
|
-
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
7058
|
-
loader.fail(`${formatPhase(phase)} ${chalk10.dim(`${elapsedSeconds}s`)}`);
|
|
7059
|
-
throw error;
|
|
7060
|
-
}
|
|
7061
|
-
}
|
|
7062
7007
|
function isRecord(value) {
|
|
7063
7008
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7064
7009
|
}
|
|
@@ -7344,7 +7289,7 @@ async function offerPackageUpdate({
|
|
|
7344
7289
|
}) {
|
|
7345
7290
|
const { currentVersion, dependency } = packageState;
|
|
7346
7291
|
if (!currentVersion || !dependency.checkForUpdates) return;
|
|
7347
|
-
const update = await
|
|
7292
|
+
const update = await context.load({
|
|
7348
7293
|
promise: context.checkForUpdates({
|
|
7349
7294
|
packageName: dependency.name,
|
|
7350
7295
|
currentVersion
|
|
@@ -7369,28 +7314,108 @@ async function offerPackageUpdate({
|
|
|
7369
7314
|
})
|
|
7370
7315
|
);
|
|
7371
7316
|
}
|
|
7372
|
-
|
|
7317
|
+
function getPackageStates(context) {
|
|
7373
7318
|
const declaredPackageNames = getDeclaredPackageNames(context.cwd);
|
|
7374
7319
|
const requiredPackages = REQUIRED_PACKAGES.filter(
|
|
7375
7320
|
({ typescriptOnly }) => !typescriptOnly || context.projectLanguage === "typescript"
|
|
7376
7321
|
);
|
|
7377
|
-
|
|
7322
|
+
return requiredPackages.map((dependency) => ({
|
|
7378
7323
|
dependency,
|
|
7324
|
+
declared: declaredPackageNames.has(dependency.name),
|
|
7379
7325
|
currentVersion: declaredPackageNames.has(dependency.name) ? getInstalledPackageVersion({
|
|
7380
7326
|
cwd: context.cwd,
|
|
7381
7327
|
packageName: dependency.name
|
|
7382
7328
|
}) : void 0
|
|
7383
7329
|
}));
|
|
7330
|
+
}
|
|
7331
|
+
async function prepareDependencies(context) {
|
|
7332
|
+
const packages = getPackageStates(context);
|
|
7384
7333
|
await offerMissingPackageInstall({
|
|
7385
7334
|
context,
|
|
7386
|
-
packages: packages.filter(
|
|
7387
|
-
({ dependency }) => !declaredPackageNames.has(dependency.name)
|
|
7388
|
-
)
|
|
7335
|
+
packages: packages.filter(({ declared }) => !declared)
|
|
7389
7336
|
});
|
|
7390
7337
|
for (const packageState of packages) {
|
|
7391
7338
|
await offerPackageUpdate({ context, packageState });
|
|
7392
7339
|
}
|
|
7393
7340
|
}
|
|
7341
|
+
var BRAILLE_BLANK = "\u2800";
|
|
7342
|
+
var LIGHTNING_INTERVAL_MILLISECONDS = 140;
|
|
7343
|
+
var boltRows = [
|
|
7344
|
+
"\u2800\u2800\u2880\u28FE\u2800\u2800\u2800\u2800",
|
|
7345
|
+
"\u2800\u2800\u28E0\u28FF\u28FF\u2800\u2800\u2800",
|
|
7346
|
+
"\u2800\u28FC\u28FF\u28FF\u28FF\u28C0\u28C0\u2840",
|
|
7347
|
+
"\u2808\u2809\u2809\u28FF\u28FF\u28FF\u285F\u2800",
|
|
7348
|
+
"\u2800\u2800\u2800\u28FF\u28FF\u280B\u2800\u2800",
|
|
7349
|
+
"\u2800\u2800\u2800\u287F\u2801\u2800\u2800\u2800"
|
|
7350
|
+
];
|
|
7351
|
+
var boltFillOrder = boltRows.flatMap(
|
|
7352
|
+
(row, rowIndex) => [...row].flatMap(
|
|
7353
|
+
(cell, columnIndex) => cell === BRAILLE_BLANK ? [] : rowIndex * row.length + columnIndex
|
|
7354
|
+
)
|
|
7355
|
+
);
|
|
7356
|
+
var fillStages = [
|
|
7357
|
+
...Array.from({ length: boltFillOrder.length + 1 }, (_, index) => index),
|
|
7358
|
+
boltFillOrder.length,
|
|
7359
|
+
0
|
|
7360
|
+
];
|
|
7361
|
+
var boltFillRanks = new Map(
|
|
7362
|
+
boltFillOrder.map((cellIndex, fillIndex) => [cellIndex, fillIndex])
|
|
7363
|
+
);
|
|
7364
|
+
var STATUS_ROW_INDEX = Math.floor(boltRows.length / 2);
|
|
7365
|
+
function formatPhase({ label, detail }) {
|
|
7366
|
+
return detail ? `${chalk10.bold(label)} ${chalk10.dim(detail)}` : chalk10.bold(label);
|
|
7367
|
+
}
|
|
7368
|
+
function formatLoaderFrame({
|
|
7369
|
+
phase,
|
|
7370
|
+
fillStage
|
|
7371
|
+
}) {
|
|
7372
|
+
return boltRows.map((row, rowIndex) => {
|
|
7373
|
+
const bolt = [...row].map((cell, columnIndex) => {
|
|
7374
|
+
if (cell === BRAILLE_BLANK) return cell;
|
|
7375
|
+
const cellIndex = rowIndex * row.length + columnIndex;
|
|
7376
|
+
const fillRank = boltFillRanks.get(cellIndex);
|
|
7377
|
+
const isFilled = fillRank !== void 0 && fillRank < fillStage;
|
|
7378
|
+
return isFilled ? chalk10.bold.yellow(cell) : chalk10.dim.yellow(cell);
|
|
7379
|
+
}).join("");
|
|
7380
|
+
const status = rowIndex === STATUS_ROW_INDEX ? ` ${formatPhase(phase)}` : "";
|
|
7381
|
+
return `${bolt}${status}`;
|
|
7382
|
+
}).join("\n");
|
|
7383
|
+
}
|
|
7384
|
+
async function runWithSetupLoader({
|
|
7385
|
+
promise,
|
|
7386
|
+
...phase
|
|
7387
|
+
}) {
|
|
7388
|
+
const startedAt = Date.now();
|
|
7389
|
+
let fillFrameIndex = 0;
|
|
7390
|
+
const loader = ora({
|
|
7391
|
+
isEnabled: process.stderr.isTTY === true,
|
|
7392
|
+
spinner: { interval: 80, frames: [""] },
|
|
7393
|
+
text: formatLoaderFrame({
|
|
7394
|
+
phase,
|
|
7395
|
+
fillStage: fillStages[fillFrameIndex]
|
|
7396
|
+
})
|
|
7397
|
+
}).start();
|
|
7398
|
+
const animationTimer = setInterval(() => {
|
|
7399
|
+
fillFrameIndex = (fillFrameIndex + 1) % fillStages.length;
|
|
7400
|
+
loader.text = formatLoaderFrame({
|
|
7401
|
+
phase,
|
|
7402
|
+
fillStage: fillStages[fillFrameIndex]
|
|
7403
|
+
});
|
|
7404
|
+
}, LIGHTNING_INTERVAL_MILLISECONDS);
|
|
7405
|
+
animationTimer.unref?.();
|
|
7406
|
+
try {
|
|
7407
|
+
const result = await promise;
|
|
7408
|
+
clearInterval(animationTimer);
|
|
7409
|
+
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
7410
|
+
loader.succeed(`${formatPhase(phase)} ${chalk10.dim(`${elapsedSeconds}s`)}`);
|
|
7411
|
+
return result;
|
|
7412
|
+
} catch (error) {
|
|
7413
|
+
clearInterval(animationTimer);
|
|
7414
|
+
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
7415
|
+
loader.fail(`${formatPhase(phase)} ${chalk10.dim(`${elapsedSeconds}s`)}`);
|
|
7416
|
+
throw error;
|
|
7417
|
+
}
|
|
7418
|
+
}
|
|
7394
7419
|
|
|
7395
7420
|
// src/plugins/setup/package-commands.ts
|
|
7396
7421
|
function createLocalPackageCommand({
|
|
@@ -7429,7 +7454,10 @@ function formatPackageCommand({
|
|
|
7429
7454
|
command,
|
|
7430
7455
|
args
|
|
7431
7456
|
}) {
|
|
7432
|
-
return [command, ...args].join(" ");
|
|
7457
|
+
return [command, ...args].map(quoteShellArgument).join(" ");
|
|
7458
|
+
}
|
|
7459
|
+
function quoteShellArgument(value) {
|
|
7460
|
+
return /^[a-zA-Z0-9_@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
7433
7461
|
}
|
|
7434
7462
|
|
|
7435
7463
|
// src/plugins/setup/project.ts
|
|
@@ -7534,13 +7562,14 @@ async function runCommand({
|
|
|
7534
7562
|
args = [],
|
|
7535
7563
|
cwd,
|
|
7536
7564
|
capture = true,
|
|
7537
|
-
input
|
|
7565
|
+
input,
|
|
7566
|
+
load = runWithSetupLoader
|
|
7538
7567
|
}) {
|
|
7539
7568
|
const commandLabel = `$ ${command} ${args.join(" ")}`.trim();
|
|
7540
7569
|
const execute = capture ? executeCapturedCommand({ command, args, cwd, input }) : executeStreamingCommand({ command, args, cwd, input });
|
|
7541
7570
|
try {
|
|
7542
7571
|
if (capture) {
|
|
7543
|
-
return await
|
|
7572
|
+
return await load({
|
|
7544
7573
|
promise: execute,
|
|
7545
7574
|
label: "Running command",
|
|
7546
7575
|
detail: commandLabel
|
|
@@ -7624,7 +7653,7 @@ function detectProjectLanguage({
|
|
|
7624
7653
|
);
|
|
7625
7654
|
return hasTypeScript ? "typescript" : "javascript";
|
|
7626
7655
|
}
|
|
7627
|
-
async function
|
|
7656
|
+
async function initializeProject(context) {
|
|
7628
7657
|
context.packageManager = detectPackageManager(context.cwd).name;
|
|
7629
7658
|
console.log(`Using ${context.packageManager} for dependency installs.`);
|
|
7630
7659
|
const hasExistingProject = existsSync(join(context.cwd, "package.json"));
|
|
@@ -7640,182 +7669,157 @@ async function prepareProject(context) {
|
|
|
7640
7669
|
cwd: context.cwd
|
|
7641
7670
|
});
|
|
7642
7671
|
}
|
|
7672
|
+
}
|
|
7673
|
+
async function prepareProject(context) {
|
|
7674
|
+
await initializeProject(context);
|
|
7643
7675
|
await prepareDependencies(context);
|
|
7644
7676
|
}
|
|
7645
7677
|
|
|
7646
7678
|
// src/plugins/setup/context.ts
|
|
7647
7679
|
function createWizardContext({
|
|
7648
|
-
imports
|
|
7680
|
+
imports,
|
|
7681
|
+
agent = false
|
|
7649
7682
|
}) {
|
|
7650
|
-
|
|
7683
|
+
const context = {
|
|
7651
7684
|
cwd: process.cwd(),
|
|
7685
|
+
load: agent ? ({ promise }) => promise : runWithSetupLoader,
|
|
7652
7686
|
imports,
|
|
7653
7687
|
createAnswer: () => createCliAnswer({ mode: "closed-list" }),
|
|
7654
7688
|
setupController: createSetupController(),
|
|
7655
|
-
selectStoredLoginCredentials: () => chooseStoredLoginCredentials({
|
|
7656
|
-
|
|
7689
|
+
selectStoredLoginCredentials: () => chooseStoredLoginCredentials({
|
|
7690
|
+
imports,
|
|
7691
|
+
options: {},
|
|
7692
|
+
...agent ? {
|
|
7693
|
+
prompt: async (options) => {
|
|
7694
|
+
const credentialChoices = buildCredentialsChoices(options);
|
|
7695
|
+
const choices = credentialChoices.map(({ name, value }) => ({
|
|
7696
|
+
label: name,
|
|
7697
|
+
value: value.action === "create" ? "create" : `account:${value.credentials.name}`,
|
|
7698
|
+
result: value
|
|
7699
|
+
}));
|
|
7700
|
+
const selected = await resolveSetupSelect({
|
|
7701
|
+
answer: context.createAnswer(),
|
|
7702
|
+
controller: context.setupController,
|
|
7703
|
+
message: CREDENTIALS_PICKER_QUESTION,
|
|
7704
|
+
choices
|
|
7705
|
+
});
|
|
7706
|
+
const selectedIndex = choices.findIndex(
|
|
7707
|
+
({ value }) => value === selected
|
|
7708
|
+
);
|
|
7709
|
+
return choices[selectedIndex].result;
|
|
7710
|
+
}
|
|
7711
|
+
} : {}
|
|
7712
|
+
}),
|
|
7713
|
+
authenticateNewAccount: ({ entryPoint, ...options }) => runAccountAuth({
|
|
7657
7714
|
imports,
|
|
7658
|
-
options
|
|
7715
|
+
options,
|
|
7659
7716
|
entryPoint,
|
|
7660
7717
|
storedCredentialsMode: "fresh",
|
|
7661
|
-
preserveExistingCredentials: true
|
|
7718
|
+
preserveExistingCredentials: true,
|
|
7719
|
+
useBrowserCallback: agent && options.headless === false,
|
|
7720
|
+
silent: agent && options.headless
|
|
7662
7721
|
}),
|
|
7663
7722
|
checkForUpdates,
|
|
7664
7723
|
openUrl: async (url) => {
|
|
7665
7724
|
await open(url);
|
|
7666
7725
|
},
|
|
7667
|
-
runCommand
|
|
7726
|
+
runCommand: agent ? (options) => runCommand({
|
|
7727
|
+
...options,
|
|
7728
|
+
capture: true,
|
|
7729
|
+
load: ({ promise, detail }) => {
|
|
7730
|
+
console.log(detail);
|
|
7731
|
+
return promise;
|
|
7732
|
+
}
|
|
7733
|
+
}) : runCommand,
|
|
7668
7734
|
packageManager: detectPackageManager(process.cwd()).name,
|
|
7669
7735
|
projectLanguage: "typescript"
|
|
7670
7736
|
};
|
|
7737
|
+
return context;
|
|
7738
|
+
}
|
|
7739
|
+
var SetupStepSchema = z.enum([
|
|
7740
|
+
"directory",
|
|
7741
|
+
"project",
|
|
7742
|
+
"install",
|
|
7743
|
+
"sdk-update",
|
|
7744
|
+
"cli-update",
|
|
7745
|
+
"skill",
|
|
7746
|
+
"account",
|
|
7747
|
+
"account-flow",
|
|
7748
|
+
"account-environment",
|
|
7749
|
+
"authorize",
|
|
7750
|
+
"confirm-account",
|
|
7751
|
+
"connections",
|
|
7752
|
+
"slack",
|
|
7753
|
+
"slack-overwrite",
|
|
7754
|
+
"slack-existing",
|
|
7755
|
+
"slack-retry",
|
|
7756
|
+
"handoff"
|
|
7757
|
+
]);
|
|
7758
|
+
var SetupSchema = z.object({
|
|
7759
|
+
agent: z.boolean().optional().describe(
|
|
7760
|
+
"For AI agents and callers without a terminal: print the next setup question and the exact command to run for each answer."
|
|
7761
|
+
),
|
|
7762
|
+
step: SetupStepSchema.optional().describe(
|
|
7763
|
+
"Setup operation to inspect or execute."
|
|
7764
|
+
),
|
|
7765
|
+
nonInteractive: z.boolean().optional().describe("Execute the named setup step without terminal prompts."),
|
|
7766
|
+
answer: z.string().optional().describe(
|
|
7767
|
+
"User selection or input for a non-interactive setup step. Omitted confirmations use the terminal wizard's default."
|
|
7768
|
+
),
|
|
7769
|
+
flow: z.enum(["login", "signup"]).optional().describe(
|
|
7770
|
+
"Account flow selected for the environment and OAuth callback steps."
|
|
7771
|
+
),
|
|
7772
|
+
language: z.enum(["javascript", "typescript"]).optional().describe(
|
|
7773
|
+
"Project language for dependency installation and the Slack demo."
|
|
7774
|
+
)
|
|
7775
|
+
}).describe(
|
|
7776
|
+
"Set up the Zapier SDK in an existing or new project. Runs an interactive terminal wizard; AI agents should use --agent instead."
|
|
7777
|
+
);
|
|
7778
|
+
var agentLabels = {
|
|
7779
|
+
claude: "Claude Code",
|
|
7780
|
+
codex: "Codex",
|
|
7781
|
+
cursor: "Cursor",
|
|
7782
|
+
"vscode-copilot": "VS Code Copilot"
|
|
7783
|
+
};
|
|
7784
|
+
function buildAgentPrompt({
|
|
7785
|
+
context
|
|
7786
|
+
}) {
|
|
7787
|
+
const listConnectionsCommand = formatPackageCommand(
|
|
7788
|
+
createLocalPackageCommand({
|
|
7789
|
+
packageManager: context.packageManager,
|
|
7790
|
+
binary: "zapier-sdk",
|
|
7791
|
+
args: ["list-connections", "--owner", "me", "--json"]
|
|
7792
|
+
})
|
|
7793
|
+
);
|
|
7794
|
+
const listActionsCommand = formatPackageCommand(
|
|
7795
|
+
createLocalPackageCommand({
|
|
7796
|
+
packageManager: context.packageManager,
|
|
7797
|
+
binary: "zapier-sdk",
|
|
7798
|
+
args: ["list-actions", "APP_KEY"]
|
|
7799
|
+
})
|
|
7800
|
+
);
|
|
7801
|
+
return `Start by running this command to discover my active connected apps outside of your sandbox:
|
|
7802
|
+
|
|
7803
|
+
${listConnectionsCommand}
|
|
7804
|
+
|
|
7805
|
+
Using the connected apps returned by that command:
|
|
7806
|
+
|
|
7807
|
+
- Pick 1-3 apps and show commands I can use to explore their actions, such as: ${listActionsCommand}
|
|
7808
|
+
- Do not run those list-actions commands.
|
|
7809
|
+
- Suggest 3 specific ideas based on my connected apps. Each idea should read from one app, optionally process data, and write to another.
|
|
7810
|
+
- Do not suggest event-driven workflows.
|
|
7811
|
+
- Keep each idea to one sentence. Example: "pull in-progress Jira issues and DM yourself a summary on Slack".
|
|
7812
|
+
|
|
7813
|
+
Do not inspect files or modify the project. If fewer than two distinct apps are listed, explain that cross-app ideas require another active connection instead of inventing apps.`;
|
|
7671
7814
|
}
|
|
7672
|
-
|
|
7673
|
-
function printAuthCommand({
|
|
7815
|
+
function printAgentPrompt({
|
|
7674
7816
|
context,
|
|
7675
|
-
|
|
7676
|
-
headless
|
|
7817
|
+
message
|
|
7677
7818
|
}) {
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
});
|
|
7683
|
-
console.log(`$ ${formatPackageCommand(command)}`);
|
|
7684
|
-
if (headless) {
|
|
7685
|
-
console.log(
|
|
7686
|
-
"Open the printed URL in another browser, then paste the final OAuth callback URL when prompted."
|
|
7687
|
-
);
|
|
7688
|
-
}
|
|
7689
|
-
}
|
|
7690
|
-
function isCredentialWriteError(error) {
|
|
7691
|
-
const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : "";
|
|
7692
|
-
if (/^(eacces|eperm)$/i.test(code)) return true;
|
|
7693
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
7694
|
-
return /permission|sandbox|eacces|eperm/i.test(message);
|
|
7695
|
-
}
|
|
7696
|
-
async function confirmAuthentication(context) {
|
|
7697
|
-
const { data: profile } = await runWithSetupLoader({
|
|
7698
|
-
promise: context.imports.getProfile({}),
|
|
7699
|
-
label: "Confirming Zapier account"
|
|
7700
|
-
});
|
|
7701
|
-
context.accountEmail = profile.email;
|
|
7702
|
-
console.log(`Authenticated as ${profile.email}.`);
|
|
7703
|
-
}
|
|
7704
|
-
async function authenticate(context) {
|
|
7705
|
-
const activeProfile = await runWithSetupLoader({
|
|
7706
|
-
promise: context.imports.getProfile({}).then(({ data }) => data).catch((error) => {
|
|
7707
|
-
if (isZapierAuthenticationError(error)) return void 0;
|
|
7708
|
-
throw error;
|
|
7709
|
-
}),
|
|
7710
|
-
label: "Checking Zapier authentication"
|
|
7711
|
-
});
|
|
7712
|
-
const storedCredentialsSelection = await context.selectStoredLoginCredentials();
|
|
7713
|
-
if (storedCredentialsSelection === "switch") {
|
|
7714
|
-
await confirmAuthentication(context);
|
|
7715
|
-
return;
|
|
7716
|
-
}
|
|
7717
|
-
if (storedCredentialsSelection === "none" && activeProfile) {
|
|
7718
|
-
const shouldLogout = await resolveSetupConfirm({
|
|
7719
|
-
answer: context.createAnswer(),
|
|
7720
|
-
controller: context.setupController,
|
|
7721
|
-
message: `You are already logged in as "${activeProfile.email}".
|
|
7722
|
-
Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
|
|
7723
|
-
Log out and use a different account?`,
|
|
7724
|
-
defaultValue: false
|
|
7725
|
-
});
|
|
7726
|
-
if (!shouldLogout) {
|
|
7727
|
-
context.accountEmail = activeProfile.email;
|
|
7728
|
-
console.log(`Continuing as ${activeProfile.email}.`);
|
|
7729
|
-
return;
|
|
7730
|
-
}
|
|
7731
|
-
const logoutCommand = createLocalPackageCommand({
|
|
7732
|
-
packageManager: context.packageManager,
|
|
7733
|
-
binary: "zapier-sdk",
|
|
7734
|
-
args: ["logout"]
|
|
7735
|
-
});
|
|
7736
|
-
console.log(`$ ${formatPackageCommand(logoutCommand)}`);
|
|
7737
|
-
await context.imports.logout({});
|
|
7738
|
-
}
|
|
7739
|
-
const flow = await resolveSetupSelect({
|
|
7740
|
-
answer: context.createAnswer(),
|
|
7741
|
-
controller: context.setupController,
|
|
7742
|
-
message: "Zapier account:",
|
|
7743
|
-
choices: [
|
|
7744
|
-
{ label: "Log in to an existing account", value: "login" },
|
|
7745
|
-
{ label: "Create a new Zapier account", value: "signup" }
|
|
7746
|
-
]
|
|
7747
|
-
});
|
|
7748
|
-
const environment = await resolveSetupSelect({
|
|
7749
|
-
answer: context.createAnswer(),
|
|
7750
|
-
controller: context.setupController,
|
|
7751
|
-
message: "Environment:",
|
|
7752
|
-
choices: [
|
|
7753
|
-
{ label: "Local machine with a browser", value: "local" },
|
|
7754
|
-
{ label: "Remote or headless", value: "headless" }
|
|
7755
|
-
]
|
|
7756
|
-
});
|
|
7757
|
-
const headless = environment === "headless";
|
|
7758
|
-
printAuthCommand({ context, flow, headless });
|
|
7759
|
-
try {
|
|
7760
|
-
if (storedCredentialsSelection === "create") {
|
|
7761
|
-
await context.authenticateNewAccount({ entryPoint: flow, headless });
|
|
7762
|
-
} else {
|
|
7763
|
-
const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
|
|
7764
|
-
await runAuth({ headless });
|
|
7765
|
-
}
|
|
7766
|
-
} catch (error) {
|
|
7767
|
-
if (isCredentialWriteError(error)) {
|
|
7768
|
-
console.error(
|
|
7769
|
-
"Authentication could not write credentials. A permissions or sandbox restriction may be blocking disk access."
|
|
7770
|
-
);
|
|
7771
|
-
}
|
|
7772
|
-
throw error;
|
|
7773
|
-
}
|
|
7774
|
-
await confirmAuthentication(context);
|
|
7775
|
-
}
|
|
7776
|
-
var agentLabels = {
|
|
7777
|
-
claude: "Claude Code",
|
|
7778
|
-
codex: "Codex",
|
|
7779
|
-
cursor: "Cursor",
|
|
7780
|
-
"vscode-copilot": "VS Code Copilot"
|
|
7781
|
-
};
|
|
7782
|
-
function buildAgentPrompt({ context }) {
|
|
7783
|
-
const listConnectionsCommand = formatPackageCommand(
|
|
7784
|
-
createLocalPackageCommand({
|
|
7785
|
-
packageManager: context.packageManager,
|
|
7786
|
-
binary: "zapier-sdk",
|
|
7787
|
-
args: ["list-connections", "--owner", "me", "--json"]
|
|
7788
|
-
})
|
|
7789
|
-
);
|
|
7790
|
-
const listActionsCommand = formatPackageCommand(
|
|
7791
|
-
createLocalPackageCommand({
|
|
7792
|
-
packageManager: context.packageManager,
|
|
7793
|
-
binary: "zapier-sdk",
|
|
7794
|
-
args: ["list-actions", "APP_KEY"]
|
|
7795
|
-
})
|
|
7796
|
-
);
|
|
7797
|
-
return `Start by running this command to discover my active connected apps outside of your sandbox:
|
|
7798
|
-
|
|
7799
|
-
${listConnectionsCommand}
|
|
7800
|
-
|
|
7801
|
-
Using the connected apps returned by that command:
|
|
7802
|
-
|
|
7803
|
-
- Pick 1-3 apps and show commands I can use to explore their actions, such as: ${listActionsCommand}
|
|
7804
|
-
- Do not run those list-actions commands.
|
|
7805
|
-
- Suggest 3 specific ideas based on my connected apps. Each idea should read from one app, optionally process data, and write to another.
|
|
7806
|
-
- Do not suggest event-driven workflows.
|
|
7807
|
-
- Keep each idea to one sentence. Example: "pull in-progress Jira issues and DM yourself a summary on Slack".
|
|
7808
|
-
|
|
7809
|
-
Do not inspect files or modify the project. If fewer than two distinct apps are listed, explain that cross-app ideas require another active connection instead of inventing apps.`;
|
|
7810
|
-
}
|
|
7811
|
-
function printAgentPrompt({
|
|
7812
|
-
context,
|
|
7813
|
-
message
|
|
7814
|
-
}) {
|
|
7815
|
-
console.log();
|
|
7816
|
-
console.log(chalk10.bgYellow.black.bold(message));
|
|
7817
|
-
console.log();
|
|
7818
|
-
console.log(buildAgentPrompt({ context }));
|
|
7819
|
+
console.log();
|
|
7820
|
+
console.log(chalk10.bgYellow.black.bold(message));
|
|
7821
|
+
console.log();
|
|
7822
|
+
console.log(buildAgentPrompt({ context }));
|
|
7819
7823
|
}
|
|
7820
7824
|
async function openAgentHandoff(context) {
|
|
7821
7825
|
const agent = await resolveSetupSelect({
|
|
@@ -7886,27 +7890,291 @@ async function openAgentHandoff(context) {
|
|
|
7886
7890
|
message: "If it didn't load correctly, paste this prompt into your agent:"
|
|
7887
7891
|
});
|
|
7888
7892
|
}
|
|
7893
|
+
|
|
7894
|
+
// src/plugins/setup/agent-output.ts
|
|
7895
|
+
var REQUIRED_STEPS = [
|
|
7896
|
+
"directory",
|
|
7897
|
+
"install"
|
|
7898
|
+
];
|
|
7899
|
+
function formatSetupCommand({
|
|
7900
|
+
context,
|
|
7901
|
+
target,
|
|
7902
|
+
answer
|
|
7903
|
+
}) {
|
|
7904
|
+
const args = [
|
|
7905
|
+
"setup",
|
|
7906
|
+
"--step",
|
|
7907
|
+
target.step,
|
|
7908
|
+
"--non-interactive",
|
|
7909
|
+
...target.flow ? ["--flow", target.flow] : [],
|
|
7910
|
+
"--language",
|
|
7911
|
+
context.projectLanguage,
|
|
7912
|
+
...answer !== void 0 ? ["--answer", answer] : []
|
|
7913
|
+
];
|
|
7914
|
+
return formatPackageCommand(
|
|
7915
|
+
SOURCE_CLI_PATH ? {
|
|
7916
|
+
command: process.execPath,
|
|
7917
|
+
args: [
|
|
7918
|
+
"--import",
|
|
7919
|
+
createRequire(import.meta.url).resolve("tsx"),
|
|
7920
|
+
"--conditions",
|
|
7921
|
+
"source",
|
|
7922
|
+
SOURCE_CLI_PATH,
|
|
7923
|
+
...args
|
|
7924
|
+
]
|
|
7925
|
+
} : createPackageRunnerCommand({
|
|
7926
|
+
packageManager: context.packageManager,
|
|
7927
|
+
packageName: `@zapier/zapier-sdk-cli@${package_default.version}`,
|
|
7928
|
+
args
|
|
7929
|
+
})
|
|
7930
|
+
);
|
|
7931
|
+
}
|
|
7932
|
+
function printAgentStep({
|
|
7933
|
+
context,
|
|
7934
|
+
target,
|
|
7935
|
+
question
|
|
7936
|
+
}) {
|
|
7937
|
+
console.log(
|
|
7938
|
+
`Step: ${target.step}
|
|
7939
|
+
Working directory: ${context.cwd}
|
|
7940
|
+
Detected package manager: ${context.packageManager}
|
|
7941
|
+
Project language: ${context.projectLanguage}`
|
|
7942
|
+
);
|
|
7943
|
+
if (!question) {
|
|
7944
|
+
console.log(
|
|
7945
|
+
`Run this exact command:
|
|
7946
|
+
${formatSetupCommand({ context, target })}`
|
|
7947
|
+
);
|
|
7948
|
+
} else {
|
|
7949
|
+
if (target.step === "authorize" && context.authorizationUrl)
|
|
7950
|
+
console.log(
|
|
7951
|
+
`Give the user this URL to open in a browser where they can sign in to Zapier:
|
|
7952
|
+
${context.authorizationUrl}
|
|
7953
|
+
After they approve, the browser opens a localhost page that may fail to load. That is expected: ask them to copy the full address from the browser's address bar. Pass that address only to the command below; do not save it or repeat it elsewhere.`
|
|
7954
|
+
);
|
|
7955
|
+
console.log(`Ask the user this question verbatim: "${question.message}"`);
|
|
7956
|
+
if (question.type === "select") {
|
|
7957
|
+
for (const { value, label } of question.choices)
|
|
7958
|
+
console.log(`${JSON.stringify(value)}: ${label}`);
|
|
7959
|
+
for (const { value } of question.choices) {
|
|
7960
|
+
const decision = value === "true" ? "agrees" : value === "false" ? "declines" : `chooses ${JSON.stringify(value)}`;
|
|
7961
|
+
if (value === "false" && REQUIRED_STEPS.includes(target.step))
|
|
7962
|
+
console.log("If the user declines, stop setup.");
|
|
7963
|
+
else
|
|
7964
|
+
console.log(
|
|
7965
|
+
`If the user ${decision}, run this exact command:
|
|
7966
|
+
${formatSetupCommand({ context, target, answer: value })}`
|
|
7967
|
+
);
|
|
7968
|
+
}
|
|
7969
|
+
} else {
|
|
7970
|
+
console.log(
|
|
7971
|
+
`Run this exact command with their answer as one shell-quoted argument (an empty answer is ''):
|
|
7972
|
+
${formatSetupCommand({ context, target, answer: "<answer>" })}`
|
|
7973
|
+
);
|
|
7974
|
+
}
|
|
7975
|
+
if (target.step === "account-environment")
|
|
7976
|
+
console.log(
|
|
7977
|
+
`The local command opens a browser and waits up to ${LOGIN_TIMEOUT_MILLISECONDS / 1e3} seconds for authorization, using the terminal login flow. Keep the process running until it completes and allow extra time for credential creation. If the browser does not open, use its printed fallback URL or choose headless instead.`
|
|
7978
|
+
);
|
|
7979
|
+
console.log(
|
|
7980
|
+
"Use your tool for asking the user questions if you have one. Do not answer on the user's behalf."
|
|
7981
|
+
);
|
|
7982
|
+
}
|
|
7983
|
+
console.log(
|
|
7984
|
+
"On success, follow the next step's guidance printed by that operation. On failure, stop and report the error; do not proceed or retry automatically. Ignore CLI update notices; setup offers package updates as their own steps."
|
|
7985
|
+
);
|
|
7986
|
+
}
|
|
7987
|
+
function printAgentCompletion({
|
|
7988
|
+
context,
|
|
7989
|
+
cancelled = false
|
|
7990
|
+
}) {
|
|
7991
|
+
console.log(
|
|
7992
|
+
cancelled ? "Setup cancelled." : `Setup walkthrough finished. Report which operations succeeded, failed, or were skipped based on their command results.
|
|
7993
|
+
Learn more: https://docs.zapier.com/sdk
|
|
7994
|
+
|
|
7995
|
+
Continue in this agent. Do not open another agent or ask the user to choose one.
|
|
7996
|
+
${buildAgentPrompt({ context })}`
|
|
7997
|
+
);
|
|
7998
|
+
}
|
|
7999
|
+
|
|
8000
|
+
// src/plugins/setup/authentication.ts
|
|
8001
|
+
function printAuthCommand({
|
|
8002
|
+
context,
|
|
8003
|
+
flow,
|
|
8004
|
+
headless = false
|
|
8005
|
+
}) {
|
|
8006
|
+
const command = createLocalPackageCommand({
|
|
8007
|
+
packageManager: context.packageManager,
|
|
8008
|
+
binary: "zapier-sdk",
|
|
8009
|
+
args: [flow, ...headless ? ["--headless"] : []]
|
|
8010
|
+
});
|
|
8011
|
+
console.log(`$ ${formatPackageCommand(command)}`);
|
|
8012
|
+
if (headless) {
|
|
8013
|
+
console.log(
|
|
8014
|
+
"Open the printed URL in another browser, then paste the final OAuth callback URL when prompted."
|
|
8015
|
+
);
|
|
8016
|
+
}
|
|
8017
|
+
}
|
|
8018
|
+
function isCredentialWriteError(error) {
|
|
8019
|
+
const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : "";
|
|
8020
|
+
if (/^(eacces|eperm)$/i.test(code)) return true;
|
|
8021
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8022
|
+
return /permission|sandbox|eacces|eperm/i.test(message);
|
|
8023
|
+
}
|
|
8024
|
+
async function confirmAuthentication(context) {
|
|
8025
|
+
const { data: profile } = await context.load({
|
|
8026
|
+
promise: context.imports.getProfile({}),
|
|
8027
|
+
label: "Confirming Zapier account"
|
|
8028
|
+
});
|
|
8029
|
+
context.accountEmail = profile.email;
|
|
8030
|
+
console.log(`Authenticated as ${profile.email}.`);
|
|
8031
|
+
}
|
|
8032
|
+
function selectAccountFlow(context) {
|
|
8033
|
+
return resolveSetupSelect({
|
|
8034
|
+
answer: context.createAnswer(),
|
|
8035
|
+
controller: context.setupController,
|
|
8036
|
+
message: "Zapier account:",
|
|
8037
|
+
choices: [
|
|
8038
|
+
{ label: "Log in to an existing account", value: "login" },
|
|
8039
|
+
{ label: "Create a new Zapier account", value: "signup" }
|
|
8040
|
+
]
|
|
8041
|
+
});
|
|
8042
|
+
}
|
|
8043
|
+
function selectAuthenticationEnvironment(context) {
|
|
8044
|
+
return resolveSetupSelect({
|
|
8045
|
+
answer: context.createAnswer(),
|
|
8046
|
+
controller: context.setupController,
|
|
8047
|
+
message: "Environment:",
|
|
8048
|
+
choices: [
|
|
8049
|
+
{ label: "Local machine with a browser", value: "local" },
|
|
8050
|
+
{ label: "Remote or headless", value: "headless" }
|
|
8051
|
+
]
|
|
8052
|
+
});
|
|
8053
|
+
}
|
|
8054
|
+
async function selectAccount(context) {
|
|
8055
|
+
const activeProfile = await context.load({
|
|
8056
|
+
promise: context.imports.getProfile({}).then(({ data }) => data).catch((error) => {
|
|
8057
|
+
if (isZapierAuthenticationError(error)) return void 0;
|
|
8058
|
+
throw error;
|
|
8059
|
+
}),
|
|
8060
|
+
label: "Checking Zapier authentication"
|
|
8061
|
+
});
|
|
8062
|
+
const storedCredentialsSelection = await context.selectStoredLoginCredentials();
|
|
8063
|
+
if (storedCredentialsSelection === "none" && activeProfile) {
|
|
8064
|
+
const shouldLogout = await resolveSetupConfirm({
|
|
8065
|
+
answer: context.createAnswer(),
|
|
8066
|
+
controller: context.setupController,
|
|
8067
|
+
message: `You are already logged in as "${activeProfile.email}".
|
|
8068
|
+
Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
|
|
8069
|
+
Log out and use a different account?`,
|
|
8070
|
+
defaultValue: false
|
|
8071
|
+
});
|
|
8072
|
+
if (!shouldLogout) {
|
|
8073
|
+
context.accountEmail = activeProfile.email;
|
|
8074
|
+
console.log(`Continuing as ${activeProfile.email}.`);
|
|
8075
|
+
return "continue";
|
|
8076
|
+
}
|
|
8077
|
+
printAuthCommand({ context, flow: "logout" });
|
|
8078
|
+
await context.imports.logout({});
|
|
8079
|
+
}
|
|
8080
|
+
return storedCredentialsSelection;
|
|
8081
|
+
}
|
|
8082
|
+
async function authenticate(context) {
|
|
8083
|
+
const next = await runAuthenticationStep({ context, options: {} });
|
|
8084
|
+
if (next.step === "confirm-account") await confirmAuthentication(context);
|
|
8085
|
+
}
|
|
8086
|
+
async function runAuthenticationStep({
|
|
8087
|
+
context,
|
|
8088
|
+
options
|
|
8089
|
+
}) {
|
|
8090
|
+
const { step } = options;
|
|
8091
|
+
let newAccount = step === "account-environment";
|
|
8092
|
+
if (!step || step === "account") {
|
|
8093
|
+
const selection = await selectAccount(context);
|
|
8094
|
+
if (selection === "switch") return { step: "confirm-account" };
|
|
8095
|
+
if (selection === "continue")
|
|
8096
|
+
return { step: step ? "confirm-account" : "connections" };
|
|
8097
|
+
if (step) return { step: "account-flow" };
|
|
8098
|
+
newAccount = selection === "create";
|
|
8099
|
+
}
|
|
8100
|
+
if (step === "confirm-account") {
|
|
8101
|
+
await confirmAuthentication(context);
|
|
8102
|
+
return { step: "connections" };
|
|
8103
|
+
}
|
|
8104
|
+
const flow = !step || step === "account-flow" ? await selectAccountFlow(context) : options.flow;
|
|
8105
|
+
if (step === "account-flow")
|
|
8106
|
+
return {
|
|
8107
|
+
step: "account-environment",
|
|
8108
|
+
flow
|
|
8109
|
+
};
|
|
8110
|
+
if (!flow)
|
|
8111
|
+
throw new ZapierCliValidationError(
|
|
8112
|
+
"This setup step requires --flow login or --flow signup."
|
|
8113
|
+
);
|
|
8114
|
+
let headless = true;
|
|
8115
|
+
let callbackUrl;
|
|
8116
|
+
let recoveryMessage;
|
|
8117
|
+
if (step === "authorize") {
|
|
8118
|
+
recoveryMessage = `Generate a fresh authorization URL with \`${formatSetupCommand(
|
|
8119
|
+
{
|
|
8120
|
+
context,
|
|
8121
|
+
target: { step: "account-environment", flow },
|
|
8122
|
+
answer: "headless"
|
|
8123
|
+
}
|
|
8124
|
+
)}\`.`;
|
|
8125
|
+
const pending = getPendingOauthFlow({ entryPoint: flow, recoveryMessage });
|
|
8126
|
+
context.authorizationUrl = pending.transaction.browserAuthUrl;
|
|
8127
|
+
callbackUrl = await resolveSetupInput({
|
|
8128
|
+
answer: context.createAnswer(),
|
|
8129
|
+
controller: context.setupController,
|
|
8130
|
+
message: OAUTH_CALLBACK_QUESTION
|
|
8131
|
+
});
|
|
8132
|
+
} else {
|
|
8133
|
+
headless = await selectAuthenticationEnvironment(context) === "headless";
|
|
8134
|
+
if (!step) printAuthCommand({ context, flow, headless });
|
|
8135
|
+
}
|
|
8136
|
+
const authOptions = {
|
|
8137
|
+
headless,
|
|
8138
|
+
...step ? { nonInteractive: true } : {},
|
|
8139
|
+
...callbackUrl !== void 0 ? { callbackUrl } : {}
|
|
8140
|
+
};
|
|
8141
|
+
try {
|
|
8142
|
+
if (newAccount) {
|
|
8143
|
+
await context.authenticateNewAccount({
|
|
8144
|
+
entryPoint: flow,
|
|
8145
|
+
...authOptions
|
|
8146
|
+
});
|
|
8147
|
+
} else {
|
|
8148
|
+
await context.imports[flow](authOptions);
|
|
8149
|
+
}
|
|
8150
|
+
} catch (error) {
|
|
8151
|
+
if (recoveryMessage) console.error(recoveryMessage);
|
|
8152
|
+
if (isCredentialWriteError(error)) {
|
|
8153
|
+
console.error(
|
|
8154
|
+
"Authentication could not write credentials. A permissions or sandbox restriction may be blocking disk access."
|
|
8155
|
+
);
|
|
8156
|
+
}
|
|
8157
|
+
throw error;
|
|
8158
|
+
}
|
|
8159
|
+
return step === "account-environment" && headless ? { step: "authorize", flow } : { step: "confirm-account" };
|
|
8160
|
+
}
|
|
7889
8161
|
var CONNECTIONS_URL = "https://zapier.com/app/assets/connections";
|
|
7890
8162
|
var CONNECTION_DISPLAY_LIMIT = 10;
|
|
7891
|
-
async function
|
|
7892
|
-
const page = await
|
|
8163
|
+
async function showActiveConnections(context) {
|
|
8164
|
+
const page = await context.load({
|
|
7893
8165
|
promise: context.imports.listConnections({
|
|
7894
8166
|
owner: "me",
|
|
7895
8167
|
maxItems: CONNECTION_DISPLAY_LIMIT
|
|
7896
8168
|
}),
|
|
7897
8169
|
label: "Loading app connections"
|
|
7898
8170
|
});
|
|
7899
|
-
if (page.data.length === 0)
|
|
7900
|
-
console.log(
|
|
7901
|
-
`No active connections found. Connect or reconnect an app at ${CONNECTIONS_URL}, then come back and run setup again.`
|
|
7902
|
-
);
|
|
7903
|
-
throw new ZapierCliExitError(
|
|
7904
|
-
"Setup stopped before completion because no active connections are available."
|
|
7905
|
-
);
|
|
7906
|
-
}
|
|
8171
|
+
if (page.data.length === 0) return false;
|
|
7907
8172
|
const table = new Table({
|
|
7908
8173
|
head: ["App", "Connection"],
|
|
7909
|
-
style: {
|
|
8174
|
+
style: {
|
|
8175
|
+
compact: true,
|
|
8176
|
+
...process.stdout.isTTY ? {} : { head: [], border: [] }
|
|
8177
|
+
}
|
|
7910
8178
|
});
|
|
7911
8179
|
table.push(
|
|
7912
8180
|
...page.data.map((connection) => [
|
|
@@ -7918,11 +8186,22 @@ async function ensureConnectionsAvailable(context) {
|
|
|
7918
8186
|
`Active Zapier connections (showing up to ${CONNECTION_DISPLAY_LIMIT}):`
|
|
7919
8187
|
);
|
|
7920
8188
|
console.log(table.toString());
|
|
8189
|
+
return true;
|
|
8190
|
+
}
|
|
8191
|
+
async function ensureConnectionsAvailable(context) {
|
|
8192
|
+
if (await showActiveConnections(context)) return;
|
|
8193
|
+
console.log(
|
|
8194
|
+
`No active connections found. Connect or reconnect an app at ${CONNECTIONS_URL}, then come back and run setup again.`
|
|
8195
|
+
);
|
|
8196
|
+
throw new ZapierCliExitError(
|
|
8197
|
+
"Setup stopped before completion because no active connections are available."
|
|
8198
|
+
);
|
|
7921
8199
|
}
|
|
7922
8200
|
var CONNECTION_PLACEHOLDER = "__ZAPIER_SDK_SLACK_CONNECTION__";
|
|
7923
8201
|
var EMAIL_PLACEHOLDER = "__ZAPIER_SDK_ACCOUNT_EMAIL__";
|
|
7924
8202
|
var APP_PLACEHOLDER = "__ZAPIER_SDK_SLACK_APP__";
|
|
7925
8203
|
var SLACK_SLUG = "slack";
|
|
8204
|
+
var SLACK_RETRY_QUESTION = "Slack email for one retry after the failed test:";
|
|
7926
8205
|
function getSlackTestPath(context) {
|
|
7927
8206
|
const extension = context.projectLanguage === "typescript" ? "ts" : "mjs";
|
|
7928
8207
|
return join("src", "sdk-demo", `zapier-slack-test.${extension}`);
|
|
@@ -7932,7 +8211,7 @@ function getSlackTestTemplatePath(context) {
|
|
|
7932
8211
|
return join(TEMPLATES_DIR, "setup", `zapier-slack-test.${extension}`);
|
|
7933
8212
|
}
|
|
7934
8213
|
async function findSlackConnection(context) {
|
|
7935
|
-
const page = await
|
|
8214
|
+
const page = await context.load({
|
|
7936
8215
|
promise: context.imports.listConnections({
|
|
7937
8216
|
owner: "me",
|
|
7938
8217
|
app: SLACK_SLUG,
|
|
@@ -7953,17 +8232,22 @@ function renderSlackTest({
|
|
|
7953
8232
|
}) {
|
|
7954
8233
|
return readFileSync(getSlackTestTemplatePath(context), "utf8").replace(APP_PLACEHOLDER, () => toTemplateString(app)).replace(CONNECTION_PLACEHOLDER, () => toTemplateString(connection)).replace(EMAIL_PLACEHOLDER, () => toTemplateString(email));
|
|
7955
8234
|
}
|
|
7956
|
-
function
|
|
8235
|
+
async function createAndRunSlackTest({
|
|
7957
8236
|
context,
|
|
7958
|
-
app,
|
|
7959
8237
|
connection,
|
|
7960
|
-
email
|
|
8238
|
+
email,
|
|
8239
|
+
overwrite = true
|
|
7961
8240
|
}) {
|
|
7962
8241
|
const slackTestPath = getSlackTestPath(context);
|
|
7963
8242
|
const path2 = join(context.cwd, slackTestPath);
|
|
7964
8243
|
if (!existsSync(dirname(path2))) mkdirSync(dirname(path2), { recursive: true });
|
|
7965
|
-
writeFileSync(
|
|
8244
|
+
writeFileSync(
|
|
8245
|
+
path2,
|
|
8246
|
+
renderSlackTest({ context, app: SLACK_SLUG, connection, email }),
|
|
8247
|
+
{ flag: overwrite ? "w" : "wx" }
|
|
8248
|
+
);
|
|
7966
8249
|
console.log(`Created ${slackTestPath}.`);
|
|
8250
|
+
return trySlackTest(context);
|
|
7967
8251
|
}
|
|
7968
8252
|
async function executeSlackTest(context) {
|
|
7969
8253
|
const slackTestPath = getSlackTestPath(context);
|
|
@@ -7991,75 +8275,76 @@ async function executeSlackTest(context) {
|
|
|
7991
8275
|
async function trySlackTest(context) {
|
|
7992
8276
|
try {
|
|
7993
8277
|
await executeSlackTest(context);
|
|
8278
|
+
(context.outcomes ?? (context.outcomes = {})).slack = "succeeded";
|
|
7994
8279
|
return true;
|
|
7995
8280
|
} catch (error) {
|
|
8281
|
+
(context.outcomes ?? (context.outcomes = {})).slack = "failed";
|
|
7996
8282
|
const message = error instanceof Error ? error.message : String(error);
|
|
7997
8283
|
console.warn(`Slack demo failed: ${message}. Setup will continue.`);
|
|
7998
8284
|
return false;
|
|
7999
8285
|
}
|
|
8000
8286
|
}
|
|
8001
|
-
async function
|
|
8287
|
+
async function runSlackStep({
|
|
8288
|
+
context,
|
|
8289
|
+
step,
|
|
8290
|
+
connection
|
|
8291
|
+
}) {
|
|
8002
8292
|
if (!context.accountEmail) {
|
|
8003
8293
|
console.log("No account email found; skipping the Slack demo.");
|
|
8004
|
-
return;
|
|
8294
|
+
return "handoff";
|
|
8005
8295
|
}
|
|
8006
|
-
|
|
8007
|
-
if (!slackConnection) {
|
|
8296
|
+
if (!connection) {
|
|
8008
8297
|
console.log("No active Slack connection found; skipping the Slack demo.");
|
|
8009
|
-
return;
|
|
8298
|
+
return "handoff";
|
|
8010
8299
|
}
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
answer: context.createAnswer(),
|
|
8014
|
-
controller: context.setupController,
|
|
8015
|
-
message: `Run the Slack self-DM test using ${context.accountEmail}?`,
|
|
8016
|
-
defaultValue: true
|
|
8017
|
-
});
|
|
8018
|
-
if (!shouldRun) return;
|
|
8019
|
-
const path2 = join(context.cwd, slackTestPath);
|
|
8020
|
-
if (existsSync(path2)) {
|
|
8021
|
-
const shouldOverwrite = await resolveSetupConfirm({
|
|
8300
|
+
if (step === "slack-retry") {
|
|
8301
|
+
const email = await resolveSetupInput({
|
|
8022
8302
|
answer: context.createAnswer(),
|
|
8023
8303
|
controller: context.setupController,
|
|
8024
|
-
message:
|
|
8025
|
-
defaultValue: false
|
|
8304
|
+
message: SLACK_RETRY_QUESTION
|
|
8026
8305
|
});
|
|
8027
|
-
if (
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
|
|
8031
|
-
|
|
8032
|
-
message: `Run the existing ${slackTestPath}?`,
|
|
8033
|
-
defaultValue: false
|
|
8306
|
+
if (email)
|
|
8307
|
+
await createAndRunSlackTest({
|
|
8308
|
+
context,
|
|
8309
|
+
connection: connection.id,
|
|
8310
|
+
email
|
|
8034
8311
|
});
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
}
|
|
8312
|
+
else console.log("Skipping the Slack test.");
|
|
8313
|
+
return "handoff";
|
|
8038
8314
|
}
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
context,
|
|
8042
|
-
app: SLACK_SLUG,
|
|
8043
|
-
connection: slackConnection.id,
|
|
8044
|
-
email
|
|
8045
|
-
});
|
|
8046
|
-
if (await trySlackTest(context)) return;
|
|
8047
|
-
email = await resolveSetupInput({
|
|
8315
|
+
const slackTestPath = getSlackTestPath(context);
|
|
8316
|
+
const shouldRun = await resolveSetupConfirm({
|
|
8048
8317
|
answer: context.createAnswer(),
|
|
8049
8318
|
controller: context.setupController,
|
|
8050
|
-
message: "Slack
|
|
8319
|
+
message: step === "slack" ? `Run the Slack self-DM test using ${context.accountEmail}?` : step === "slack-overwrite" ? `${slackTestPath} already exists. Is it okay to overwrite it?` : `Run the existing ${slackTestPath}?`,
|
|
8320
|
+
defaultValue: step === "slack"
|
|
8051
8321
|
});
|
|
8052
|
-
if (!
|
|
8053
|
-
|
|
8054
|
-
|
|
8322
|
+
if (!shouldRun) {
|
|
8323
|
+
if (step === "slack-overwrite") {
|
|
8324
|
+
console.log("Keeping the existing Slack test file.");
|
|
8325
|
+
return "slack-existing";
|
|
8326
|
+
}
|
|
8327
|
+
return "handoff";
|
|
8328
|
+
}
|
|
8329
|
+
if (step === "slack" && existsSync(join(context.cwd, slackTestPath)))
|
|
8330
|
+
return "slack-overwrite";
|
|
8331
|
+
if (step === "slack-existing") {
|
|
8332
|
+
await trySlackTest(context);
|
|
8333
|
+
return "handoff";
|
|
8055
8334
|
}
|
|
8056
|
-
|
|
8335
|
+
const succeeded = await createAndRunSlackTest({
|
|
8057
8336
|
context,
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8337
|
+
connection: connection.id,
|
|
8338
|
+
email: context.accountEmail,
|
|
8339
|
+
overwrite: step === "slack-overwrite"
|
|
8061
8340
|
});
|
|
8062
|
-
|
|
8341
|
+
return succeeded ? "handoff" : "slack-retry";
|
|
8342
|
+
}
|
|
8343
|
+
async function offerSlackTest(context) {
|
|
8344
|
+
const connection = context.accountEmail ? await findSlackConnection(context) : void 0;
|
|
8345
|
+
let step = "slack";
|
|
8346
|
+
while (step !== "handoff")
|
|
8347
|
+
step = await runSlackStep({ context, step, connection });
|
|
8063
8348
|
}
|
|
8064
8349
|
|
|
8065
8350
|
// src/plugins/setup/skill.ts
|
|
@@ -8085,7 +8370,9 @@ async function installOptionalSkill(context) {
|
|
|
8085
8370
|
cwd: context.cwd,
|
|
8086
8371
|
capture: true
|
|
8087
8372
|
});
|
|
8373
|
+
(context.outcomes ?? (context.outcomes = {})).skill = "succeeded";
|
|
8088
8374
|
} catch {
|
|
8375
|
+
(context.outcomes ?? (context.outcomes = {})).skill = "failed";
|
|
8089
8376
|
console.warn(
|
|
8090
8377
|
`Could not install the optional Zapier SDK skill. To install it manually, run: ${formatPackageCommand(command)}`
|
|
8091
8378
|
);
|
|
@@ -8142,6 +8429,177 @@ async function runWizard(context) {
|
|
|
8142
8429
|
console.log(chalk10.bgCyan.black.bold(" Next steps "));
|
|
8143
8430
|
await openAgentHandoff(context);
|
|
8144
8431
|
}
|
|
8432
|
+
var UNPROMPTED_STEPS = [
|
|
8433
|
+
"project",
|
|
8434
|
+
"confirm-account",
|
|
8435
|
+
"connections"
|
|
8436
|
+
];
|
|
8437
|
+
var ZapierSetupQuestionSignal = class extends ZapierSignal {
|
|
8438
|
+
constructor(question) {
|
|
8439
|
+
super(question.message);
|
|
8440
|
+
this.question = question;
|
|
8441
|
+
this.name = "ZapierSetupQuestionSignal";
|
|
8442
|
+
this.code = "ZAPIER_SETUP_QUESTION";
|
|
8443
|
+
}
|
|
8444
|
+
};
|
|
8445
|
+
function isZapierSetupQuestionSignal(error) {
|
|
8446
|
+
return isZapierSignal(error) && error.code === "ZAPIER_SETUP_QUESTION";
|
|
8447
|
+
}
|
|
8448
|
+
function createSetupAnswer({
|
|
8449
|
+
answer,
|
|
8450
|
+
execute
|
|
8451
|
+
}) {
|
|
8452
|
+
let answered = false;
|
|
8453
|
+
return async ({ result: { question } }) => {
|
|
8454
|
+
if (question.type === "collection")
|
|
8455
|
+
throw new ZapierCliValidationError(
|
|
8456
|
+
"Setup expects a selection or text input."
|
|
8457
|
+
);
|
|
8458
|
+
if (!execute) throw new ZapierSetupQuestionSignal(question);
|
|
8459
|
+
if (answered)
|
|
8460
|
+
throw new ZapierCliValidationError(
|
|
8461
|
+
"Each setup step can answer only one question. Inspect the next question with --agent and run it in a separate command."
|
|
8462
|
+
);
|
|
8463
|
+
answered = true;
|
|
8464
|
+
const confirmation = question.type === "select" && question.choices.some(({ value }) => value === "true") && question.choices.some(({ value }) => value === "false");
|
|
8465
|
+
if (answer === void 0 && !confirmation)
|
|
8466
|
+
throw new ZapierCliValidationError(
|
|
8467
|
+
"This setup step requires --answer. Inspect it with --agent and pass the user's selection or input."
|
|
8468
|
+
);
|
|
8469
|
+
if (question.type === "input")
|
|
8470
|
+
return { type: "custom", value: answer?.trim() ?? "" };
|
|
8471
|
+
const selected = answer?.trim() ?? question.choices[0].value;
|
|
8472
|
+
if (!question.choices.some(({ value }) => value === selected))
|
|
8473
|
+
throw new ZapierCliValidationError(
|
|
8474
|
+
`Answer must be one of: ${question.choices.map(({ value }) => value).join(", ")}.`
|
|
8475
|
+
);
|
|
8476
|
+
return { type: "choose", value: selected };
|
|
8477
|
+
};
|
|
8478
|
+
}
|
|
8479
|
+
async function runSetupStep({
|
|
8480
|
+
context,
|
|
8481
|
+
target
|
|
8482
|
+
}) {
|
|
8483
|
+
switch (target.step) {
|
|
8484
|
+
case "directory":
|
|
8485
|
+
await chooseDirectory(context);
|
|
8486
|
+
return { step: "project" };
|
|
8487
|
+
case "project":
|
|
8488
|
+
await ensureSupportedNode(context);
|
|
8489
|
+
await initializeProject(context);
|
|
8490
|
+
return { step: "install" };
|
|
8491
|
+
case "install":
|
|
8492
|
+
await offerMissingPackageInstall({
|
|
8493
|
+
context,
|
|
8494
|
+
packages: getPackageStates(context).filter(({ declared }) => !declared)
|
|
8495
|
+
});
|
|
8496
|
+
return { step: "sdk-update" };
|
|
8497
|
+
case "sdk-update":
|
|
8498
|
+
case "cli-update": {
|
|
8499
|
+
const name = target.step === "sdk-update" ? "@zapier/zapier-sdk" : "@zapier/zapier-sdk-cli";
|
|
8500
|
+
const packageState = getPackageStates(context).find(
|
|
8501
|
+
({ dependency }) => dependency.name === name
|
|
8502
|
+
);
|
|
8503
|
+
if (packageState) await offerPackageUpdate({ context, packageState });
|
|
8504
|
+
return { step: target.step === "sdk-update" ? "cli-update" : "skill" };
|
|
8505
|
+
}
|
|
8506
|
+
case "skill":
|
|
8507
|
+
await installOptionalSkill(context);
|
|
8508
|
+
return { step: "account" };
|
|
8509
|
+
case "account":
|
|
8510
|
+
case "account-flow":
|
|
8511
|
+
case "account-environment":
|
|
8512
|
+
case "authorize":
|
|
8513
|
+
case "confirm-account":
|
|
8514
|
+
return runAuthenticationStep({ context, options: target });
|
|
8515
|
+
case "connections":
|
|
8516
|
+
if (!await showActiveConnections(context)) {
|
|
8517
|
+
console.log(
|
|
8518
|
+
`No active connections found. Ask the user to connect or reconnect an app at ${CONNECTIONS_URL}. After they confirm, run this exact command:
|
|
8519
|
+
${formatSetupCommand({ context, target })}
|
|
8520
|
+
Success means it prints the active connections table.`
|
|
8521
|
+
);
|
|
8522
|
+
throw new ZapierCliExitError(
|
|
8523
|
+
"Setup stopped until an app connection is active."
|
|
8524
|
+
);
|
|
8525
|
+
}
|
|
8526
|
+
console.log(
|
|
8527
|
+
"Show the user every app and connection title in the table above before continuing. Do not just report that connections were found."
|
|
8528
|
+
);
|
|
8529
|
+
return { step: "slack" };
|
|
8530
|
+
case "slack":
|
|
8531
|
+
case "slack-overwrite":
|
|
8532
|
+
case "slack-existing":
|
|
8533
|
+
case "slack-retry": {
|
|
8534
|
+
const { data: profile } = await context.imports.getProfile({});
|
|
8535
|
+
context.accountEmail = profile.email;
|
|
8536
|
+
return {
|
|
8537
|
+
step: await runSlackStep({
|
|
8538
|
+
context,
|
|
8539
|
+
step: target.step,
|
|
8540
|
+
connection: await findSlackConnection(context)
|
|
8541
|
+
})
|
|
8542
|
+
};
|
|
8543
|
+
}
|
|
8544
|
+
}
|
|
8545
|
+
}
|
|
8546
|
+
async function runAgentSetup({
|
|
8547
|
+
context,
|
|
8548
|
+
options
|
|
8549
|
+
}) {
|
|
8550
|
+
if (options.agent && options.nonInteractive)
|
|
8551
|
+
throw new ZapierCliValidationError(
|
|
8552
|
+
"Use --agent to inspect a step or --non-interactive to execute it, not both."
|
|
8553
|
+
);
|
|
8554
|
+
if (!options.agent && !options.nonInteractive)
|
|
8555
|
+
throw new ZapierCliValidationError(
|
|
8556
|
+
options.step ? "Use --agent to inspect the named step or --non-interactive to execute it." : "--answer, --flow, and --language require a setup step."
|
|
8557
|
+
);
|
|
8558
|
+
if (options.nonInteractive && !options.step)
|
|
8559
|
+
throw new ZapierCliValidationError(
|
|
8560
|
+
"--non-interactive requires --step. Start with setup --agent and follow its printed commands."
|
|
8561
|
+
);
|
|
8562
|
+
if (options.answer !== void 0 && !options.nonInteractive)
|
|
8563
|
+
throw new ZapierCliValidationError("--answer requires --non-interactive.");
|
|
8564
|
+
context.cwd = realpathSync(context.cwd);
|
|
8565
|
+
context.projectLanguage = options.language ?? detectProjectLanguage({
|
|
8566
|
+
cwd: context.cwd,
|
|
8567
|
+
hasExistingProject: existsSync(join(context.cwd, "package.json"))
|
|
8568
|
+
});
|
|
8569
|
+
let target = {
|
|
8570
|
+
step: options.step ?? "directory",
|
|
8571
|
+
flow: options.flow
|
|
8572
|
+
};
|
|
8573
|
+
let execute = options.nonInteractive === true;
|
|
8574
|
+
while (true) {
|
|
8575
|
+
const { step, flow } = target;
|
|
8576
|
+
if (step === "handoff") return printAgentCompletion({ context });
|
|
8577
|
+
if (!execute && UNPROMPTED_STEPS.includes(step))
|
|
8578
|
+
return printAgentStep({ context, target });
|
|
8579
|
+
const answer = createSetupAnswer({
|
|
8580
|
+
answer: execute ? options.answer : void 0,
|
|
8581
|
+
execute
|
|
8582
|
+
});
|
|
8583
|
+
context.createAnswer = () => answer;
|
|
8584
|
+
try {
|
|
8585
|
+
const next = await runSetupStep({ context, target: { step, flow } });
|
|
8586
|
+
if (options.language) context.projectLanguage = options.language;
|
|
8587
|
+
if (execute)
|
|
8588
|
+
for (const [operation, outcome] of Object.entries(
|
|
8589
|
+
context.outcomes ?? {}
|
|
8590
|
+
))
|
|
8591
|
+
console.log(`${operation}: ${outcome}`);
|
|
8592
|
+
target = next;
|
|
8593
|
+
execute = false;
|
|
8594
|
+
} catch (error) {
|
|
8595
|
+
if (isZapierSetupQuestionSignal(error))
|
|
8596
|
+
return printAgentStep({ context, target, question: error.question });
|
|
8597
|
+
if (error instanceof ZapierCliUserCancellationError)
|
|
8598
|
+
return printAgentCompletion({ context, cancelled: true });
|
|
8599
|
+
throw error;
|
|
8600
|
+
}
|
|
8601
|
+
}
|
|
8602
|
+
}
|
|
8145
8603
|
|
|
8146
8604
|
// src/plugins/setup/index.ts
|
|
8147
8605
|
var getProfileRef = declareMethod({ id: "getProfile" });
|
|
@@ -8166,10 +8624,19 @@ var setupPlugin = defineMethod({
|
|
|
8166
8624
|
supportsJsonOutput: false,
|
|
8167
8625
|
inputSchema: SetupSchema,
|
|
8168
8626
|
output: "raw",
|
|
8169
|
-
run: async ({ imports }) => {
|
|
8627
|
+
run: async ({ imports, input }) => {
|
|
8628
|
+
if (input.agent || input.nonInteractive || [input.step, input.answer, input.flow, input.language].some(
|
|
8629
|
+
(value) => value !== void 0
|
|
8630
|
+
)) {
|
|
8631
|
+
await runAgentSetup({
|
|
8632
|
+
context: createWizardContext({ imports, agent: true }),
|
|
8633
|
+
options: input
|
|
8634
|
+
});
|
|
8635
|
+
return;
|
|
8636
|
+
}
|
|
8170
8637
|
if (process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
|
|
8171
|
-
throw new
|
|
8172
|
-
"`zapier-sdk setup` requires an interactive terminal."
|
|
8638
|
+
throw new ZapierCliValidationError(
|
|
8639
|
+
"`zapier-sdk setup` requires an interactive terminal. AI agents and other callers without a terminal should run `zapier-sdk setup --agent` and follow its printed steps."
|
|
8173
8640
|
);
|
|
8174
8641
|
}
|
|
8175
8642
|
await runWizard(createWizardContext({ imports }));
|
|
@@ -8649,59 +9116,6 @@ var watchTriggerInboxCliPlugin = defineMethod({
|
|
|
8649
9116
|
return doWatch();
|
|
8650
9117
|
}
|
|
8651
9118
|
});
|
|
8652
|
-
var createWorkflowRef = declareMethod$1({ id: "createWorkflow" });
|
|
8653
|
-
function createPublicInputSchema(schema) {
|
|
8654
|
-
const publicSchema = z.object(
|
|
8655
|
-
Object.fromEntries(
|
|
8656
|
-
Object.entries(schema.shape).filter(
|
|
8657
|
-
([name]) => !INTERNAL_CREATE_WORKFLOW_FIELDS.includes(
|
|
8658
|
-
name
|
|
8659
|
-
)
|
|
8660
|
-
)
|
|
8661
|
-
)
|
|
8662
|
-
);
|
|
8663
|
-
return schema.description === void 0 ? publicSchema : publicSchema.describe(schema.description);
|
|
8664
|
-
}
|
|
8665
|
-
var CreateWorkflowCliOptionsSchema = createPublicInputSchema(
|
|
8666
|
-
CreateWorkflowOptionsSchema
|
|
8667
|
-
);
|
|
8668
|
-
var createWorkflowCliPlugin = defineMethod$1({
|
|
8669
|
-
namespace: "cli",
|
|
8670
|
-
name: "createWorkflow",
|
|
8671
|
-
imports: [createWorkflowRef],
|
|
8672
|
-
type: "create",
|
|
8673
|
-
itemType: "Workflow",
|
|
8674
|
-
categories: ["code-workflow"],
|
|
8675
|
-
stability: "experimental",
|
|
8676
|
-
inputSchema: CreateWorkflowCliOptionsSchema,
|
|
8677
|
-
outputSchema: CreateWorkflowResponseSchema,
|
|
8678
|
-
skipOutputValidation: true,
|
|
8679
|
-
output: "raw",
|
|
8680
|
-
run: ({ imports, input }) => imports.createWorkflow({
|
|
8681
|
-
...input,
|
|
8682
|
-
creationHarness: getAgent(),
|
|
8683
|
-
creationAccessMethod: "sdk_cli"
|
|
8684
|
-
})
|
|
8685
|
-
});
|
|
8686
|
-
var importWorkflowRef = declareMethod$1({ id: "importWorkflow" });
|
|
8687
|
-
var importWorkflowCliPlugin = defineMethod$1({
|
|
8688
|
-
namespace: "cli",
|
|
8689
|
-
name: "importWorkflow",
|
|
8690
|
-
imports: [importWorkflowRef],
|
|
8691
|
-
type: "create",
|
|
8692
|
-
itemType: "Workflow",
|
|
8693
|
-
categories: ["code-workflow"],
|
|
8694
|
-
stability: "experimental",
|
|
8695
|
-
inputSchema: createPublicInputSchema(ImportWorkflowOptionsSchema),
|
|
8696
|
-
outputSchema: ImportWorkflowResponseSchema,
|
|
8697
|
-
skipOutputValidation: true,
|
|
8698
|
-
output: "raw",
|
|
8699
|
-
run: ({ imports, input }) => imports.importWorkflow({
|
|
8700
|
-
...input,
|
|
8701
|
-
creationHarness: getAgent(),
|
|
8702
|
-
creationAccessMethod: "sdk_cli"
|
|
8703
|
-
})
|
|
8704
|
-
});
|
|
8705
9119
|
var BOX_WIDTH = 72;
|
|
8706
9120
|
var BOX_TITLE = "ZAPIER SDK DEPRECATION NOTICE";
|
|
8707
9121
|
var activeNotices = /* @__PURE__ */ new Map();
|
|
@@ -8744,7 +9158,7 @@ function buildBoxLines(message) {
|
|
|
8744
9158
|
// package.json with { type: 'json' }
|
|
8745
9159
|
var package_default2 = {
|
|
8746
9160
|
name: "@zapier/zapier-sdk-cli",
|
|
8747
|
-
version: "0.
|
|
9161
|
+
version: "0.87.1"};
|
|
8748
9162
|
|
|
8749
9163
|
// src/sdk.ts
|
|
8750
9164
|
var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
|
|
@@ -8910,14 +9324,10 @@ function createZapierCliSdk3(options = {}) {
|
|
|
8910
9324
|
exports: [
|
|
8911
9325
|
omitExports$1(zapierExperimentalSdkPlugin, [
|
|
8912
9326
|
"drainTriggerInbox",
|
|
8913
|
-
"watchTriggerInbox"
|
|
8914
|
-
"createWorkflow",
|
|
8915
|
-
"importWorkflow"
|
|
9327
|
+
"watchTriggerInbox"
|
|
8916
9328
|
]),
|
|
8917
9329
|
drainTriggerInboxCliPlugin,
|
|
8918
9330
|
watchTriggerInboxCliPlugin,
|
|
8919
|
-
createWorkflowCliPlugin,
|
|
8920
|
-
importWorkflowCliPlugin,
|
|
8921
9331
|
loginPlugin,
|
|
8922
9332
|
signupPlugin,
|
|
8923
9333
|
logoutPlugin,
|