@zapier/zapier-sdk-cli 0.52.10 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/README.md +39 -1
- package/dist/cli.cjs +972 -473
- package/dist/cli.mjs +973 -474
- package/dist/experimental.cjs +914 -424
- package/dist/experimental.d.mts +1 -1
- package/dist/experimental.d.ts +1 -1
- package/dist/experimental.mjs +910 -420
- package/dist/index.cjs +914 -424
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +910 -420
- package/dist/login.cjs +8 -10
- package/dist/login.d.mts +2 -10
- package/dist/login.d.ts +2 -10
- package/dist/login.mjs +5 -9
- package/dist/package.json +1 -1
- package/dist/{sdk-B3nKAZdN.d.mts → sdk-SOLizjno.d.mts} +54 -16
- package/dist/{sdk-B3nKAZdN.d.ts → sdk-SOLizjno.d.ts} +54 -16
- package/dist/src/experimental.js +30 -27
- package/dist/src/login/index.d.ts +1 -9
- package/dist/src/login/index.js +12 -14
- package/dist/src/plugins/add/index.d.ts +15 -15
- package/dist/src/plugins/add/index.js +1 -1
- package/dist/src/plugins/buildManifest/index.d.ts +2 -2
- package/dist/src/plugins/bundleCode/index.d.ts +1 -1
- package/dist/src/plugins/bundleCode/index.js +2 -1
- package/dist/src/plugins/cliOverrides/index.d.ts +5 -10
- package/dist/src/plugins/cliOverrides/index.js +2 -6
- package/dist/src/plugins/curl/index.d.ts +2 -2
- package/dist/src/plugins/curl/schemas.d.ts +2 -2
- package/dist/src/plugins/feedback/index.d.ts +1 -1
- package/dist/src/plugins/generateAppTypes/index.d.ts +11 -11
- package/dist/src/plugins/getLoginConfigPath/index.d.ts +1 -1
- package/dist/src/plugins/index.d.ts +2 -1
- package/dist/src/plugins/index.js +2 -1
- package/dist/src/plugins/init/index.d.ts +1 -1
- package/dist/src/plugins/login/index.d.ts +3 -16
- package/dist/src/plugins/login/index.js +3 -191
- package/dist/src/plugins/logout/index.d.ts +1 -1
- package/dist/src/plugins/mcp/index.d.ts +1 -1
- package/dist/src/plugins/signup/index.d.ts +25 -0
- package/dist/src/plugins/signup/index.js +12 -0
- package/dist/src/plugins/signup/schemas.d.ts +9 -0
- package/dist/src/plugins/signup/schemas.js +26 -0
- package/dist/src/plugins/signup/test-harness.d.ts +34 -0
- package/dist/src/plugins/signup/test-harness.js +74 -0
- package/dist/src/sdk.js +32 -20
- package/dist/src/types/sdk.d.ts +2 -1
- package/dist/src/utils/auth/account-auth.d.ts +32 -0
- package/dist/src/utils/auth/account-auth.js +265 -0
- package/dist/src/utils/auth/oauth-callback.d.ts +6 -0
- package/dist/src/utils/auth/oauth-callback.js +28 -0
- package/dist/src/utils/auth/oauth-errors.d.ts +2 -0
- package/dist/src/utils/auth/oauth-errors.js +39 -0
- package/dist/src/utils/auth/oauth-flow.d.ts +31 -6
- package/dist/src/utils/auth/oauth-flow.js +258 -106
- package/dist/src/utils/auth/oauth-transaction.d.ts +35 -0
- package/dist/src/utils/auth/oauth-transaction.js +69 -0
- package/dist/src/utils/cli-generator.js +14 -7
- package/dist/src/utils/cli-renderer.d.ts +13 -3
- package/dist/src/utils/cli-renderer.js +27 -20
- package/dist/src/utils/log.js +9 -4
- package/dist/src/utils/non-interactive.d.ts +5 -4
- package/dist/src/utils/non-interactive.js +6 -5
- package/dist/src/utils/parameter-resolver.js +3 -1
- package/dist/src/utils/schema-formatter.d.ts +2 -2
- package/dist/src/utils/schema-formatter.js +4 -30
- package/dist/src/utils/version-checker.js +8 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
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,
|
|
4
|
+
import { definePlugin, createPluginMethod, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, ZapierReleaseTriggerMessageSignal, injectCliLogin, BaseSdkOptionsSchema, getOrCreateApiClient, invalidateCachedToken, batch, toSnakeCase, ZapierAbortDrainSignal, createZapierSdkStack as createZapierSdkStack$1, addPlugin as addPlugin$1, ZapierError, isCredentialsObject, buildApplicationLifecycleEvent, ZapierAuthenticationError, isPositional, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } 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, getKeyring, getPassword
|
|
12
|
+
import { deletePassword, setPassword, getKeyring, 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';
|
|
@@ -18,8 +18,9 @@ import * as path from 'path';
|
|
|
18
18
|
import { resolve, join, dirname, basename, relative, extname } from 'path';
|
|
19
19
|
import * as lockfile from 'proper-lockfile';
|
|
20
20
|
import { hostname } from 'os';
|
|
21
|
-
import open from 'open';
|
|
22
21
|
import express from 'express';
|
|
22
|
+
import { createInterface } from 'readline/promises';
|
|
23
|
+
import open from 'open';
|
|
23
24
|
import pkceChallenge from 'pkce-challenge';
|
|
24
25
|
import { startMcpServer } from '@zapier/zapier-sdk-mcp';
|
|
25
26
|
import { buildSync } from 'esbuild';
|
|
@@ -29,8 +30,8 @@ import isInstalledGlobally from 'is-installed-globally';
|
|
|
29
30
|
import { execSync, spawn } from 'child_process';
|
|
30
31
|
import Handlebars from 'handlebars';
|
|
31
32
|
import { fileURLToPath } from 'url';
|
|
32
|
-
import { injectCliLogin as injectCliLogin$1,
|
|
33
|
-
import packageJsonLib from 'package-json';
|
|
33
|
+
import { injectCliLogin as injectCliLogin$1, createZapierSdkStack, addPlugin } from '@zapier/zapier-sdk/experimental';
|
|
34
|
+
import packageJsonLib, { VersionNotFoundError } from 'package-json';
|
|
34
35
|
import semver from 'semver';
|
|
35
36
|
|
|
36
37
|
var __defProp = Object.defineProperty;
|
|
@@ -158,7 +159,7 @@ var SchemaParameterResolver = class {
|
|
|
158
159
|
debugLog(message) {
|
|
159
160
|
if (this.debug) {
|
|
160
161
|
this.stopSpinner();
|
|
161
|
-
console.
|
|
162
|
+
console.error(chalk.gray(`[Zapier CLI] ${message}`));
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
startSpinner() {
|
|
@@ -1530,7 +1531,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
1530
1531
|
|
|
1531
1532
|
// package.json
|
|
1532
1533
|
var package_default = {
|
|
1533
|
-
version: "0.
|
|
1534
|
+
version: "0.53.0"};
|
|
1534
1535
|
|
|
1535
1536
|
// src/telemetry/builders.ts
|
|
1536
1537
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1584,12 +1585,6 @@ function buildCliCommandExecutedEvent({
|
|
|
1584
1585
|
subprocess_count: data.subprocess_count ?? null
|
|
1585
1586
|
};
|
|
1586
1587
|
}
|
|
1587
|
-
function getFormatMetadata(schema) {
|
|
1588
|
-
return schema?._zod?.def?.formatMeta;
|
|
1589
|
-
}
|
|
1590
|
-
function getOutputSchema(schema) {
|
|
1591
|
-
return schema?._zod?.def?.outputSchema;
|
|
1592
|
-
}
|
|
1593
1588
|
function formatJsonOutput(data) {
|
|
1594
1589
|
if (data === void 0) {
|
|
1595
1590
|
return;
|
|
@@ -1598,21 +1593,26 @@ function formatJsonOutput(data) {
|
|
|
1598
1593
|
util.inspect(data, { colors: true, depth: null, breakLength: 80 })
|
|
1599
1594
|
);
|
|
1600
1595
|
}
|
|
1601
|
-
async function formatItemsFromSchema(
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1596
|
+
async function formatItemsFromSchema(_functionInfo, items, startingNumber = 0, options) {
|
|
1597
|
+
if (options?.formatter) {
|
|
1598
|
+
let context;
|
|
1599
|
+
if (options.formatter.fetch && options.sdk && options.params) {
|
|
1600
|
+
for (const item of items) {
|
|
1601
|
+
context = await options.formatter.fetch(
|
|
1602
|
+
options.sdk,
|
|
1603
|
+
options.params,
|
|
1604
|
+
item,
|
|
1605
|
+
context
|
|
1606
|
+
);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
items.forEach((item, index) => {
|
|
1610
|
+
const formatted = options.formatter.format(item, context);
|
|
1611
|
+
formatSingleItem(formatted, startingNumber + index);
|
|
1612
|
+
});
|
|
1610
1613
|
return;
|
|
1611
1614
|
}
|
|
1612
|
-
items
|
|
1613
|
-
const formatted = formatMeta.format(item);
|
|
1614
|
-
formatSingleItem(formatted, startingNumber + index);
|
|
1615
|
-
});
|
|
1615
|
+
formatItemsGeneric(items, startingNumber);
|
|
1616
1616
|
}
|
|
1617
1617
|
function formatSingleItem(formatted, itemNumber) {
|
|
1618
1618
|
let titleLine = `${chalk.gray(`${itemNumber + 1}.`)} ${chalk.cyan(formatted.title)}`;
|
|
@@ -1772,7 +1772,7 @@ function createJsonRenderer() {
|
|
|
1772
1772
|
errors: []
|
|
1773
1773
|
});
|
|
1774
1774
|
},
|
|
1775
|
-
renderCollectedList(items, _options) {
|
|
1775
|
+
async renderCollectedList(items, _options) {
|
|
1776
1776
|
outputJson({ data: items, errors: [] });
|
|
1777
1777
|
},
|
|
1778
1778
|
renderItem(value, options) {
|
|
@@ -1804,27 +1804,32 @@ function getListTitle(functionInfo) {
|
|
|
1804
1804
|
if (functionInfo.itemType) return `Available ${functionInfo.itemType} items`;
|
|
1805
1805
|
return "items";
|
|
1806
1806
|
}
|
|
1807
|
-
function
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`
|
|
1807
|
+
function createInteractiveRenderer(context = {}) {
|
|
1808
|
+
async function renderItemsForDisplay(items, functionInfo, startingNumber = 0) {
|
|
1809
|
+
if (functionInfo?.inputSchema) {
|
|
1810
|
+
await formatItemsFromSchema(
|
|
1811
|
+
functionInfo,
|
|
1812
|
+
items,
|
|
1813
|
+
startingNumber,
|
|
1814
|
+
{
|
|
1815
|
+
formatter: functionInfo.formatter,
|
|
1816
|
+
sdk: context.sdk,
|
|
1817
|
+
params: context.params
|
|
1818
|
+
}
|
|
1820
1819
|
);
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1820
|
+
} else {
|
|
1821
|
+
items.forEach((item, index) => {
|
|
1822
|
+
const obj = item;
|
|
1823
|
+
const name = obj?.name || obj?.key || obj?.id || "Item";
|
|
1824
|
+
console.log(
|
|
1825
|
+
`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`
|
|
1826
|
+
);
|
|
1827
|
+
if (obj?.description)
|
|
1828
|
+
console.log(` ${chalk.dim(String(obj.description))}`);
|
|
1829
|
+
console.log();
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1825
1832
|
}
|
|
1826
|
-
}
|
|
1827
|
-
function createInteractiveRenderer() {
|
|
1828
1833
|
return {
|
|
1829
1834
|
async renderPaginatedList(source, functionInfo) {
|
|
1830
1835
|
const itemName = getItemName(functionInfo);
|
|
@@ -1834,7 +1839,7 @@ function createInteractiveRenderer() {
|
|
|
1834
1839
|
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
1835
1840
|
return;
|
|
1836
1841
|
}
|
|
1837
|
-
renderItemsForDisplay(items, functionInfo, 0);
|
|
1842
|
+
await renderItemsForDisplay(items, functionInfo, 0);
|
|
1838
1843
|
console.log(chalk.green(`
|
|
1839
1844
|
\u2705 Showing ${items.length} ${itemName}`));
|
|
1840
1845
|
return;
|
|
@@ -1856,7 +1861,7 @@ function createInteractiveRenderer() {
|
|
|
1856
1861
|
console.log(chalk.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
|
|
1857
1862
|
`));
|
|
1858
1863
|
}
|
|
1859
|
-
renderItemsForDisplay(items, functionInfo, totalShown);
|
|
1864
|
+
await renderItemsForDisplay(items, functionInfo, totalShown);
|
|
1860
1865
|
totalShown += items.length;
|
|
1861
1866
|
console.log(
|
|
1862
1867
|
chalk.green(
|
|
@@ -1881,7 +1886,7 @@ function createInteractiveRenderer() {
|
|
|
1881
1886
|
console.log(chalk.gray(`
|
|
1882
1887
|
\u{1F4C4} Finished browsing ${itemName}`));
|
|
1883
1888
|
},
|
|
1884
|
-
renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
|
|
1889
|
+
async renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
|
|
1885
1890
|
if (!Array.isArray(items)) {
|
|
1886
1891
|
formatJsonOutput(items);
|
|
1887
1892
|
return;
|
|
@@ -1894,7 +1899,7 @@ function createInteractiveRenderer() {
|
|
|
1894
1899
|
console.log(chalk.green(`
|
|
1895
1900
|
\u2705 Found ${items.length} ${itemName}:
|
|
1896
1901
|
`));
|
|
1897
|
-
renderItemsForDisplay(items, functionInfo);
|
|
1902
|
+
await renderItemsForDisplay(items, functionInfo);
|
|
1898
1903
|
if (userSpecifiedMaxItems && maxItems) {
|
|
1899
1904
|
console.log(
|
|
1900
1905
|
chalk.gray(
|
|
@@ -2357,11 +2362,11 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2357
2362
|
const startTime = Date.now();
|
|
2358
2363
|
let success = true;
|
|
2359
2364
|
let errorMessage = null;
|
|
2360
|
-
|
|
2365
|
+
const resolvedParams = {};
|
|
2361
2366
|
const commandObj = args[args.length - 1];
|
|
2362
2367
|
const options = commandObj.opts();
|
|
2363
2368
|
const interactiveMode = !options.json;
|
|
2364
|
-
const renderer = interactiveMode ? createInteractiveRenderer() : createJsonRenderer();
|
|
2369
|
+
const renderer = interactiveMode ? createInteractiveRenderer({ sdk, params: resolvedParams }) : createJsonRenderer();
|
|
2365
2370
|
try {
|
|
2366
2371
|
emitDeprecationWarning({
|
|
2367
2372
|
cliCommandName,
|
|
@@ -2394,7 +2399,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2394
2399
|
}
|
|
2395
2400
|
if (schema && !usesInputParameters) {
|
|
2396
2401
|
const resolver = new SchemaParameterResolver();
|
|
2397
|
-
|
|
2402
|
+
const resolved = await resolver.resolveParameters(
|
|
2398
2403
|
schema,
|
|
2399
2404
|
rawParams,
|
|
2400
2405
|
sdk,
|
|
@@ -2404,8 +2409,9 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2404
2409
|
debug: !!options.debug || process.env.DEBUG === "true" || process.argv.includes("--debug")
|
|
2405
2410
|
}
|
|
2406
2411
|
);
|
|
2412
|
+
Object.assign(resolvedParams, resolved);
|
|
2407
2413
|
} else {
|
|
2408
|
-
resolvedParams
|
|
2414
|
+
Object.assign(resolvedParams, rawParams);
|
|
2409
2415
|
}
|
|
2410
2416
|
const confirm = functionInfo.confirm;
|
|
2411
2417
|
let confirmMessageAfter;
|
|
@@ -2434,7 +2440,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2434
2440
|
sdkResult,
|
|
2435
2441
|
maxItems
|
|
2436
2442
|
});
|
|
2437
|
-
renderer.renderCollectedList(allItems, {
|
|
2443
|
+
await renderer.renderCollectedList(allItems, {
|
|
2438
2444
|
maxItems,
|
|
2439
2445
|
userSpecifiedMaxItems: hasUserSpecifiedMaxItems,
|
|
2440
2446
|
functionInfo
|
|
@@ -2468,7 +2474,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2468
2474
|
if (normalizedResult.kind === "response") {
|
|
2469
2475
|
await renderer.renderResponse(normalizedResult.value);
|
|
2470
2476
|
} else if (normalizedResult.kind === "list") {
|
|
2471
|
-
renderer.renderCollectedList(normalizedResult.data, {
|
|
2477
|
+
await renderer.renderCollectedList(normalizedResult.data, {
|
|
2472
2478
|
maxItems: resolvedParams.maxItems,
|
|
2473
2479
|
userSpecifiedMaxItems: hasUserSpecifiedMaxItems,
|
|
2474
2480
|
functionInfo
|
|
@@ -2524,7 +2530,7 @@ ${confirmMessageAfter}`));
|
|
|
2524
2530
|
description,
|
|
2525
2531
|
parameters,
|
|
2526
2532
|
handler,
|
|
2527
|
-
hidden: functionInfo.
|
|
2533
|
+
hidden: !!functionInfo.deprecation,
|
|
2528
2534
|
aliases: functionInfo.aliases,
|
|
2529
2535
|
supportsJsonOutput: functionInfo.supportsJsonOutput
|
|
2530
2536
|
};
|
|
@@ -3087,12 +3093,6 @@ async function deleteStoredClientCredentials({
|
|
|
3087
3093
|
}
|
|
3088
3094
|
|
|
3089
3095
|
// src/login/index.ts
|
|
3090
|
-
var ZapierAuthenticationError = class extends Error {
|
|
3091
|
-
constructor(message) {
|
|
3092
|
-
super(message);
|
|
3093
|
-
this.name = "ZapierAuthenticationError";
|
|
3094
|
-
}
|
|
3095
|
-
};
|
|
3096
3096
|
var DEFAULT_AUTH_CLIENT_ID = "grwWZD5hUWGvb4V8ODBuOtXer3h0DBEZ2HR8aay6";
|
|
3097
3097
|
var TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
3098
3098
|
function createDebugLog(enabled) {
|
|
@@ -3102,9 +3102,9 @@ function createDebugLog(enabled) {
|
|
|
3102
3102
|
}
|
|
3103
3103
|
return (message, data) => {
|
|
3104
3104
|
if (data === void 0) {
|
|
3105
|
-
console.
|
|
3105
|
+
console.error(`[Zapier SDK CLI Login] ${message}`);
|
|
3106
3106
|
} else {
|
|
3107
|
-
console.
|
|
3107
|
+
console.error(`[Zapier SDK CLI Login] ${message}`, data);
|
|
3108
3108
|
}
|
|
3109
3109
|
};
|
|
3110
3110
|
}
|
|
@@ -3503,45 +3503,186 @@ async function revokeCredentials({
|
|
|
3503
3503
|
});
|
|
3504
3504
|
emitAuthLogout(onEvent);
|
|
3505
3505
|
}
|
|
3506
|
+
function getBaseUrlFromResolvedCredentials(credentials2) {
|
|
3507
|
+
if (credentials2 && isCredentialsObject(credentials2)) {
|
|
3508
|
+
return credentials2.baseUrl;
|
|
3509
|
+
}
|
|
3510
|
+
return void 0;
|
|
3511
|
+
}
|
|
3512
|
+
function getBaseUrlFromOptionsCredentials(credentials2) {
|
|
3513
|
+
if (credentials2 && typeof credentials2 === "object" && "baseUrl" in credentials2 && typeof credentials2.baseUrl === "string") {
|
|
3514
|
+
return credentials2.baseUrl;
|
|
3515
|
+
}
|
|
3516
|
+
return void 0;
|
|
3517
|
+
}
|
|
3518
|
+
async function resolveCredentialsBaseUrl(context) {
|
|
3519
|
+
const resolvedCredentials = "resolvedCredentials" in context ? context.resolvedCredentials : await context.resolveCredentials?.();
|
|
3520
|
+
return getBaseUrlFromResolvedCredentials(resolvedCredentials) ?? getBaseUrlFromOptionsCredentials(context.options?.credentials) ?? context.options?.baseUrl;
|
|
3521
|
+
}
|
|
3506
3522
|
|
|
3507
|
-
// src/utils/
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3523
|
+
// src/utils/non-interactive.ts
|
|
3524
|
+
function resolveNonInteractive(options) {
|
|
3525
|
+
return options.nonInteractive === true || options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3528
|
+
// src/utils/auth/client-credentials.ts
|
|
3529
|
+
var CREDENTIALS_SCOPES = ["external", "credentials"];
|
|
3530
|
+
var EMPTY_POLICY = {
|
|
3531
|
+
version: 2,
|
|
3532
|
+
statements: []
|
|
3533
|
+
};
|
|
3534
|
+
async function createCredentialsOnServer(api2, name, policy) {
|
|
3535
|
+
const response = await api2.post(
|
|
3536
|
+
"/api/v0/client-credentials",
|
|
3537
|
+
{
|
|
3538
|
+
name,
|
|
3539
|
+
allowed_scopes: CREDENTIALS_SCOPES,
|
|
3540
|
+
...policy !== void 0 && { policy }
|
|
3541
|
+
},
|
|
3542
|
+
{ authRequired: true, requiredScopes: ["credentials"] }
|
|
3543
|
+
);
|
|
3544
|
+
return {
|
|
3545
|
+
clientId: response.data.client_id,
|
|
3546
|
+
clientSecret: response.data.client_secret
|
|
3547
|
+
};
|
|
3548
|
+
}
|
|
3549
|
+
async function deleteCredentialsOnServer(api2, clientId) {
|
|
3550
|
+
await api2.delete(`/api/v0/client-credentials/${clientId}`, void 0, {
|
|
3551
|
+
authRequired: true,
|
|
3552
|
+
requiredScopes: ["credentials"]
|
|
3553
|
+
});
|
|
3554
|
+
}
|
|
3555
|
+
async function setupClientCredentials({
|
|
3556
|
+
api: api2,
|
|
3557
|
+
name,
|
|
3558
|
+
credentialsBaseUrl: credentialsBaseUrl2,
|
|
3559
|
+
policy
|
|
3560
|
+
}) {
|
|
3561
|
+
const { clientId, clientSecret } = await createCredentialsOnServer(
|
|
3562
|
+
api2,
|
|
3563
|
+
name,
|
|
3564
|
+
policy
|
|
3565
|
+
);
|
|
3512
3566
|
try {
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3567
|
+
await withRetry({
|
|
3568
|
+
action: () => storeClientCredentials({
|
|
3569
|
+
name,
|
|
3570
|
+
clientId,
|
|
3571
|
+
clientSecret,
|
|
3572
|
+
scopes: [...CREDENTIALS_SCOPES],
|
|
3573
|
+
baseUrl: credentialsBaseUrl2
|
|
3574
|
+
})
|
|
3575
|
+
});
|
|
3576
|
+
} catch (storeErr) {
|
|
3577
|
+
try {
|
|
3578
|
+
await withRetry({
|
|
3579
|
+
action: () => deleteCredentialsOnServer(api2, clientId)
|
|
3580
|
+
});
|
|
3581
|
+
} catch {
|
|
3582
|
+
console.error(
|
|
3583
|
+
`Failed to roll back orphaned credential ${clientId}. Delete it manually with: zapier-sdk delete-client-credentials ${clientId}`
|
|
3584
|
+
);
|
|
3521
3585
|
}
|
|
3522
|
-
throw
|
|
3586
|
+
throw storeErr;
|
|
3523
3587
|
}
|
|
3588
|
+
return { clientId };
|
|
3589
|
+
}
|
|
3590
|
+
|
|
3591
|
+
// src/utils/constants.ts
|
|
3592
|
+
var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
3593
|
+
var LOGIN_TIMEOUT_MS = 3e5;
|
|
3594
|
+
|
|
3595
|
+
// src/utils/getCallablePromise.ts
|
|
3596
|
+
var getCallablePromise = () => {
|
|
3597
|
+
let resolve4 = () => {
|
|
3598
|
+
};
|
|
3599
|
+
let reject = () => {
|
|
3600
|
+
};
|
|
3601
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
3602
|
+
resolve4 = _resolve;
|
|
3603
|
+
reject = _reject;
|
|
3604
|
+
});
|
|
3605
|
+
return {
|
|
3606
|
+
promise,
|
|
3607
|
+
resolve: resolve4,
|
|
3608
|
+
reject
|
|
3609
|
+
};
|
|
3524
3610
|
};
|
|
3611
|
+
var getCallablePromise_default = getCallablePromise;
|
|
3525
3612
|
var log = {
|
|
3526
3613
|
info: (message, ...args) => {
|
|
3527
|
-
console.
|
|
3614
|
+
console.error(chalk.blue("\u2139"), message, ...args);
|
|
3528
3615
|
},
|
|
3529
3616
|
error: (message, ...args) => {
|
|
3530
3617
|
console.error(chalk.red("\u2716"), message, ...args);
|
|
3531
3618
|
},
|
|
3532
3619
|
success: (message, ...args) => {
|
|
3533
|
-
console.
|
|
3620
|
+
console.error(chalk.green("\u2713"), message, ...args);
|
|
3534
3621
|
},
|
|
3535
3622
|
warn: (message, ...args) => {
|
|
3536
|
-
console.
|
|
3623
|
+
console.error(chalk.yellow("\u26A0"), message, ...args);
|
|
3537
3624
|
},
|
|
3538
3625
|
debug: (message, ...args) => {
|
|
3539
3626
|
if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
|
|
3540
|
-
console.
|
|
3627
|
+
console.error(chalk.gray("\u{1F41B}"), message, ...args);
|
|
3541
3628
|
}
|
|
3542
3629
|
}
|
|
3543
3630
|
};
|
|
3544
3631
|
var log_default = log;
|
|
3632
|
+
var spinPromise = async (promise, text) => {
|
|
3633
|
+
const spinner = ora(text).start();
|
|
3634
|
+
try {
|
|
3635
|
+
const result = await promise;
|
|
3636
|
+
spinner.succeed();
|
|
3637
|
+
return result;
|
|
3638
|
+
} catch (error) {
|
|
3639
|
+
if (error instanceof ZapierCliUserCancellationError) {
|
|
3640
|
+
spinner.stop();
|
|
3641
|
+
} else {
|
|
3642
|
+
spinner.fail();
|
|
3643
|
+
}
|
|
3644
|
+
throw error;
|
|
3645
|
+
}
|
|
3646
|
+
};
|
|
3647
|
+
|
|
3648
|
+
// src/utils/auth/oauth-callback.ts
|
|
3649
|
+
function getCallbackCode({
|
|
3650
|
+
callbackUrl,
|
|
3651
|
+
transaction,
|
|
3652
|
+
recoveryMessage
|
|
3653
|
+
}) {
|
|
3654
|
+
let parsed;
|
|
3655
|
+
try {
|
|
3656
|
+
parsed = new URL(callbackUrl.trim());
|
|
3657
|
+
} catch {
|
|
3658
|
+
throw new ZapierCliValidationError(
|
|
3659
|
+
"Paste the final OAuth callback URL from your browser."
|
|
3660
|
+
);
|
|
3661
|
+
}
|
|
3662
|
+
const expected = new URL(transaction.redirectUri);
|
|
3663
|
+
if (parsed.protocol !== "http:" || parsed.hostname !== expected.hostname || parsed.pathname !== expected.pathname || parsed.port !== expected.port) {
|
|
3664
|
+
throw new ZapierCliValidationError(
|
|
3665
|
+
`Expected the final OAuth callback URL to start with ${transaction.redirectUri}.`
|
|
3666
|
+
);
|
|
3667
|
+
}
|
|
3668
|
+
if (parsed.searchParams.get("state") !== transaction.state) {
|
|
3669
|
+
throw new ZapierCliValidationError(
|
|
3670
|
+
`OAuth state mismatch.${recoveryMessage ? ` ${recoveryMessage}` : ""}`
|
|
3671
|
+
);
|
|
3672
|
+
}
|
|
3673
|
+
if (parsed.searchParams.has("error")) {
|
|
3674
|
+
throw new ZapierCliValidationError(
|
|
3675
|
+
`Authorization denied: ${parsed.searchParams.get("error_description") ?? parsed.searchParams.get("error")}.${recoveryMessage ? ` ${recoveryMessage}` : ""}`
|
|
3676
|
+
);
|
|
3677
|
+
}
|
|
3678
|
+
const code = parsed.searchParams.get("code");
|
|
3679
|
+
if (!code) {
|
|
3680
|
+
throw new ZapierCliValidationError(
|
|
3681
|
+
"No authorization code found in the pasted callback URL."
|
|
3682
|
+
);
|
|
3683
|
+
}
|
|
3684
|
+
return code;
|
|
3685
|
+
}
|
|
3545
3686
|
|
|
3546
3687
|
// src/utils/api/client.ts
|
|
3547
3688
|
var createApiClient = () => {
|
|
@@ -3572,179 +3713,77 @@ var createApiClient = () => {
|
|
|
3572
3713
|
var api = createApiClient();
|
|
3573
3714
|
var client_default = api;
|
|
3574
3715
|
|
|
3575
|
-
// src/utils/
|
|
3576
|
-
var
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
}
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
// src/utils/auth/oauth-flow.ts
|
|
3594
|
-
var findAvailablePort = () => {
|
|
3595
|
-
return new Promise((resolve4, reject) => {
|
|
3596
|
-
let portIndex = 0;
|
|
3597
|
-
const tryPort = (port) => {
|
|
3598
|
-
const server = express().listen(port, () => {
|
|
3599
|
-
server.close();
|
|
3600
|
-
resolve4(port);
|
|
3601
|
-
});
|
|
3602
|
-
server.on("error", (err) => {
|
|
3603
|
-
if (err.code === "EADDRINUSE") {
|
|
3604
|
-
if (portIndex < LOGIN_PORTS.length) {
|
|
3605
|
-
tryPort(LOGIN_PORTS[portIndex++]);
|
|
3606
|
-
} else {
|
|
3607
|
-
reject(
|
|
3608
|
-
new Error(
|
|
3609
|
-
`All configured OAuth callback ports are busy: ${LOGIN_PORTS.join(", ")}. Please try again later or close applications using these ports.`
|
|
3610
|
-
)
|
|
3611
|
-
);
|
|
3612
|
-
}
|
|
3613
|
-
} else {
|
|
3614
|
-
reject(err);
|
|
3615
|
-
}
|
|
3616
|
-
});
|
|
3617
|
-
};
|
|
3618
|
-
if (LOGIN_PORTS.length > 0) {
|
|
3619
|
-
tryPort(LOGIN_PORTS[portIndex++]);
|
|
3620
|
-
} else {
|
|
3621
|
-
reject(new Error("No OAuth callback ports configured"));
|
|
3622
|
-
}
|
|
3623
|
-
});
|
|
3624
|
-
};
|
|
3625
|
-
var generateRandomString = () => {
|
|
3716
|
+
// src/utils/auth/oauth-transaction.ts
|
|
3717
|
+
var OAUTH_LOOPBACK_HOST = "localhost";
|
|
3718
|
+
function buildBrowserAuthUrl({
|
|
3719
|
+
authorizeUrl,
|
|
3720
|
+
entryPoint = "login"
|
|
3721
|
+
}) {
|
|
3722
|
+
if (entryPoint === "login") return authorizeUrl;
|
|
3723
|
+
const parsedAuthorizeUrl = new URL(authorizeUrl);
|
|
3724
|
+
const signupUrl = new URL("/sign-up", parsedAuthorizeUrl);
|
|
3725
|
+
signupUrl.searchParams.set("skipOnboarding", "true");
|
|
3726
|
+
signupUrl.searchParams.set(
|
|
3727
|
+
"next",
|
|
3728
|
+
`${parsedAuthorizeUrl.pathname}${parsedAuthorizeUrl.search}`
|
|
3729
|
+
);
|
|
3730
|
+
return signupUrl.toString();
|
|
3731
|
+
}
|
|
3732
|
+
function generateRandomString() {
|
|
3626
3733
|
const array = new Uint32Array(28);
|
|
3627
3734
|
crypto.getRandomValues(array);
|
|
3628
3735
|
return Array.from(array, (dec) => ("0" + dec.toString(16)).slice(-2)).join(
|
|
3629
3736
|
""
|
|
3630
3737
|
);
|
|
3631
|
-
}
|
|
3738
|
+
}
|
|
3632
3739
|
function ensureOfflineAccess(scope) {
|
|
3633
|
-
if (scope.includes("offline_access"))
|
|
3634
|
-
return scope;
|
|
3635
|
-
}
|
|
3740
|
+
if (scope.includes("offline_access")) return scope;
|
|
3636
3741
|
return `${scope} offline_access`;
|
|
3637
3742
|
}
|
|
3638
|
-
async function
|
|
3639
|
-
timeoutMs = LOGIN_TIMEOUT_MS,
|
|
3743
|
+
async function prepareOauthTransaction({
|
|
3640
3744
|
pkceCredentials,
|
|
3641
|
-
baseUrl: baseUrl2
|
|
3745
|
+
baseUrl: baseUrl2,
|
|
3746
|
+
redirectUri,
|
|
3747
|
+
entryPoint = "login"
|
|
3642
3748
|
}) {
|
|
3643
3749
|
const { clientId, tokenUrl, authorizeUrl } = getPkceLoginConfig({
|
|
3644
3750
|
credentials: pkceCredentials,
|
|
3645
3751
|
baseUrl: baseUrl2
|
|
3646
3752
|
});
|
|
3647
|
-
const scope = ensureOfflineAccess(
|
|
3648
|
-
pkceCredentials?.scope || "internal credentials"
|
|
3649
|
-
);
|
|
3650
|
-
const availablePort = await findAvailablePort();
|
|
3651
|
-
const redirectUri = `http://localhost:${availablePort}/oauth`;
|
|
3652
|
-
log_default.info(`Using port ${availablePort} for OAuth callback`);
|
|
3653
|
-
const {
|
|
3654
|
-
promise: promisedCode,
|
|
3655
|
-
resolve: setCode,
|
|
3656
|
-
reject: rejectCode
|
|
3657
|
-
} = getCallablePromise_default();
|
|
3658
|
-
const oauthState = generateRandomString();
|
|
3659
|
-
const expressApp = express();
|
|
3660
|
-
expressApp.get("/oauth", (req, res) => {
|
|
3661
|
-
res.setHeader("Connection", "close");
|
|
3662
|
-
if (req.query.state !== oauthState) {
|
|
3663
|
-
rejectCode(new Error("OAuth state mismatch \u2014 possible CSRF"));
|
|
3664
|
-
res.status(400).end("Invalid state. You can close this tab.");
|
|
3665
|
-
return;
|
|
3666
|
-
}
|
|
3667
|
-
if (req.query.error) {
|
|
3668
|
-
const desc = req.query.error_description ?? req.query.error;
|
|
3669
|
-
rejectCode(new Error(`Authorization denied: ${desc}`));
|
|
3670
|
-
res.end("Authorization was denied. You can close this tab.");
|
|
3671
|
-
return;
|
|
3672
|
-
}
|
|
3673
|
-
if (!req.query.code) {
|
|
3674
|
-
rejectCode(new Error("No authorization code received"));
|
|
3675
|
-
res.end("No authorization code received. You can close this tab.");
|
|
3676
|
-
return;
|
|
3677
|
-
}
|
|
3678
|
-
setCode(String(req.query.code));
|
|
3679
|
-
res.end("You can now close this tab and return to the CLI.");
|
|
3680
|
-
});
|
|
3681
|
-
const server = expressApp.listen(availablePort);
|
|
3682
|
-
const connections = /* @__PURE__ */ new Set();
|
|
3683
|
-
server.on("connection", (conn) => {
|
|
3684
|
-
connections.add(conn);
|
|
3685
|
-
conn.on("close", () => connections.delete(conn));
|
|
3686
|
-
});
|
|
3687
|
-
const cleanup = () => {
|
|
3688
|
-
server.close();
|
|
3689
|
-
log_default.info("\n\u274C Login cancelled by user");
|
|
3690
|
-
rejectCode(new ZapierCliUserCancellationError());
|
|
3691
|
-
};
|
|
3692
|
-
process.on("SIGINT", cleanup);
|
|
3693
|
-
process.on("SIGTERM", cleanup);
|
|
3694
3753
|
const { code_verifier: codeVerifier, code_challenge: codeChallenge } = await pkceChallenge();
|
|
3754
|
+
const state = generateRandomString();
|
|
3695
3755
|
const authUrl = `${authorizeUrl}?${new URLSearchParams({
|
|
3696
3756
|
response_type: "code",
|
|
3697
3757
|
client_id: clientId,
|
|
3698
3758
|
redirect_uri: redirectUri,
|
|
3699
|
-
scope
|
|
3700
|
-
|
|
3759
|
+
scope: ensureOfflineAccess(
|
|
3760
|
+
pkceCredentials?.scope || "internal credentials"
|
|
3761
|
+
),
|
|
3762
|
+
state,
|
|
3701
3763
|
code_challenge: codeChallenge,
|
|
3702
3764
|
code_challenge_method: "S256"
|
|
3703
3765
|
}).toString()}`;
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
})
|
|
3721
|
-
]),
|
|
3722
|
-
"Waiting for you to login and authorize"
|
|
3723
|
-
);
|
|
3724
|
-
} finally {
|
|
3725
|
-
if (timeoutTimer) {
|
|
3726
|
-
clearTimeout(timeoutTimer);
|
|
3727
|
-
}
|
|
3728
|
-
process.off("SIGINT", cleanup);
|
|
3729
|
-
process.off("SIGTERM", cleanup);
|
|
3730
|
-
await new Promise((resolve4) => {
|
|
3731
|
-
const timeout = setTimeout(() => {
|
|
3732
|
-
log_default.info("Server close timed out, forcing connection shutdown...");
|
|
3733
|
-
connections.forEach((conn) => conn.destroy());
|
|
3734
|
-
resolve4();
|
|
3735
|
-
}, 1e3);
|
|
3736
|
-
server.close(() => {
|
|
3737
|
-
clearTimeout(timeout);
|
|
3738
|
-
resolve4();
|
|
3739
|
-
});
|
|
3740
|
-
});
|
|
3741
|
-
}
|
|
3742
|
-
log_default.info("Exchanging authorization code for tokens...");
|
|
3766
|
+
return {
|
|
3767
|
+
browserAuthUrl: buildBrowserAuthUrl({ authorizeUrl: authUrl, entryPoint }),
|
|
3768
|
+
clientId,
|
|
3769
|
+
codeVerifier,
|
|
3770
|
+
redirectUri,
|
|
3771
|
+
state,
|
|
3772
|
+
tokenUrl
|
|
3773
|
+
};
|
|
3774
|
+
}
|
|
3775
|
+
async function exchangeOauthCode({
|
|
3776
|
+
tokenUrl,
|
|
3777
|
+
code,
|
|
3778
|
+
redirectUri,
|
|
3779
|
+
clientId,
|
|
3780
|
+
codeVerifier
|
|
3781
|
+
}) {
|
|
3743
3782
|
const { data } = await client_default.post(
|
|
3744
3783
|
tokenUrl,
|
|
3745
3784
|
{
|
|
3746
3785
|
grant_type: "authorization_code",
|
|
3747
|
-
code
|
|
3786
|
+
code,
|
|
3748
3787
|
redirect_uri: redirectUri,
|
|
3749
3788
|
client_id: clientId,
|
|
3750
3789
|
code_verifier: codeVerifier
|
|
@@ -3756,7 +3795,6 @@ async function runOauthFlow({
|
|
|
3756
3795
|
}
|
|
3757
3796
|
}
|
|
3758
3797
|
);
|
|
3759
|
-
log_default.info("Token exchange completed successfully");
|
|
3760
3798
|
return {
|
|
3761
3799
|
accessToken: data.access_token,
|
|
3762
3800
|
refreshToken: data.refresh_token,
|
|
@@ -3764,105 +3802,467 @@ async function runOauthFlow({
|
|
|
3764
3802
|
};
|
|
3765
3803
|
}
|
|
3766
3804
|
|
|
3767
|
-
// src/utils/auth/
|
|
3768
|
-
var
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3805
|
+
// src/utils/auth/oauth-flow.ts
|
|
3806
|
+
var OauthFlowTimeoutError = class extends Error {
|
|
3807
|
+
constructor(timeoutMs) {
|
|
3808
|
+
super("OAuth flow timed out");
|
|
3809
|
+
this.timeoutMs = timeoutMs;
|
|
3810
|
+
this.name = "OauthFlowTimeoutError";
|
|
3811
|
+
}
|
|
3772
3812
|
};
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
"
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3813
|
+
var OauthAuthorizationDeniedError = class extends Error {
|
|
3814
|
+
constructor(reason) {
|
|
3815
|
+
super("OAuth authorization denied");
|
|
3816
|
+
this.reason = reason;
|
|
3817
|
+
this.name = "OauthAuthorizationDeniedError";
|
|
3818
|
+
}
|
|
3819
|
+
};
|
|
3820
|
+
function findAvailablePort() {
|
|
3821
|
+
return new Promise((resolve4, reject) => {
|
|
3822
|
+
let portIndex = 0;
|
|
3823
|
+
const tryPort = (port) => {
|
|
3824
|
+
const server = express().listen(port, OAUTH_LOOPBACK_HOST, () => {
|
|
3825
|
+
server.close();
|
|
3826
|
+
resolve4(port);
|
|
3827
|
+
});
|
|
3828
|
+
server.on("error", (err) => {
|
|
3829
|
+
if (err.code === "EADDRINUSE" && portIndex < LOGIN_PORTS.length) {
|
|
3830
|
+
tryPort(LOGIN_PORTS[portIndex++]);
|
|
3831
|
+
} else if (err.code === "EADDRINUSE") {
|
|
3832
|
+
reject(
|
|
3833
|
+
new Error(
|
|
3834
|
+
`All configured OAuth callback ports are busy: ${LOGIN_PORTS.join(", ")}. Please try again later or close applications using these ports.`
|
|
3835
|
+
)
|
|
3836
|
+
);
|
|
3837
|
+
} else {
|
|
3838
|
+
reject(err);
|
|
3839
|
+
}
|
|
3840
|
+
});
|
|
3841
|
+
};
|
|
3842
|
+
if (LOGIN_PORTS.length > 0) tryPort(LOGIN_PORTS[portIndex++]);
|
|
3843
|
+
else reject(new Error("No OAuth callback ports configured"));
|
|
3844
|
+
});
|
|
3787
3845
|
}
|
|
3788
|
-
async function
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3846
|
+
async function runLoginOauthFlow(options) {
|
|
3847
|
+
return runOauthFlowEntryPoint({
|
|
3848
|
+
...options,
|
|
3849
|
+
entryPoint: "login",
|
|
3850
|
+
authAction: "log in",
|
|
3851
|
+
flowName: "Login"
|
|
3792
3852
|
});
|
|
3793
3853
|
}
|
|
3794
|
-
async function
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3854
|
+
async function runSignupOauthFlow(options) {
|
|
3855
|
+
if (options.headless) {
|
|
3856
|
+
return runOauthFlowEntryPoint({
|
|
3857
|
+
...options,
|
|
3858
|
+
entryPoint: "signup",
|
|
3859
|
+
authAction: "sign up",
|
|
3860
|
+
flowName: "Signup",
|
|
3861
|
+
headless: true
|
|
3862
|
+
});
|
|
3863
|
+
}
|
|
3864
|
+
return runOauthFlowEntryPoint({
|
|
3865
|
+
...options,
|
|
3866
|
+
entryPoint: "signup",
|
|
3867
|
+
authAction: "sign up",
|
|
3868
|
+
flowName: "Signup"
|
|
3869
|
+
});
|
|
3870
|
+
}
|
|
3871
|
+
async function runOauthFlowEntryPoint({
|
|
3872
|
+
flowName,
|
|
3873
|
+
...options
|
|
3799
3874
|
}) {
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3875
|
+
try {
|
|
3876
|
+
return options.headless ? await runHeadlessSignupOauthFlow(options) : await runOauthFlow(options);
|
|
3877
|
+
} catch (error) {
|
|
3878
|
+
if (error instanceof OauthFlowTimeoutError) {
|
|
3879
|
+
throw new Error(
|
|
3880
|
+
withRecoveryMessage(
|
|
3881
|
+
`${flowName} timed out after ${Math.round(error.timeoutMs / 1e3)} seconds.`,
|
|
3882
|
+
options.recoveryMessage
|
|
3883
|
+
)
|
|
3884
|
+
);
|
|
3885
|
+
}
|
|
3886
|
+
if (error instanceof OauthAuthorizationDeniedError) {
|
|
3887
|
+
throw new Error(
|
|
3888
|
+
withRecoveryMessage(
|
|
3889
|
+
`Authorization denied: ${error.reason}.`,
|
|
3890
|
+
options.recoveryMessage
|
|
3891
|
+
)
|
|
3892
|
+
);
|
|
3893
|
+
}
|
|
3894
|
+
if (error instanceof ZapierCliUserCancellationError && !options.silent) {
|
|
3895
|
+
log_default.info(`
|
|
3896
|
+
\u274C ${flowName} cancelled by user`);
|
|
3897
|
+
}
|
|
3898
|
+
throw error;
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
function withRecoveryMessage(message, recoveryMessage) {
|
|
3902
|
+
return recoveryMessage ? `${message} ${recoveryMessage}` : message;
|
|
3903
|
+
}
|
|
3904
|
+
async function runOauthFlow({
|
|
3905
|
+
timeoutMs = LOGIN_TIMEOUT_MS,
|
|
3906
|
+
pkceCredentials,
|
|
3907
|
+
baseUrl: baseUrl2,
|
|
3908
|
+
entryPoint,
|
|
3909
|
+
authAction,
|
|
3910
|
+
silent = false,
|
|
3911
|
+
onProgress
|
|
3912
|
+
}) {
|
|
3913
|
+
const port = await findAvailablePort();
|
|
3914
|
+
if (!silent) log_default.info(`Using port ${port} for OAuth callback`);
|
|
3915
|
+
const transaction = await prepareOauthTransaction({
|
|
3916
|
+
pkceCredentials,
|
|
3917
|
+
baseUrl: baseUrl2,
|
|
3918
|
+
redirectUri: `http://${OAUTH_LOOPBACK_HOST}:${port}/oauth`,
|
|
3919
|
+
entryPoint
|
|
3920
|
+
});
|
|
3921
|
+
const code = await collectLocalCallbackCode({
|
|
3922
|
+
transaction,
|
|
3923
|
+
timeoutMs,
|
|
3924
|
+
authAction,
|
|
3925
|
+
silent,
|
|
3926
|
+
onProgress
|
|
3927
|
+
});
|
|
3928
|
+
onProgress?.({ type: "callback_accepted" });
|
|
3929
|
+
if (!silent) log_default.info("Exchanging authorization code for tokens...");
|
|
3930
|
+
onProgress?.({ type: "token_exchange_started" });
|
|
3931
|
+
const tokens = await exchangeOauthCode({ ...transaction, code });
|
|
3932
|
+
if (!silent) log_default.info("Token exchange completed successfully");
|
|
3933
|
+
onProgress?.({ type: "token_exchange_completed" });
|
|
3934
|
+
return tokens;
|
|
3935
|
+
}
|
|
3936
|
+
async function readHeadlessCallbackUrl({
|
|
3937
|
+
timeoutMs,
|
|
3938
|
+
interactive,
|
|
3939
|
+
recoveryMessage
|
|
3940
|
+
}) {
|
|
3941
|
+
const timeoutMessage = withRecoveryMessage(
|
|
3942
|
+
`Signup timed out after ${Math.round(timeoutMs / 1e3)} seconds.`,
|
|
3943
|
+
recoveryMessage
|
|
3944
|
+
);
|
|
3945
|
+
const missingCallbackUrlMessage = withRecoveryMessage(
|
|
3946
|
+
"Paste the final OAuth callback URL from your browser.",
|
|
3947
|
+
recoveryMessage
|
|
3804
3948
|
);
|
|
3949
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
3950
|
+
const abortController = new AbortController();
|
|
3951
|
+
const timeoutTimer = setTimeout(() => abortController.abort(), timeoutMs);
|
|
3952
|
+
const readUrl = interactive ? rl.question("Paste the final OAuth callback URL: ", {
|
|
3953
|
+
signal: abortController.signal
|
|
3954
|
+
}) : new Promise((resolve4, reject) => {
|
|
3955
|
+
let settled = false;
|
|
3956
|
+
const settleResolve = (value) => {
|
|
3957
|
+
settled = true;
|
|
3958
|
+
resolve4(value);
|
|
3959
|
+
};
|
|
3960
|
+
const settleReject = (error) => {
|
|
3961
|
+
if (settled) return;
|
|
3962
|
+
settled = true;
|
|
3963
|
+
reject(error);
|
|
3964
|
+
};
|
|
3965
|
+
abortController.signal.addEventListener(
|
|
3966
|
+
"abort",
|
|
3967
|
+
() => settleReject(new Error(timeoutMessage)),
|
|
3968
|
+
{ once: true }
|
|
3969
|
+
);
|
|
3970
|
+
rl.once("line", settleResolve);
|
|
3971
|
+
rl.once(
|
|
3972
|
+
"close",
|
|
3973
|
+
() => settleReject(new ZapierCliValidationError(missingCallbackUrlMessage))
|
|
3974
|
+
);
|
|
3975
|
+
rl.once("error", settleReject);
|
|
3976
|
+
});
|
|
3805
3977
|
try {
|
|
3806
|
-
await
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
scopes: [...CREDENTIALS_SCOPES],
|
|
3812
|
-
baseUrl: credentialsBaseUrl2
|
|
3813
|
-
})
|
|
3978
|
+
return await readUrl.catch((error) => {
|
|
3979
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
3980
|
+
throw new Error(timeoutMessage);
|
|
3981
|
+
}
|
|
3982
|
+
throw error;
|
|
3814
3983
|
});
|
|
3815
|
-
}
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3984
|
+
} finally {
|
|
3985
|
+
clearTimeout(timeoutTimer);
|
|
3986
|
+
rl.close();
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
async function runHeadlessSignupOauthFlow({
|
|
3990
|
+
timeoutMs = LOGIN_TIMEOUT_MS,
|
|
3991
|
+
pkceCredentials,
|
|
3992
|
+
baseUrl: baseUrl2,
|
|
3993
|
+
interactive = true,
|
|
3994
|
+
onProgress,
|
|
3995
|
+
recoveryMessage
|
|
3996
|
+
}) {
|
|
3997
|
+
const port = LOGIN_PORTS[0];
|
|
3998
|
+
const transaction = await prepareOauthTransaction({
|
|
3999
|
+
pkceCredentials,
|
|
4000
|
+
baseUrl: baseUrl2,
|
|
4001
|
+
redirectUri: `http://${OAUTH_LOOPBACK_HOST}:${port}/oauth`,
|
|
4002
|
+
entryPoint: "signup"
|
|
4003
|
+
});
|
|
4004
|
+
console.log(
|
|
4005
|
+
"Use this mode when signing up from a machine that has no browser."
|
|
4006
|
+
);
|
|
4007
|
+
console.log("Open this signup URL in a browser on another machine:");
|
|
4008
|
+
console.log(transaction.browserAuthUrl);
|
|
4009
|
+
console.log(
|
|
4010
|
+
`When the browser lands on ${transaction.redirectUri} and cannot connect, paste the full final URL back here.`
|
|
4011
|
+
);
|
|
4012
|
+
const callbackUrl = await readHeadlessCallbackUrl({
|
|
4013
|
+
timeoutMs,
|
|
4014
|
+
interactive,
|
|
4015
|
+
recoveryMessage
|
|
4016
|
+
});
|
|
4017
|
+
const code = getCallbackCode({
|
|
4018
|
+
callbackUrl,
|
|
4019
|
+
transaction,
|
|
4020
|
+
recoveryMessage
|
|
4021
|
+
});
|
|
4022
|
+
onProgress?.({ type: "callback_accepted" });
|
|
4023
|
+
console.log("Exchanging authorization code for tokens...");
|
|
4024
|
+
onProgress?.({ type: "token_exchange_started" });
|
|
4025
|
+
const tokens = await exchangeOauthCode({ ...transaction, code });
|
|
4026
|
+
onProgress?.({ type: "token_exchange_completed" });
|
|
4027
|
+
return tokens;
|
|
4028
|
+
}
|
|
4029
|
+
async function collectLocalCallbackCode({
|
|
4030
|
+
transaction,
|
|
4031
|
+
timeoutMs,
|
|
4032
|
+
authAction,
|
|
4033
|
+
silent,
|
|
4034
|
+
onProgress
|
|
4035
|
+
}) {
|
|
4036
|
+
const { promise, resolve: resolve4, reject } = getCallablePromise_default();
|
|
4037
|
+
const app = express();
|
|
4038
|
+
app.get("/oauth", (req, res) => {
|
|
4039
|
+
res.setHeader("Connection", "close");
|
|
4040
|
+
if (req.query.state !== transaction.state) {
|
|
4041
|
+
res.status(400).end("Invalid state. You can close this tab.");
|
|
4042
|
+
} else if (req.query.error) {
|
|
4043
|
+
reject(
|
|
4044
|
+
new OauthAuthorizationDeniedError(
|
|
4045
|
+
String(req.query.error_description ?? req.query.error)
|
|
4046
|
+
)
|
|
3823
4047
|
);
|
|
4048
|
+
res.end("Authorization was denied. You can close this tab.");
|
|
4049
|
+
} else if (!req.query.code) {
|
|
4050
|
+
reject(new Error("No authorization code received"));
|
|
4051
|
+
res.end("No authorization code received. You can close this tab.");
|
|
4052
|
+
} else {
|
|
4053
|
+
resolve4(String(req.query.code));
|
|
4054
|
+
res.end("You can now close this tab and return to the CLI.");
|
|
3824
4055
|
}
|
|
3825
|
-
|
|
4056
|
+
});
|
|
4057
|
+
const server = app.listen(
|
|
4058
|
+
Number(new URL(transaction.redirectUri).port),
|
|
4059
|
+
OAUTH_LOOPBACK_HOST
|
|
4060
|
+
);
|
|
4061
|
+
const connections = /* @__PURE__ */ new Set();
|
|
4062
|
+
server.on("connection", (conn) => {
|
|
4063
|
+
connections.add(conn);
|
|
4064
|
+
conn.on("close", () => connections.delete(conn));
|
|
4065
|
+
});
|
|
4066
|
+
const cleanup = () => {
|
|
4067
|
+
server.close();
|
|
4068
|
+
reject(new ZapierCliUserCancellationError());
|
|
4069
|
+
};
|
|
4070
|
+
process.on("SIGINT", cleanup);
|
|
4071
|
+
process.on("SIGTERM", cleanup);
|
|
4072
|
+
let timeoutTimer;
|
|
4073
|
+
try {
|
|
4074
|
+
await waitForServerListening(server);
|
|
4075
|
+
await openBrowser({ transaction, authAction, silent, onProgress });
|
|
4076
|
+
const waitForCode = Promise.race([
|
|
4077
|
+
promise,
|
|
4078
|
+
new Promise((_resolve, rejectTimeout) => {
|
|
4079
|
+
timeoutTimer = setTimeout(() => {
|
|
4080
|
+
rejectTimeout(new OauthFlowTimeoutError(timeoutMs));
|
|
4081
|
+
}, timeoutMs);
|
|
4082
|
+
})
|
|
4083
|
+
]);
|
|
4084
|
+
onProgress?.({ type: "callback_waiting" });
|
|
4085
|
+
return silent ? await waitForCode : await spinPromise(
|
|
4086
|
+
waitForCode,
|
|
4087
|
+
`Waiting for you to ${authAction} and authorize`
|
|
4088
|
+
);
|
|
4089
|
+
} finally {
|
|
4090
|
+
if (timeoutTimer) clearTimeout(timeoutTimer);
|
|
4091
|
+
process.off("SIGINT", cleanup);
|
|
4092
|
+
process.off("SIGTERM", cleanup);
|
|
4093
|
+
await closeServer({ server, connections, silent });
|
|
3826
4094
|
}
|
|
3827
|
-
return { clientId };
|
|
3828
4095
|
}
|
|
3829
|
-
function
|
|
3830
|
-
if (
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
4096
|
+
async function waitForServerListening(server) {
|
|
4097
|
+
if (server.listening) return;
|
|
4098
|
+
await new Promise((resolve4, reject) => {
|
|
4099
|
+
const cleanup = () => {
|
|
4100
|
+
server.off("listening", handleListening);
|
|
4101
|
+
server.off("error", handleError);
|
|
4102
|
+
};
|
|
4103
|
+
const handleListening = () => {
|
|
4104
|
+
cleanup();
|
|
4105
|
+
resolve4();
|
|
4106
|
+
};
|
|
4107
|
+
const handleError = (error) => {
|
|
4108
|
+
cleanup();
|
|
4109
|
+
reject(error);
|
|
4110
|
+
};
|
|
4111
|
+
server.once("listening", handleListening);
|
|
4112
|
+
server.once("error", handleError);
|
|
4113
|
+
});
|
|
3834
4114
|
}
|
|
3835
|
-
function
|
|
3836
|
-
|
|
3837
|
-
|
|
4115
|
+
async function openBrowser({
|
|
4116
|
+
transaction,
|
|
4117
|
+
authAction,
|
|
4118
|
+
silent,
|
|
4119
|
+
onProgress
|
|
4120
|
+
}) {
|
|
4121
|
+
if (!silent) {
|
|
4122
|
+
log_default.info(`Opening your browser to ${authAction}.`);
|
|
4123
|
+
log_default.info("If it doesn't open, visit:", transaction.browserAuthUrl);
|
|
4124
|
+
}
|
|
4125
|
+
onProgress?.({ type: "browser_opening", url: transaction.browserAuthUrl });
|
|
4126
|
+
try {
|
|
4127
|
+
await open(transaction.browserAuthUrl);
|
|
4128
|
+
onProgress?.({ type: "browser_opened", url: transaction.browserAuthUrl });
|
|
4129
|
+
} catch (err) {
|
|
4130
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
4131
|
+
if (!silent) {
|
|
4132
|
+
log_default.info(
|
|
4133
|
+
`Browser did not open automatically to ${authAction}: ${reason}`
|
|
4134
|
+
);
|
|
4135
|
+
log_default.info("Visit this URL manually:", transaction.browserAuthUrl);
|
|
4136
|
+
}
|
|
4137
|
+
onProgress?.({
|
|
4138
|
+
type: "browser_open_failed",
|
|
4139
|
+
url: transaction.browserAuthUrl,
|
|
4140
|
+
reason
|
|
4141
|
+
});
|
|
3838
4142
|
}
|
|
3839
|
-
return void 0;
|
|
3840
4143
|
}
|
|
3841
|
-
async function
|
|
3842
|
-
|
|
3843
|
-
|
|
4144
|
+
async function closeServer({
|
|
4145
|
+
server,
|
|
4146
|
+
connections,
|
|
4147
|
+
silent
|
|
4148
|
+
}) {
|
|
4149
|
+
await new Promise((resolve4) => {
|
|
4150
|
+
const timeout = setTimeout(() => {
|
|
4151
|
+
if (!silent)
|
|
4152
|
+
log_default.info("Server close timed out, forcing connection shutdown...");
|
|
4153
|
+
connections.forEach((conn) => conn.destroy());
|
|
4154
|
+
resolve4();
|
|
4155
|
+
}, 1e3);
|
|
4156
|
+
server.close(() => {
|
|
4157
|
+
clearTimeout(timeout);
|
|
4158
|
+
resolve4();
|
|
4159
|
+
});
|
|
4160
|
+
});
|
|
3844
4161
|
}
|
|
3845
4162
|
|
|
3846
|
-
// src/utils/
|
|
3847
|
-
|
|
3848
|
-
|
|
4163
|
+
// src/utils/auth/oauth-errors.ts
|
|
4164
|
+
var SENSITIVE_OAUTH_FIELDS = [
|
|
4165
|
+
"access_token",
|
|
4166
|
+
"refresh_token",
|
|
4167
|
+
"id_token",
|
|
4168
|
+
"client_secret",
|
|
4169
|
+
"code_verifier",
|
|
4170
|
+
"code_challenge"
|
|
4171
|
+
];
|
|
4172
|
+
function getErrorMessage(error) {
|
|
4173
|
+
return error instanceof Error ? error.message : String(error);
|
|
4174
|
+
}
|
|
4175
|
+
function toCamelCase(field) {
|
|
4176
|
+
return field.replace(
|
|
4177
|
+
/_([a-z])/g,
|
|
4178
|
+
(_match, letter) => letter.toUpperCase()
|
|
4179
|
+
);
|
|
4180
|
+
}
|
|
4181
|
+
function escapeRegExp(value) {
|
|
4182
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4183
|
+
}
|
|
4184
|
+
var sensitiveOauthFieldPattern = Array.from(
|
|
4185
|
+
new Set(
|
|
4186
|
+
SENSITIVE_OAUTH_FIELDS.flatMap((field) => [field, toCamelCase(field)])
|
|
4187
|
+
)
|
|
4188
|
+
).map(escapeRegExp).join("|");
|
|
4189
|
+
var sensitiveQueryParamPattern = new RegExp(
|
|
4190
|
+
`([?&])(${sensitiveOauthFieldPattern})(=)[^&#\\s"'<>]*`,
|
|
4191
|
+
"gi"
|
|
4192
|
+
);
|
|
4193
|
+
function redactSensitiveOauthErrorMessage(message) {
|
|
4194
|
+
return message.replace(
|
|
4195
|
+
sensitiveQueryParamPattern,
|
|
4196
|
+
(_match, prefix, key, separator) => `${prefix}${key}${separator}[REDACTED]`
|
|
4197
|
+
).replace(
|
|
4198
|
+
new RegExp(`"(${sensitiveOauthFieldPattern})"(\\s*:\\s*)"[^"]*"`, "g"),
|
|
4199
|
+
(_match, key, separator) => `"${key}"${separator}"[REDACTED]"`
|
|
4200
|
+
);
|
|
4201
|
+
}
|
|
4202
|
+
function toRedactedOauthError(error) {
|
|
4203
|
+
const message = redactSensitiveOauthErrorMessage(getErrorMessage(error));
|
|
4204
|
+
if (error instanceof ZapierCliValidationError) {
|
|
4205
|
+
return new ZapierCliValidationError(message);
|
|
4206
|
+
}
|
|
4207
|
+
if (error instanceof Error) {
|
|
4208
|
+
const redactedError = new Error(message);
|
|
4209
|
+
redactedError.name = error.name;
|
|
4210
|
+
return redactedError;
|
|
4211
|
+
}
|
|
4212
|
+
return new ZapierCliValidationError(message);
|
|
3849
4213
|
}
|
|
3850
|
-
var LoginSchema = z.object({
|
|
3851
|
-
timeout: z.string().optional().describe("Login timeout in seconds (default: 300)"),
|
|
3852
|
-
useApprovals: z.boolean().optional().describe(
|
|
3853
|
-
"Require approvals for actions performed with these credentials"
|
|
3854
|
-
),
|
|
3855
|
-
nonInteractive: z.boolean().optional().describe(
|
|
3856
|
-
"Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable."
|
|
3857
|
-
),
|
|
3858
|
-
/** @deprecated Use `nonInteractive` instead. */
|
|
3859
|
-
skipPrompts: z.boolean().optional().meta({
|
|
3860
|
-
deprecated: true,
|
|
3861
|
-
deprecationMessage: "Use --non-interactive instead."
|
|
3862
|
-
})
|
|
3863
|
-
}).describe("Log in to Zapier to access your account");
|
|
3864
4214
|
|
|
3865
|
-
// src/
|
|
4215
|
+
// src/utils/auth/account-auth.ts
|
|
4216
|
+
var LEGACY_JWT_UPGRADE_PROMPT = "We're upgrading your login to client credentials for a simpler, more reliable experience and to support future security controls. Older Zapier SDK/CLI versions on this machine may stop working after the upgrade. Continue?";
|
|
4217
|
+
var SIGNUP_RECOVERY_MESSAGE = "Restart `zapier-sdk signup` to generate a fresh signup URL and try again.";
|
|
4218
|
+
var HEADLESS_SIGNUP_RECOVERY_MESSAGE = "Restart `zapier-sdk signup --headless` to generate a fresh signup URL and try again.";
|
|
4219
|
+
function getEntryPointLabel(entryPoint) {
|
|
4220
|
+
return entryPoint === "signup" ? "Signup" : "Login";
|
|
4221
|
+
}
|
|
4222
|
+
function getActiveCredentialsAction(entryPoint) {
|
|
4223
|
+
return entryPoint === "signup" ? "continue signup" : "log in again";
|
|
4224
|
+
}
|
|
4225
|
+
function getCredentialsPromptMessage(entryPoint) {
|
|
4226
|
+
return entryPoint === "signup" ? "Enter a name to identify these credentials:" : "Enter a name to identify them:";
|
|
4227
|
+
}
|
|
4228
|
+
function getProfileMessage(entryPoint, email) {
|
|
4229
|
+
return entryPoint === "signup" ? `\u{1F464} Authenticated as ${email}` : `\u{1F464} Logged in as ${email}`;
|
|
4230
|
+
}
|
|
4231
|
+
function defaultCredentialsName(email) {
|
|
4232
|
+
return `${email}@${hostname()}`;
|
|
4233
|
+
}
|
|
4234
|
+
function validateCredentialsName(name) {
|
|
4235
|
+
const trimmedName = name.trim();
|
|
4236
|
+
if (!trimmedName) throw new ZapierCliValidationError("Name cannot be empty");
|
|
4237
|
+
return trimmedName;
|
|
4238
|
+
}
|
|
4239
|
+
async function promptCredentialsName({
|
|
4240
|
+
email,
|
|
4241
|
+
promptMessage
|
|
4242
|
+
}) {
|
|
4243
|
+
const { credentialName } = await inquirer.prompt([
|
|
4244
|
+
{
|
|
4245
|
+
type: "input",
|
|
4246
|
+
name: "credentialName",
|
|
4247
|
+
message: promptMessage,
|
|
4248
|
+
default: defaultCredentialsName(email),
|
|
4249
|
+
validate: (input) => {
|
|
4250
|
+
try {
|
|
4251
|
+
validateCredentialsName(input);
|
|
4252
|
+
return true;
|
|
4253
|
+
} catch (err) {
|
|
4254
|
+
return err instanceof Error ? err.message : String(err);
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
}
|
|
4258
|
+
]);
|
|
4259
|
+
return validateCredentialsName(credentialName);
|
|
4260
|
+
}
|
|
4261
|
+
function resolveDefaultCredentialsName({
|
|
4262
|
+
email
|
|
4263
|
+
}) {
|
|
4264
|
+
return validateCredentialsName(defaultCredentialsName(email));
|
|
4265
|
+
}
|
|
3866
4266
|
function toPkceCredentials(credentials2) {
|
|
3867
4267
|
if (credentials2 && isCredentialsObject(credentials2) && !("clientSecret" in credentials2)) {
|
|
3868
4268
|
return {
|
|
@@ -3874,104 +4274,125 @@ function toPkceCredentials(credentials2) {
|
|
|
3874
4274
|
}
|
|
3875
4275
|
return void 0;
|
|
3876
4276
|
}
|
|
3877
|
-
|
|
3878
|
-
if (
|
|
4277
|
+
function parseTimeoutSeconds(timeout) {
|
|
4278
|
+
if (timeout === void 0) return 300;
|
|
4279
|
+
const timeoutSeconds = Number(timeout);
|
|
4280
|
+
if (!Number.isInteger(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
3879
4281
|
throw new ZapierCliValidationError(
|
|
3880
|
-
|
|
4282
|
+
"Timeout must be a positive integer (seconds)."
|
|
3881
4283
|
);
|
|
3882
4284
|
}
|
|
4285
|
+
return timeoutSeconds;
|
|
4286
|
+
}
|
|
4287
|
+
async function promptConfirm2({
|
|
4288
|
+
message,
|
|
4289
|
+
defaultValue
|
|
4290
|
+
}) {
|
|
3883
4291
|
const { confirmed } = await inquirer.prompt([
|
|
3884
|
-
{
|
|
3885
|
-
|
|
3886
|
-
|
|
4292
|
+
{ type: "confirm", name: "confirmed", message, default: defaultValue }
|
|
4293
|
+
]);
|
|
4294
|
+
return confirmed;
|
|
4295
|
+
}
|
|
4296
|
+
function promptlessCredentialResetError(credentials2) {
|
|
4297
|
+
throw new ZapierCliValidationError(
|
|
4298
|
+
`Already logged in as "${credentials2.name}". Run \`logout\` first or use an interactive terminal to re-authenticate.`
|
|
4299
|
+
);
|
|
4300
|
+
}
|
|
4301
|
+
function promptlessLegacyJwtUpgradeError() {
|
|
4302
|
+
throw new ZapierCliValidationError(
|
|
4303
|
+
"Legacy JWT login detected. Run `logout` first or use an interactive terminal to migrate to client credentials."
|
|
4304
|
+
);
|
|
4305
|
+
}
|
|
4306
|
+
async function clearExistingAuthState({
|
|
4307
|
+
sdk,
|
|
4308
|
+
baseUrl: baseUrl2,
|
|
4309
|
+
interactive,
|
|
4310
|
+
entryPoint
|
|
4311
|
+
}) {
|
|
4312
|
+
const activeCredentials = getActiveCredentials({ baseUrl: baseUrl2 });
|
|
4313
|
+
const flowLabel = getEntryPointLabel(entryPoint);
|
|
4314
|
+
if (activeCredentials) {
|
|
4315
|
+
const confirmed = interactive ? await promptConfirm2({
|
|
4316
|
+
defaultValue: false,
|
|
3887
4317
|
message: `You are already logged in as "${activeCredentials.name}".
|
|
3888
4318
|
Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
|
|
3889
|
-
Log out and
|
|
3890
|
-
|
|
4319
|
+
Log out and ${getActiveCredentialsAction(entryPoint)}?`
|
|
4320
|
+
}) : promptlessCredentialResetError(activeCredentials);
|
|
4321
|
+
if (!confirmed) {
|
|
4322
|
+
console.log(`${flowLabel} cancelled.`);
|
|
4323
|
+
return false;
|
|
3891
4324
|
}
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
4325
|
+
try {
|
|
4326
|
+
await revokeCredentials({
|
|
4327
|
+
api: sdk.context.api,
|
|
4328
|
+
credentials: activeCredentials
|
|
4329
|
+
});
|
|
4330
|
+
} catch {
|
|
4331
|
+
if (!interactive) {
|
|
4332
|
+
throw new ZapierCliValidationError(
|
|
4333
|
+
`${flowLabel} cleanup failed and cannot be reset without confirmation. Re-run with an interactive terminal.`
|
|
4334
|
+
);
|
|
4335
|
+
}
|
|
4336
|
+
const reset = await promptConfirm2({
|
|
4337
|
+
defaultValue: false,
|
|
4338
|
+
message: `${flowLabel} cleanup failed. Reset local session state and continue?`
|
|
4339
|
+
});
|
|
4340
|
+
if (!reset) {
|
|
4341
|
+
console.log(`${flowLabel} cancelled.`);
|
|
4342
|
+
return false;
|
|
4343
|
+
}
|
|
4344
|
+
await deleteStoredClientCredentials({
|
|
4345
|
+
name: activeCredentials.name,
|
|
4346
|
+
baseUrl: activeCredentials.baseUrl
|
|
4347
|
+
});
|
|
3911
4348
|
}
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
}
|
|
3919
|
-
|
|
3920
|
-
if (nonInteractive) {
|
|
3921
|
-
throw new ZapierCliValidationError(
|
|
3922
|
-
"Login cleanup failed and cannot be reset without confirmation. Re-run with an interactive terminal."
|
|
3923
|
-
);
|
|
3924
|
-
}
|
|
3925
|
-
const { confirmed } = await inquirer.prompt([
|
|
3926
|
-
{
|
|
3927
|
-
type: "confirm",
|
|
3928
|
-
name: "confirmed",
|
|
3929
|
-
message: "Login cleanup failed. Reset local session state and continue?",
|
|
3930
|
-
default: false
|
|
4349
|
+
} else if (hasLegacyJwtConfig()) {
|
|
4350
|
+
const confirmed = interactive ? await promptConfirm2({
|
|
4351
|
+
defaultValue: true,
|
|
4352
|
+
message: LEGACY_JWT_UPGRADE_PROMPT
|
|
4353
|
+
}) : promptlessLegacyJwtUpgradeError();
|
|
4354
|
+
if (!confirmed) {
|
|
4355
|
+
console.log(`${flowLabel} cancelled.`);
|
|
4356
|
+
return false;
|
|
3931
4357
|
}
|
|
3932
|
-
]);
|
|
3933
|
-
if (!confirmed) {
|
|
3934
|
-
console.log("Login cancelled.");
|
|
3935
|
-
return false;
|
|
3936
4358
|
}
|
|
3937
4359
|
return true;
|
|
3938
4360
|
}
|
|
3939
|
-
function
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
}
|
|
3944
|
-
return timeoutSeconds;
|
|
4361
|
+
async function getProfile(api2) {
|
|
4362
|
+
return api2.get("/zapier/api/v4/profile/", {
|
|
4363
|
+
authRequired: true
|
|
4364
|
+
});
|
|
3945
4365
|
}
|
|
3946
|
-
async function
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
4366
|
+
async function saveClientCredentials({
|
|
4367
|
+
api: api2,
|
|
4368
|
+
name,
|
|
4369
|
+
credentialsBaseUrl: credentialsBaseUrl2,
|
|
4370
|
+
useApprovals,
|
|
4371
|
+
cleanupLogPrefix
|
|
4372
|
+
}) {
|
|
4373
|
+
await setupClientCredentials({
|
|
4374
|
+
api: api2,
|
|
4375
|
+
name,
|
|
4376
|
+
credentialsBaseUrl: credentialsBaseUrl2,
|
|
4377
|
+
...useApprovals && { policy: EMPTY_POLICY }
|
|
4378
|
+
});
|
|
4379
|
+
try {
|
|
4380
|
+
await clearLegacyJwtState();
|
|
4381
|
+
} catch (err) {
|
|
4382
|
+
console.error(
|
|
4383
|
+
`[${cleanupLogPrefix}] Best-effort legacy JWT cleanup failed:`,
|
|
4384
|
+
err
|
|
4385
|
+
);
|
|
3950
4386
|
}
|
|
3951
|
-
const { credentialName } = await inquirer.prompt([
|
|
3952
|
-
{
|
|
3953
|
-
type: "input",
|
|
3954
|
-
name: "credentialName",
|
|
3955
|
-
message: "Enter a name to identify them:",
|
|
3956
|
-
default: fallback,
|
|
3957
|
-
validate: (input) => {
|
|
3958
|
-
if (!input.trim()) return "Name cannot be empty";
|
|
3959
|
-
return true;
|
|
3960
|
-
}
|
|
3961
|
-
}
|
|
3962
|
-
]);
|
|
3963
|
-
return credentialName;
|
|
3964
4387
|
}
|
|
3965
|
-
function
|
|
4388
|
+
function emitAccountAuthSuccess({
|
|
3966
4389
|
sdk,
|
|
3967
4390
|
profile
|
|
3968
4391
|
}) {
|
|
3969
4392
|
sdk.context.eventEmission.emit(
|
|
3970
4393
|
"platform.sdk.ApplicationLifecycleEvent",
|
|
3971
4394
|
buildApplicationLifecycleEvent(
|
|
3972
|
-
{
|
|
3973
|
-
lifecycle_event_type: "login_success"
|
|
3974
|
-
},
|
|
4395
|
+
{ lifecycle_event_type: "login_success" },
|
|
3975
4396
|
{
|
|
3976
4397
|
customuser_id: profile.user_id,
|
|
3977
4398
|
account_id: profile.roles[0]?.account_id ?? null
|
|
@@ -3979,18 +4400,128 @@ function emitLoginSuccess({
|
|
|
3979
4400
|
)
|
|
3980
4401
|
);
|
|
3981
4402
|
}
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
4403
|
+
function emitSignupSuccess({
|
|
4404
|
+
sdk
|
|
4405
|
+
}) {
|
|
4406
|
+
sdk.context.eventEmission.emit(
|
|
4407
|
+
"platform.sdk.ApplicationLifecycleEvent",
|
|
4408
|
+
buildApplicationLifecycleEvent({ lifecycle_event_type: "signup_success" })
|
|
4409
|
+
);
|
|
3986
4410
|
}
|
|
3987
|
-
async function
|
|
4411
|
+
async function runOauthWithRedaction(runOauth) {
|
|
3988
4412
|
try {
|
|
3989
|
-
await
|
|
3990
|
-
} catch (
|
|
3991
|
-
|
|
4413
|
+
return await runOauth();
|
|
4414
|
+
} catch (error) {
|
|
4415
|
+
if (error instanceof ZapierCliUserCancellationError) throw error;
|
|
4416
|
+
throw toRedactedOauthError(error);
|
|
4417
|
+
}
|
|
4418
|
+
}
|
|
4419
|
+
async function runOauthForEntryPoint({
|
|
4420
|
+
sdk,
|
|
4421
|
+
entryPoint,
|
|
4422
|
+
timeoutMs,
|
|
4423
|
+
pkceCredentials,
|
|
4424
|
+
baseUrl: baseUrl2,
|
|
4425
|
+
headless,
|
|
4426
|
+
interactive
|
|
4427
|
+
}) {
|
|
4428
|
+
if (entryPoint === "signup") {
|
|
4429
|
+
return runOauthWithRedaction(
|
|
4430
|
+
() => runSignupOauthFlow({
|
|
4431
|
+
timeoutMs,
|
|
4432
|
+
pkceCredentials,
|
|
4433
|
+
baseUrl: baseUrl2,
|
|
4434
|
+
headless,
|
|
4435
|
+
interactive,
|
|
4436
|
+
recoveryMessage: headless ? HEADLESS_SIGNUP_RECOVERY_MESSAGE : SIGNUP_RECOVERY_MESSAGE,
|
|
4437
|
+
onProgress: (event) => {
|
|
4438
|
+
if (event.type === "callback_accepted") {
|
|
4439
|
+
emitSignupSuccess({ sdk });
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4442
|
+
})
|
|
4443
|
+
);
|
|
4444
|
+
}
|
|
4445
|
+
return runOauthWithRedaction(
|
|
4446
|
+
() => runLoginOauthFlow({ timeoutMs, pkceCredentials, baseUrl: baseUrl2 })
|
|
4447
|
+
);
|
|
4448
|
+
}
|
|
4449
|
+
async function runAccountAuth({
|
|
4450
|
+
sdk,
|
|
4451
|
+
options,
|
|
4452
|
+
entryPoint
|
|
4453
|
+
}) {
|
|
4454
|
+
const timeoutSeconds = parseTimeoutSeconds(options.timeout);
|
|
4455
|
+
const interactive = !resolveNonInteractive(options);
|
|
4456
|
+
const resolvedCredentials = await sdk.context.resolveCredentials();
|
|
4457
|
+
const pkceCredentials = toPkceCredentials(resolvedCredentials);
|
|
4458
|
+
const credentialsBaseUrl2 = await resolveCredentialsBaseUrl({
|
|
4459
|
+
...sdk.context,
|
|
4460
|
+
resolvedCredentials
|
|
4461
|
+
});
|
|
4462
|
+
if (!await clearExistingAuthState({
|
|
4463
|
+
sdk,
|
|
4464
|
+
baseUrl: credentialsBaseUrl2,
|
|
4465
|
+
interactive,
|
|
4466
|
+
entryPoint
|
|
4467
|
+
})) {
|
|
4468
|
+
return;
|
|
4469
|
+
}
|
|
4470
|
+
const { accessToken } = await runOauthForEntryPoint({
|
|
4471
|
+
sdk,
|
|
4472
|
+
entryPoint,
|
|
4473
|
+
timeoutMs: timeoutSeconds * 1e3,
|
|
4474
|
+
pkceCredentials,
|
|
4475
|
+
baseUrl: credentialsBaseUrl2,
|
|
4476
|
+
headless: options.headless === true,
|
|
4477
|
+
interactive
|
|
4478
|
+
});
|
|
4479
|
+
const scopedApi = getOrCreateApiClient({
|
|
4480
|
+
credentials: accessToken,
|
|
4481
|
+
baseUrl: credentialsBaseUrl2
|
|
4482
|
+
});
|
|
4483
|
+
const profile = await getProfile(scopedApi);
|
|
4484
|
+
console.log(getProfileMessage(entryPoint, profile.email));
|
|
4485
|
+
console.log(
|
|
4486
|
+
"\nGenerating credentials so this machine can make authenticated requests on your behalf."
|
|
4487
|
+
);
|
|
4488
|
+
const resolveCredentialsName = interactive ? ({ email }) => promptCredentialsName({
|
|
4489
|
+
email,
|
|
4490
|
+
promptMessage: getCredentialsPromptMessage(entryPoint)
|
|
4491
|
+
}) : resolveDefaultCredentialsName;
|
|
4492
|
+
const credentialName = await resolveCredentialsName({ email: profile.email });
|
|
4493
|
+
const useApprovals = options.useApprovals === true;
|
|
4494
|
+
await saveClientCredentials({
|
|
4495
|
+
api: scopedApi,
|
|
4496
|
+
name: credentialName,
|
|
4497
|
+
credentialsBaseUrl: credentialsBaseUrl2,
|
|
4498
|
+
useApprovals,
|
|
4499
|
+
cleanupLogPrefix: entryPoint
|
|
4500
|
+
});
|
|
4501
|
+
console.log(
|
|
4502
|
+
`\u2705 Credentials "${credentialName}" created and set as default. You are ready to use the Zapier SDK.`
|
|
4503
|
+
);
|
|
4504
|
+
if (useApprovals) {
|
|
4505
|
+
console.log("\u{1F510} Approvals are enabled for these credentials.");
|
|
3992
4506
|
}
|
|
4507
|
+
emitAccountAuthSuccess({ sdk, profile });
|
|
3993
4508
|
}
|
|
4509
|
+
var LoginSchema = z.object({
|
|
4510
|
+
timeout: z.string().optional().describe("Login timeout in seconds (default: 300)"),
|
|
4511
|
+
useApprovals: z.boolean().optional().describe(
|
|
4512
|
+
"Require approvals for actions performed with these credentials"
|
|
4513
|
+
),
|
|
4514
|
+
nonInteractive: z.boolean().optional().describe(
|
|
4515
|
+
"Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable."
|
|
4516
|
+
),
|
|
4517
|
+
/** @deprecated Use `nonInteractive` instead. */
|
|
4518
|
+
skipPrompts: z.boolean().optional().meta({
|
|
4519
|
+
deprecated: true,
|
|
4520
|
+
deprecationMessage: "Use --non-interactive instead."
|
|
4521
|
+
})
|
|
4522
|
+
}).describe("Log in to Zapier to access your account");
|
|
4523
|
+
|
|
4524
|
+
// src/plugins/login/index.ts
|
|
3994
4525
|
var loginPlugin = definePlugin(
|
|
3995
4526
|
(sdk) => createPluginMethod(sdk, {
|
|
3996
4527
|
name: "login",
|
|
@@ -3998,68 +4529,37 @@ var loginPlugin = definePlugin(
|
|
|
3998
4529
|
inputSchema: LoginSchema,
|
|
3999
4530
|
supportsJsonOutput: false,
|
|
4000
4531
|
handler: async ({ sdk: sdk2, options }) => {
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
pkceCredentials,
|
|
4033
|
-
baseUrl: credentialsBaseUrl2
|
|
4034
|
-
});
|
|
4035
|
-
const scopedApi = getOrCreateApiClient({
|
|
4036
|
-
credentials: accessToken,
|
|
4037
|
-
baseUrl: credentialsBaseUrl2
|
|
4038
|
-
});
|
|
4039
|
-
const profile = await getProfile(scopedApi);
|
|
4040
|
-
console.log(`\u{1F464} Logged in as ${profile.email}`);
|
|
4041
|
-
console.log(
|
|
4042
|
-
"\nGenerating credentials so this machine can make authenticated requests on your behalf."
|
|
4043
|
-
);
|
|
4044
|
-
const credentialName = await promptCredentialsName(
|
|
4045
|
-
profile.email,
|
|
4046
|
-
nonInteractive
|
|
4047
|
-
);
|
|
4048
|
-
const useApprovals = options.useApprovals === true;
|
|
4049
|
-
await setupClientCredentials({
|
|
4050
|
-
api: scopedApi,
|
|
4051
|
-
name: credentialName,
|
|
4052
|
-
credentialsBaseUrl: credentialsBaseUrl2,
|
|
4053
|
-
...useApprovals && { policy: EMPTY_POLICY }
|
|
4054
|
-
});
|
|
4055
|
-
await bestEffortClearLegacyJwtState();
|
|
4056
|
-
console.log(
|
|
4057
|
-
`\u2705 Credentials "${credentialName}" created and set as default. You are ready to use the Zapier SDK.`
|
|
4058
|
-
);
|
|
4059
|
-
if (useApprovals) {
|
|
4060
|
-
console.log("\u{1F510} Approvals are enabled for these credentials.");
|
|
4061
|
-
}
|
|
4062
|
-
emitLoginSuccess({ sdk: sdk2, profile });
|
|
4532
|
+
await runAccountAuth({ sdk: sdk2, options, entryPoint: "login" });
|
|
4533
|
+
}
|
|
4534
|
+
})
|
|
4535
|
+
);
|
|
4536
|
+
var SignupSchema = z.object({
|
|
4537
|
+
timeout: z.string().optional().describe("Signup timeout in seconds (default: 300)"),
|
|
4538
|
+
useApprovals: z.boolean().optional().describe(
|
|
4539
|
+
"Require approvals for actions performed with these credentials"
|
|
4540
|
+
),
|
|
4541
|
+
nonInteractive: z.boolean().optional().describe(
|
|
4542
|
+
"Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable."
|
|
4543
|
+
),
|
|
4544
|
+
/** @deprecated Use `nonInteractive` instead. */
|
|
4545
|
+
skipPrompts: z.boolean().optional().meta({
|
|
4546
|
+
deprecated: true,
|
|
4547
|
+
deprecationMessage: "Use --non-interactive instead."
|
|
4548
|
+
}),
|
|
4549
|
+
headless: z.boolean().optional().describe(
|
|
4550
|
+
"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."
|
|
4551
|
+
)
|
|
4552
|
+
}).describe("Set up Zapier account access and SDK credentials");
|
|
4553
|
+
|
|
4554
|
+
// src/plugins/signup/index.ts
|
|
4555
|
+
var signupPlugin = definePlugin(
|
|
4556
|
+
(sdk) => createPluginMethod(sdk, {
|
|
4557
|
+
name: "signup",
|
|
4558
|
+
categories: ["account"],
|
|
4559
|
+
inputSchema: SignupSchema,
|
|
4560
|
+
supportsJsonOutput: false,
|
|
4561
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
4562
|
+
await runAccountAuth({ sdk: sdk2, options, entryPoint: "signup" });
|
|
4063
4563
|
}
|
|
4064
4564
|
})
|
|
4065
4565
|
);
|
|
@@ -4126,7 +4626,8 @@ var BundleCodeSchema = z.object({
|
|
|
4126
4626
|
var bundleCodePlugin = definePlugin(
|
|
4127
4627
|
(sdk) => createPluginMethod(sdk, {
|
|
4128
4628
|
name: "bundleCode",
|
|
4129
|
-
categories: ["utility"
|
|
4629
|
+
categories: ["utility"],
|
|
4630
|
+
deprecation: { message: "bundleCode is no longer maintained." },
|
|
4130
4631
|
inputSchema: BundleCodeSchema,
|
|
4131
4632
|
handler: async ({ options }) => bundleCode(options)
|
|
4132
4633
|
})
|
|
@@ -4222,7 +4723,7 @@ async function detectTypesOutputDirectory() {
|
|
|
4222
4723
|
}
|
|
4223
4724
|
return "./zapier/apps/";
|
|
4224
4725
|
}
|
|
4225
|
-
var
|
|
4726
|
+
var addAppsPlugin = definePlugin(
|
|
4226
4727
|
(sdk) => createPluginMethod(sdk, {
|
|
4227
4728
|
name: "add",
|
|
4228
4729
|
categories: ["utility"],
|
|
@@ -5627,10 +6128,6 @@ var cliOverridesPlugin = definePlugin(
|
|
|
5627
6128
|
if (sdk.context.meta.fetch) {
|
|
5628
6129
|
meta.fetch = {
|
|
5629
6130
|
...sdk.context.meta.fetch,
|
|
5630
|
-
categories: [
|
|
5631
|
-
...sdk.context.meta.fetch.categories || [],
|
|
5632
|
-
"deprecated"
|
|
5633
|
-
],
|
|
5634
6131
|
deprecation: {
|
|
5635
6132
|
message: "This command is deprecated and will be removed soon. Use `curl` instead. Learn more: https://docs.zapier.com/sdk/cli-reference#curl"
|
|
5636
6133
|
}
|
|
@@ -6611,7 +7108,7 @@ var watchTriggerInboxCliPlugin = definePlugin(
|
|
|
6611
7108
|
// package.json with { type: 'json' }
|
|
6612
7109
|
var package_default2 = {
|
|
6613
7110
|
name: "@zapier/zapier-sdk-cli",
|
|
6614
|
-
version: "0.
|
|
7111
|
+
version: "0.53.0"};
|
|
6615
7112
|
|
|
6616
7113
|
// src/sdk.ts
|
|
6617
7114
|
injectCliLogin(login_exports);
|
|
@@ -6620,21 +7117,21 @@ function createZapierCliSdk(options = {}) {
|
|
|
6620
7117
|
const extensionsContextPlugin = () => ({
|
|
6621
7118
|
context: { extensions }
|
|
6622
7119
|
});
|
|
6623
|
-
|
|
7120
|
+
const sdk = createZapierSdkStack$1({
|
|
6624
7121
|
...sdkOptions,
|
|
6625
7122
|
eventEmission: { ...sdkOptions.eventEmission, callContext: "cli" },
|
|
6626
7123
|
callerPackage: { name: package_default2.name, version: package_default2.version }
|
|
6627
|
-
}).
|
|
7124
|
+
}).use(extensionsContextPlugin).use(generateAppTypesPlugin).use(buildManifestPlugin).use(bundleCodePlugin).use(getLoginConfigPathPlugin).use(addAppsPlugin).use(feedbackPlugin).use(curlPlugin).use(initPlugin).use(mcpPlugin).use(loginPlugin).use(signupPlugin).use(logoutPlugin).use(cliOverridesPlugin, { override: true }).toSdk();
|
|
6628
7125
|
for (const ext of extensions) {
|
|
6629
7126
|
try {
|
|
6630
|
-
|
|
7127
|
+
addPlugin$1(sdk, ext);
|
|
6631
7128
|
} catch (err) {
|
|
6632
7129
|
console.warn(
|
|
6633
7130
|
`Extension plugin failed to construct: ${err.message}; skipping.`
|
|
6634
7131
|
);
|
|
6635
7132
|
}
|
|
6636
7133
|
}
|
|
6637
|
-
return
|
|
7134
|
+
return sdk;
|
|
6638
7135
|
}
|
|
6639
7136
|
injectCliLogin$1(login_exports);
|
|
6640
7137
|
function createZapierCliSdk2(options = {}) {
|
|
@@ -6645,21 +7142,21 @@ function createZapierCliSdk2(options = {}) {
|
|
|
6645
7142
|
const experimentalContextPlugin = () => ({
|
|
6646
7143
|
context: { experimental: true }
|
|
6647
7144
|
});
|
|
6648
|
-
|
|
7145
|
+
const sdk = createZapierSdkStack({
|
|
6649
7146
|
...sdkOptions,
|
|
6650
7147
|
eventEmission: { ...sdkOptions.eventEmission, callContext: "cli" },
|
|
6651
7148
|
callerPackage: { name: package_default2.name, version: package_default2.version }
|
|
6652
|
-
}).
|
|
7149
|
+
}).use(extensionsContextPlugin).use(experimentalContextPlugin).use(generateAppTypesPlugin).use(buildManifestPlugin).use(bundleCodePlugin).use(getLoginConfigPathPlugin).use(addAppsPlugin).use(feedbackPlugin).use(curlPlugin).use(initPlugin).use(drainTriggerInboxCliPlugin, { override: true }).use(watchTriggerInboxCliPlugin, { override: true }).use(mcpPlugin).use(loginPlugin).use(signupPlugin).use(logoutPlugin).use(cliOverridesPlugin, { override: true }).toSdk();
|
|
6653
7150
|
for (const ext of extensions) {
|
|
6654
7151
|
try {
|
|
6655
|
-
|
|
7152
|
+
addPlugin(sdk, ext);
|
|
6656
7153
|
} catch (err) {
|
|
6657
7154
|
console.warn(
|
|
6658
7155
|
`Extension plugin failed to construct: ${err.message}; skipping.`
|
|
6659
7156
|
);
|
|
6660
7157
|
}
|
|
6661
7158
|
}
|
|
6662
|
-
return
|
|
7159
|
+
return sdk;
|
|
6663
7160
|
}
|
|
6664
7161
|
|
|
6665
7162
|
// src/utils/extensions.ts
|
|
@@ -6793,7 +7290,9 @@ async function checkForUpdates({
|
|
|
6793
7290
|
currentVersion
|
|
6794
7291
|
);
|
|
6795
7292
|
} catch (error) {
|
|
6796
|
-
|
|
7293
|
+
if (!(error instanceof VersionNotFoundError)) {
|
|
7294
|
+
log_default.debug(`Failed to check deprecation for current version: ${error}`);
|
|
7295
|
+
}
|
|
6797
7296
|
currentPackageInfo = latestPackageInfo;
|
|
6798
7297
|
}
|
|
6799
7298
|
const isDeprecated = Boolean(currentPackageInfo.deprecated);
|