@zapier/zapier-sdk-cli 0.47.0 → 0.48.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/CHANGELOG.md +22 -0
- package/README.md +2 -1
- package/dist/cli.cjs +581 -86
- package/dist/cli.mjs +581 -86
- package/dist/experimental.cjs +562 -86
- package/dist/experimental.mjs +561 -85
- package/dist/index.cjs +563 -87
- package/dist/index.mjs +562 -86
- package/dist/login.cjs +94 -25
- package/dist/login.d.mts +29 -2
- package/dist/login.d.ts +29 -2
- package/dist/login.mjs +90 -25
- package/dist/package.json +1 -1
- package/dist/src/cli.js +32 -3
- package/dist/src/login/config.d.ts +4 -0
- package/dist/src/login/config.js +21 -0
- package/dist/src/login/credentials-revoke.d.ts +13 -0
- package/dist/src/login/credentials-revoke.js +48 -0
- package/dist/src/login/credentials-store.d.ts +33 -0
- package/dist/src/login/credentials-store.js +142 -0
- package/dist/src/login/index.d.ts +5 -2
- package/dist/src/login/index.js +11 -27
- package/dist/src/login/legacy-jwt.d.ts +4 -0
- package/dist/src/login/legacy-jwt.js +18 -0
- package/dist/src/plugins/auth/credentials-base-url.d.ts +11 -0
- package/dist/src/plugins/auth/credentials-base-url.js +24 -0
- package/dist/src/plugins/login/index.d.ts +6 -1
- package/dist/src/plugins/login/index.js +154 -14
- package/dist/src/plugins/logout/index.d.ts +14 -0
- package/dist/src/plugins/logout/index.js +35 -3
- package/dist/src/plugins/mcp/index.d.ts +1 -0
- package/dist/src/plugins/mcp/index.js +8 -7
- package/dist/src/utils/auth/client-credentials.d.ts +16 -0
- package/dist/src/utils/auth/client-credentials.js +53 -0
- package/dist/src/utils/auth/oauth-flow.d.ts +12 -0
- package/dist/src/utils/auth/{login.js → oauth-flow.js} +36 -58
- package/dist/src/utils/retry.d.ts +5 -0
- package/dist/src/utils/retry.js +21 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/src/utils/auth/login.d.ts +0 -7
package/dist/cli.cjs
CHANGED
|
@@ -9,13 +9,14 @@ var chalk7 = require('chalk');
|
|
|
9
9
|
var ora = require('ora');
|
|
10
10
|
var util = require('util');
|
|
11
11
|
var wrapAnsi = require('wrap-ansi');
|
|
12
|
-
var Conf = require('conf');
|
|
13
|
-
var fs = require('fs');
|
|
14
12
|
var jwt = require('jsonwebtoken');
|
|
15
13
|
var crossKeychain = require('cross-keychain');
|
|
14
|
+
var Conf = require('conf');
|
|
15
|
+
var fs = require('fs');
|
|
16
16
|
var crypto = require('crypto');
|
|
17
17
|
var path = require('path');
|
|
18
18
|
var lockfile = require('proper-lockfile');
|
|
19
|
+
var os = require('os');
|
|
19
20
|
var open = require('open');
|
|
20
21
|
var express = require('express');
|
|
21
22
|
var pkceChallenge = require('pkce-challenge');
|
|
@@ -57,9 +58,9 @@ var chalk7__default = /*#__PURE__*/_interopDefault(chalk7);
|
|
|
57
58
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
58
59
|
var util__default = /*#__PURE__*/_interopDefault(util);
|
|
59
60
|
var wrapAnsi__default = /*#__PURE__*/_interopDefault(wrapAnsi);
|
|
61
|
+
var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
|
|
60
62
|
var Conf__default = /*#__PURE__*/_interopDefault(Conf);
|
|
61
63
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
62
|
-
var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
|
|
63
64
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
64
65
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
65
66
|
var lockfile__namespace = /*#__PURE__*/_interopNamespace(lockfile);
|
|
@@ -1189,7 +1190,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
1189
1190
|
|
|
1190
1191
|
// package.json
|
|
1191
1192
|
var package_default = {
|
|
1192
|
-
version: "0.
|
|
1193
|
+
version: "0.48.1"};
|
|
1193
1194
|
|
|
1194
1195
|
// src/telemetry/builders.ts
|
|
1195
1196
|
function createCliBaseEvent(context = {}) {
|
|
@@ -2341,8 +2342,11 @@ function convertValue(value, type, elementType) {
|
|
|
2341
2342
|
var login_exports = {};
|
|
2342
2343
|
__export(login_exports, {
|
|
2343
2344
|
AUTH_MODE_HEADER: () => AUTH_MODE_HEADER,
|
|
2345
|
+
DEFAULT_AUTH_BASE_URL: () => DEFAULT_AUTH_BASE_URL,
|
|
2344
2346
|
ZapierAuthenticationError: () => ZapierAuthenticationError,
|
|
2347
|
+
clearTokensFromKeychain: () => clearTokensFromKeychain,
|
|
2345
2348
|
createCache: () => createCache,
|
|
2349
|
+
getActiveCredentials: () => getActiveCredentials,
|
|
2346
2350
|
getAuthAuthorizeUrl: () => getAuthAuthorizeUrl,
|
|
2347
2351
|
getAuthTokenUrl: () => getAuthTokenUrl,
|
|
2348
2352
|
getConfig: () => getConfig,
|
|
@@ -2350,6 +2354,7 @@ __export(login_exports, {
|
|
|
2350
2354
|
getLoggedInUser: () => getLoggedInUser,
|
|
2351
2355
|
getLoginStorageMode: () => getLoginStorageMode,
|
|
2352
2356
|
getPkceLoginConfig: () => getPkceLoginConfig,
|
|
2357
|
+
getStoredClientCredentials: () => getStoredClientCredentials,
|
|
2353
2358
|
getToken: () => getToken,
|
|
2354
2359
|
logout: () => logout,
|
|
2355
2360
|
unloadConfig: () => unloadConfig,
|
|
@@ -2430,6 +2435,38 @@ async function clearTokensFromKeychain({
|
|
|
2430
2435
|
}
|
|
2431
2436
|
});
|
|
2432
2437
|
}
|
|
2438
|
+
var DEFAULT_AUTH_BASE_URL = "https://zapier.com";
|
|
2439
|
+
var config = null;
|
|
2440
|
+
function getConfig() {
|
|
2441
|
+
if (!config) {
|
|
2442
|
+
config = new Conf__default.default({ projectName: "zapier-sdk-cli" });
|
|
2443
|
+
if (!config.has("login_storage_mode")) {
|
|
2444
|
+
config.set(
|
|
2445
|
+
"login_storage_mode",
|
|
2446
|
+
fs.existsSync(config.path) ? "config" : "keychain"
|
|
2447
|
+
);
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
return config;
|
|
2451
|
+
}
|
|
2452
|
+
function resetConfig() {
|
|
2453
|
+
config = null;
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
// src/login/legacy-jwt.ts
|
|
2457
|
+
function clearLegacyJwtConfigKeys(config2) {
|
|
2458
|
+
config2.delete("login_jwt");
|
|
2459
|
+
config2.delete("login_refresh_token");
|
|
2460
|
+
config2.delete("login_expires_at");
|
|
2461
|
+
}
|
|
2462
|
+
async function clearLegacyJwtState() {
|
|
2463
|
+
clearLegacyJwtConfigKeys(getConfig());
|
|
2464
|
+
await clearTokensFromKeychain();
|
|
2465
|
+
}
|
|
2466
|
+
function hasLegacyJwtConfig() {
|
|
2467
|
+
const cfg = getConfig();
|
|
2468
|
+
return typeof cfg.get("login_jwt") === "string" || typeof cfg.get("login_refresh_token") === "string" || typeof cfg.get("login_expires_at") === "number";
|
|
2469
|
+
}
|
|
2433
2470
|
var SERVICE2 = "zapier-sdk-cache";
|
|
2434
2471
|
var CONFIG_KEY = "cache";
|
|
2435
2472
|
var LOCK_UPDATE_MS = 5e3;
|
|
@@ -2557,6 +2594,163 @@ function createCache() {
|
|
|
2557
2594
|
}
|
|
2558
2595
|
};
|
|
2559
2596
|
}
|
|
2597
|
+
var SERVICE3 = "zapier-sdk-cli";
|
|
2598
|
+
var CREDENTIALS_KEY = "credentials";
|
|
2599
|
+
var REGISTRY_KEY = "credentialsRegistry";
|
|
2600
|
+
var CredentialsEntrySchema = zod.z.object({
|
|
2601
|
+
name: zod.z.string(),
|
|
2602
|
+
clientId: zod.z.string(),
|
|
2603
|
+
createdAt: zod.z.number(),
|
|
2604
|
+
scopes: zod.z.array(zod.z.string()),
|
|
2605
|
+
baseUrl: zod.z.string()
|
|
2606
|
+
});
|
|
2607
|
+
function normalizeBaseUrl(baseUrl2) {
|
|
2608
|
+
return baseUrl2 ?? DEFAULT_AUTH_BASE_URL;
|
|
2609
|
+
}
|
|
2610
|
+
function keychainAccount2(key) {
|
|
2611
|
+
return crypto.createHash("sha256").update(key).digest("hex");
|
|
2612
|
+
}
|
|
2613
|
+
function buildKeychainKey(clientId, scopes, baseUrl2) {
|
|
2614
|
+
const sortedScopes = [...scopes].sort().join(",");
|
|
2615
|
+
return `zapier-sdk/client-credentials-secret/${clientId}:${sortedScopes}:${baseUrl2}`;
|
|
2616
|
+
}
|
|
2617
|
+
function findEntry(registry, name, baseUrl2) {
|
|
2618
|
+
return registry.find((e) => e.name === name && e.baseUrl === baseUrl2);
|
|
2619
|
+
}
|
|
2620
|
+
function readRegistry() {
|
|
2621
|
+
const stored = getConfig().get(REGISTRY_KEY);
|
|
2622
|
+
if (!Array.isArray(stored)) return [];
|
|
2623
|
+
return stored.flatMap((entry) => {
|
|
2624
|
+
const result = CredentialsEntrySchema.safeParse(entry);
|
|
2625
|
+
return result.success ? [result.data] : [];
|
|
2626
|
+
});
|
|
2627
|
+
}
|
|
2628
|
+
function getActiveCredentials(options) {
|
|
2629
|
+
const name = getConfig().get(CREDENTIALS_KEY);
|
|
2630
|
+
if (!name) return void 0;
|
|
2631
|
+
return findEntry(readRegistry(), name, normalizeBaseUrl(options?.baseUrl));
|
|
2632
|
+
}
|
|
2633
|
+
async function storeClientCredentials({
|
|
2634
|
+
name,
|
|
2635
|
+
clientId,
|
|
2636
|
+
clientSecret,
|
|
2637
|
+
scopes,
|
|
2638
|
+
baseUrl: baseUrl2
|
|
2639
|
+
}) {
|
|
2640
|
+
if (!name || typeof name !== "string") {
|
|
2641
|
+
throw new Error("storeClientCredentials: name is required");
|
|
2642
|
+
}
|
|
2643
|
+
if (!clientId || typeof clientId !== "string") {
|
|
2644
|
+
throw new Error("storeClientCredentials: clientId is required");
|
|
2645
|
+
}
|
|
2646
|
+
if (!clientSecret || typeof clientSecret !== "string") {
|
|
2647
|
+
throw new Error("storeClientCredentials: clientSecret is required");
|
|
2648
|
+
}
|
|
2649
|
+
if (!Array.isArray(scopes) || scopes.length === 0) {
|
|
2650
|
+
throw new Error("storeClientCredentials: scopes must be a non-empty array");
|
|
2651
|
+
}
|
|
2652
|
+
const sortedScopes = [...scopes].sort();
|
|
2653
|
+
const resolvedBaseUrl = normalizeBaseUrl(baseUrl2);
|
|
2654
|
+
const keychainKey = buildKeychainKey(clientId, sortedScopes, resolvedBaseUrl);
|
|
2655
|
+
const existingEntry = findEntry(readRegistry(), name, resolvedBaseUrl);
|
|
2656
|
+
const existingKeychainKey = existingEntry ? buildKeychainKey(
|
|
2657
|
+
existingEntry.clientId,
|
|
2658
|
+
existingEntry.scopes,
|
|
2659
|
+
existingEntry.baseUrl
|
|
2660
|
+
) : void 0;
|
|
2661
|
+
await enqueue(async () => {
|
|
2662
|
+
await getBackendInfo();
|
|
2663
|
+
await crossKeychain.setPassword(SERVICE3, keychainAccount2(keychainKey), clientSecret);
|
|
2664
|
+
});
|
|
2665
|
+
const entry = {
|
|
2666
|
+
name,
|
|
2667
|
+
clientId,
|
|
2668
|
+
createdAt: Date.now(),
|
|
2669
|
+
scopes: sortedScopes,
|
|
2670
|
+
baseUrl: resolvedBaseUrl
|
|
2671
|
+
};
|
|
2672
|
+
const registry = readRegistry().filter(
|
|
2673
|
+
(e) => !(e.name === name && e.baseUrl === resolvedBaseUrl)
|
|
2674
|
+
);
|
|
2675
|
+
registry.push(entry);
|
|
2676
|
+
const cfg = getConfig();
|
|
2677
|
+
cfg.set(REGISTRY_KEY, registry);
|
|
2678
|
+
cfg.set(CREDENTIALS_KEY, name);
|
|
2679
|
+
if (existingEntry && existingKeychainKey !== keychainKey) {
|
|
2680
|
+
await deleteKeychainSecret(existingEntry);
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
function credentialsNameExists({
|
|
2684
|
+
name,
|
|
2685
|
+
baseUrl: baseUrl2
|
|
2686
|
+
}) {
|
|
2687
|
+
return !!findEntry(readRegistry(), name, normalizeBaseUrl(baseUrl2));
|
|
2688
|
+
}
|
|
2689
|
+
async function getStoredClientCredentials(options) {
|
|
2690
|
+
const entry = options?.name ? findEntry(readRegistry(), options.name, normalizeBaseUrl(options.baseUrl)) : getActiveCredentials(options);
|
|
2691
|
+
if (!entry) return void 0;
|
|
2692
|
+
const keychainKey = buildKeychainKey(
|
|
2693
|
+
entry.clientId,
|
|
2694
|
+
entry.scopes,
|
|
2695
|
+
entry.baseUrl
|
|
2696
|
+
);
|
|
2697
|
+
const clientSecret = await enqueue(async () => {
|
|
2698
|
+
await getBackendInfo();
|
|
2699
|
+
return crossKeychain.getPassword(SERVICE3, keychainAccount2(keychainKey));
|
|
2700
|
+
});
|
|
2701
|
+
if (!clientSecret) return void 0;
|
|
2702
|
+
return {
|
|
2703
|
+
type: "client_credentials",
|
|
2704
|
+
clientId: entry.clientId,
|
|
2705
|
+
clientSecret,
|
|
2706
|
+
baseUrl: entry.baseUrl,
|
|
2707
|
+
scope: [...entry.scopes].sort().join(" ")
|
|
2708
|
+
};
|
|
2709
|
+
}
|
|
2710
|
+
function deleteRegistryEntry(registry, name, baseUrl2) {
|
|
2711
|
+
const idx = registry.findIndex(
|
|
2712
|
+
(e) => e.name === name && e.baseUrl === baseUrl2
|
|
2713
|
+
);
|
|
2714
|
+
if (idx === -1) return void 0;
|
|
2715
|
+
const [removed] = registry.splice(idx, 1);
|
|
2716
|
+
return removed;
|
|
2717
|
+
}
|
|
2718
|
+
function unsetMatchingCredentialsKey(cfg, name) {
|
|
2719
|
+
const activeName = cfg.get(CREDENTIALS_KEY);
|
|
2720
|
+
if (activeName === name && !readRegistry().some((e) => e.name === name)) {
|
|
2721
|
+
cfg.delete(CREDENTIALS_KEY);
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
async function deleteKeychainSecret(entry) {
|
|
2725
|
+
const keychainKey = buildKeychainKey(
|
|
2726
|
+
entry.clientId,
|
|
2727
|
+
entry.scopes,
|
|
2728
|
+
entry.baseUrl
|
|
2729
|
+
);
|
|
2730
|
+
try {
|
|
2731
|
+
await enqueue(async () => {
|
|
2732
|
+
await getBackendInfo();
|
|
2733
|
+
await crossKeychain.deletePassword(SERVICE3, keychainAccount2(keychainKey));
|
|
2734
|
+
});
|
|
2735
|
+
} catch {
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
async function deleteStoredClientCredentials({
|
|
2739
|
+
name,
|
|
2740
|
+
baseUrl: baseUrl2
|
|
2741
|
+
}) {
|
|
2742
|
+
const registry = readRegistry();
|
|
2743
|
+
const removed = deleteRegistryEntry(
|
|
2744
|
+
registry,
|
|
2745
|
+
name,
|
|
2746
|
+
normalizeBaseUrl(baseUrl2)
|
|
2747
|
+
);
|
|
2748
|
+
if (!removed) return;
|
|
2749
|
+
const cfg = getConfig();
|
|
2750
|
+
cfg.set(REGISTRY_KEY, registry);
|
|
2751
|
+
unsetMatchingCredentialsKey(cfg, name);
|
|
2752
|
+
await deleteKeychainSecret(removed);
|
|
2753
|
+
}
|
|
2560
2754
|
|
|
2561
2755
|
// src/login/index.ts
|
|
2562
2756
|
var ZapierAuthenticationError = class extends Error {
|
|
@@ -2565,7 +2759,6 @@ var ZapierAuthenticationError = class extends Error {
|
|
|
2565
2759
|
this.name = "ZapierAuthenticationError";
|
|
2566
2760
|
}
|
|
2567
2761
|
};
|
|
2568
|
-
var config = null;
|
|
2569
2762
|
var DEFAULT_AUTH_CLIENT_ID = "grwWZD5hUWGvb4V8ODBuOtXer3h0DBEZ2HR8aay6";
|
|
2570
2763
|
var TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
2571
2764
|
function createDebugLog(enabled) {
|
|
@@ -2591,7 +2784,6 @@ function getAuthClientId(clientId) {
|
|
|
2591
2784
|
return clientId || DEFAULT_AUTH_CLIENT_ID;
|
|
2592
2785
|
}
|
|
2593
2786
|
var AUTH_MODE_HEADER = "X-Auth";
|
|
2594
|
-
var DEFAULT_AUTH_BASE_URL = "https://zapier.com";
|
|
2595
2787
|
function getAuthTokenUrl(options) {
|
|
2596
2788
|
const authBaseUrl = options?.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
2597
2789
|
return `${authBaseUrl}/oauth/token/`;
|
|
@@ -2601,29 +2793,16 @@ function getAuthAuthorizeUrl(options) {
|
|
|
2601
2793
|
return `${authBaseUrl}/oauth/authorize/`;
|
|
2602
2794
|
}
|
|
2603
2795
|
function getPkceLoginConfig(options) {
|
|
2796
|
+
const effectiveBaseUrl = options?.credentials?.baseUrl ?? options?.baseUrl;
|
|
2604
2797
|
return {
|
|
2605
2798
|
clientId: getAuthClientId(options?.credentials?.clientId),
|
|
2606
|
-
tokenUrl: getAuthTokenUrl({ baseUrl:
|
|
2607
|
-
authorizeUrl: getAuthAuthorizeUrl({
|
|
2608
|
-
baseUrl: options?.credentials?.baseUrl
|
|
2609
|
-
})
|
|
2799
|
+
tokenUrl: getAuthTokenUrl({ baseUrl: effectiveBaseUrl }),
|
|
2800
|
+
authorizeUrl: getAuthAuthorizeUrl({ baseUrl: effectiveBaseUrl })
|
|
2610
2801
|
};
|
|
2611
2802
|
}
|
|
2612
2803
|
var cachedLogin;
|
|
2613
|
-
function getConfig() {
|
|
2614
|
-
if (!config) {
|
|
2615
|
-
config = new Conf__default.default({ projectName: "zapier-sdk-cli" });
|
|
2616
|
-
if (!config.has("login_storage_mode")) {
|
|
2617
|
-
config.set(
|
|
2618
|
-
"login_storage_mode",
|
|
2619
|
-
fs.existsSync(config.path) ? "config" : "keychain"
|
|
2620
|
-
);
|
|
2621
|
-
}
|
|
2622
|
-
}
|
|
2623
|
-
return config;
|
|
2624
|
-
}
|
|
2625
2804
|
function unloadConfig() {
|
|
2626
|
-
|
|
2805
|
+
resetConfig();
|
|
2627
2806
|
cachedLogin = void 0;
|
|
2628
2807
|
}
|
|
2629
2808
|
async function updateLogin(loginData, options = {}) {
|
|
@@ -2896,9 +3075,7 @@ async function logout(options = {}) {
|
|
|
2896
3075
|
await clearTokensFromKeychain();
|
|
2897
3076
|
const cfg = getConfig();
|
|
2898
3077
|
cfg.set("login_storage_mode", mode);
|
|
2899
|
-
cfg
|
|
2900
|
-
cfg.delete("login_jwt");
|
|
2901
|
-
cfg.delete("login_refresh_token");
|
|
3078
|
+
clearLegacyJwtConfigKeys(cfg);
|
|
2902
3079
|
onEvent?.({
|
|
2903
3080
|
type: "auth_logout",
|
|
2904
3081
|
payload: { message: "Logged out successfully", operation: "logout" },
|
|
@@ -2910,6 +3087,79 @@ function getConfigPath() {
|
|
|
2910
3087
|
return cfg.path;
|
|
2911
3088
|
}
|
|
2912
3089
|
|
|
3090
|
+
// src/utils/retry.ts
|
|
3091
|
+
function sleep(ms) {
|
|
3092
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
3093
|
+
}
|
|
3094
|
+
async function withRetry({
|
|
3095
|
+
action,
|
|
3096
|
+
attempts = 3,
|
|
3097
|
+
initialDelayMs = 100
|
|
3098
|
+
}) {
|
|
3099
|
+
if (attempts <= 0) {
|
|
3100
|
+
throw new Error("withRetry: attempts must be greater than 0");
|
|
3101
|
+
}
|
|
3102
|
+
let lastError;
|
|
3103
|
+
for (let i = 0; i < attempts; i++) {
|
|
3104
|
+
try {
|
|
3105
|
+
return await action();
|
|
3106
|
+
} catch (err) {
|
|
3107
|
+
lastError = err;
|
|
3108
|
+
if (i < attempts - 1) {
|
|
3109
|
+
await sleep(initialDelayMs * 2 ** i);
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
}
|
|
3113
|
+
throw lastError;
|
|
3114
|
+
}
|
|
3115
|
+
|
|
3116
|
+
// src/login/credentials-revoke.ts
|
|
3117
|
+
function emitAuthLogout(onEvent) {
|
|
3118
|
+
onEvent?.({
|
|
3119
|
+
type: "auth_logout",
|
|
3120
|
+
payload: { message: "Logged out successfully", operation: "logout" },
|
|
3121
|
+
timestamp: Date.now()
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
function isNotFoundError(err) {
|
|
3125
|
+
return typeof err === "object" && err !== null && "statusCode" in err && err.statusCode === 404;
|
|
3126
|
+
}
|
|
3127
|
+
async function revokeCredentials({
|
|
3128
|
+
api: api2,
|
|
3129
|
+
credentials: credentials2,
|
|
3130
|
+
onEvent
|
|
3131
|
+
}) {
|
|
3132
|
+
await withRetry({
|
|
3133
|
+
action: async () => {
|
|
3134
|
+
try {
|
|
3135
|
+
await api2.delete(
|
|
3136
|
+
`/api/v0/client-credentials/${credentials2.clientId}`,
|
|
3137
|
+
void 0,
|
|
3138
|
+
{ authRequired: true, requiredScopes: ["credentials"] }
|
|
3139
|
+
);
|
|
3140
|
+
} catch (err) {
|
|
3141
|
+
if (isNotFoundError(err)) return;
|
|
3142
|
+
throw err;
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
});
|
|
3146
|
+
try {
|
|
3147
|
+
await deleteStoredClientCredentials({
|
|
3148
|
+
name: credentials2.name,
|
|
3149
|
+
baseUrl: credentials2.baseUrl
|
|
3150
|
+
});
|
|
3151
|
+
} catch (err) {
|
|
3152
|
+
console.warn("[revokeCredentials] Local store cleanup failed:", err);
|
|
3153
|
+
}
|
|
3154
|
+
await clearLegacyJwtState();
|
|
3155
|
+
await zapierSdk.invalidateCachedToken({
|
|
3156
|
+
clientId: credentials2.clientId,
|
|
3157
|
+
scopes: credentials2.scopes,
|
|
3158
|
+
baseUrl: credentials2.baseUrl
|
|
3159
|
+
});
|
|
3160
|
+
emitAuthLogout(onEvent);
|
|
3161
|
+
}
|
|
3162
|
+
|
|
2913
3163
|
// src/utils/constants.ts
|
|
2914
3164
|
var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
2915
3165
|
var LOGIN_TIMEOUT_MS = 3e5;
|
|
@@ -2995,6 +3245,8 @@ var getCallablePromise = () => {
|
|
|
2995
3245
|
};
|
|
2996
3246
|
};
|
|
2997
3247
|
var getCallablePromise_default = getCallablePromise;
|
|
3248
|
+
|
|
3249
|
+
// src/utils/auth/oauth-flow.ts
|
|
2998
3250
|
var findAvailablePort = () => {
|
|
2999
3251
|
return new Promise((resolve4, reject) => {
|
|
3000
3252
|
let portIndex = 0;
|
|
@@ -3029,10 +3281,9 @@ var findAvailablePort = () => {
|
|
|
3029
3281
|
var generateRandomString = () => {
|
|
3030
3282
|
const array = new Uint32Array(28);
|
|
3031
3283
|
crypto__default.default.getRandomValues(array);
|
|
3032
|
-
return Array.from(
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
).join("");
|
|
3284
|
+
return Array.from(array, (dec) => ("0" + dec.toString(16)).slice(-2)).join(
|
|
3285
|
+
""
|
|
3286
|
+
);
|
|
3036
3287
|
};
|
|
3037
3288
|
function ensureOfflineAccess(scope) {
|
|
3038
3289
|
if (scope.includes("offline_access")) {
|
|
@@ -3040,17 +3291,18 @@ function ensureOfflineAccess(scope) {
|
|
|
3040
3291
|
}
|
|
3041
3292
|
return `${scope} offline_access`;
|
|
3042
3293
|
}
|
|
3043
|
-
|
|
3294
|
+
async function runOauthFlow({
|
|
3044
3295
|
timeoutMs = LOGIN_TIMEOUT_MS,
|
|
3045
|
-
|
|
3046
|
-
|
|
3296
|
+
pkceCredentials,
|
|
3297
|
+
baseUrl: baseUrl2
|
|
3298
|
+
}) {
|
|
3047
3299
|
const { clientId, tokenUrl, authorizeUrl } = getPkceLoginConfig({
|
|
3048
|
-
credentials:
|
|
3300
|
+
credentials: pkceCredentials,
|
|
3301
|
+
baseUrl: baseUrl2
|
|
3049
3302
|
});
|
|
3050
3303
|
const scope = ensureOfflineAccess(
|
|
3051
|
-
|
|
3304
|
+
pkceCredentials?.scope || "internal credentials"
|
|
3052
3305
|
);
|
|
3053
|
-
await logout();
|
|
3054
3306
|
const availablePort = await findAvailablePort();
|
|
3055
3307
|
const redirectUri = `http://localhost:${availablePort}/oauth`;
|
|
3056
3308
|
log_default.info(`Using port ${availablePort} for OAuth callback`);
|
|
@@ -3059,13 +3311,30 @@ var login = async ({
|
|
|
3059
3311
|
resolve: setCode,
|
|
3060
3312
|
reject: rejectCode
|
|
3061
3313
|
} = getCallablePromise_default();
|
|
3062
|
-
const
|
|
3063
|
-
|
|
3064
|
-
|
|
3314
|
+
const oauthState = generateRandomString();
|
|
3315
|
+
const expressApp = express__default.default();
|
|
3316
|
+
expressApp.get("/oauth", (req, res) => {
|
|
3065
3317
|
res.setHeader("Connection", "close");
|
|
3318
|
+
if (req.query.state !== oauthState) {
|
|
3319
|
+
rejectCode(new Error("OAuth state mismatch \u2014 possible CSRF"));
|
|
3320
|
+
res.status(400).end("Invalid state. You can close this tab.");
|
|
3321
|
+
return;
|
|
3322
|
+
}
|
|
3323
|
+
if (req.query.error) {
|
|
3324
|
+
const desc = req.query.error_description ?? req.query.error;
|
|
3325
|
+
rejectCode(new Error(`Authorization denied: ${desc}`));
|
|
3326
|
+
res.end("Authorization was denied. You can close this tab.");
|
|
3327
|
+
return;
|
|
3328
|
+
}
|
|
3329
|
+
if (!req.query.code) {
|
|
3330
|
+
rejectCode(new Error("No authorization code received"));
|
|
3331
|
+
res.end("No authorization code received. You can close this tab.");
|
|
3332
|
+
return;
|
|
3333
|
+
}
|
|
3334
|
+
setCode(String(req.query.code));
|
|
3066
3335
|
res.end("You can now close this tab and return to the CLI.");
|
|
3067
3336
|
});
|
|
3068
|
-
const server =
|
|
3337
|
+
const server = expressApp.listen(availablePort);
|
|
3069
3338
|
const connections = /* @__PURE__ */ new Set();
|
|
3070
3339
|
server.on("connection", (conn) => {
|
|
3071
3340
|
connections.add(conn);
|
|
@@ -3084,7 +3353,7 @@ var login = async ({
|
|
|
3084
3353
|
client_id: clientId,
|
|
3085
3354
|
redirect_uri: redirectUri,
|
|
3086
3355
|
scope,
|
|
3087
|
-
state:
|
|
3356
|
+
state: oauthState,
|
|
3088
3357
|
code_challenge: codeChallenge,
|
|
3089
3358
|
code_challenge_method: "S256"
|
|
3090
3359
|
}).toString()}`;
|
|
@@ -3143,36 +3412,79 @@ var login = async ({
|
|
|
3143
3412
|
}
|
|
3144
3413
|
}
|
|
3145
3414
|
);
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3415
|
+
log_default.info("Token exchange completed successfully");
|
|
3416
|
+
return {
|
|
3417
|
+
accessToken: data.access_token,
|
|
3418
|
+
refreshToken: data.refresh_token,
|
|
3419
|
+
expiresIn: data.expires_in
|
|
3420
|
+
};
|
|
3421
|
+
}
|
|
3422
|
+
|
|
3423
|
+
// src/utils/auth/client-credentials.ts
|
|
3424
|
+
var CREDENTIALS_SCOPES = ["external", "credentials"];
|
|
3425
|
+
async function createCredentialsOnServer(api2, name) {
|
|
3426
|
+
const response = await api2.post(
|
|
3427
|
+
"/api/v0/client-credentials",
|
|
3428
|
+
{ name, allowed_scopes: CREDENTIALS_SCOPES },
|
|
3429
|
+
{ authRequired: true, requiredScopes: ["credentials"] }
|
|
3430
|
+
);
|
|
3431
|
+
return {
|
|
3432
|
+
clientId: response.data.client_id,
|
|
3433
|
+
clientSecret: response.data.client_secret
|
|
3434
|
+
};
|
|
3435
|
+
}
|
|
3436
|
+
async function deleteCredentialsOnServer(api2, clientId) {
|
|
3437
|
+
await api2.delete(`/api/v0/client-credentials/${clientId}`, void 0, {
|
|
3438
|
+
authRequired: true,
|
|
3439
|
+
requiredScopes: ["credentials"]
|
|
3440
|
+
});
|
|
3441
|
+
}
|
|
3442
|
+
async function setupClientCredentials({
|
|
3443
|
+
api: api2,
|
|
3444
|
+
name,
|
|
3445
|
+
credentialsBaseUrl: credentialsBaseUrl2
|
|
3446
|
+
}) {
|
|
3447
|
+
const { clientId, clientSecret } = await createCredentialsOnServer(api2, name);
|
|
3160
3448
|
try {
|
|
3161
|
-
await
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3449
|
+
await withRetry({
|
|
3450
|
+
action: () => storeClientCredentials({
|
|
3451
|
+
name,
|
|
3452
|
+
clientId,
|
|
3453
|
+
clientSecret,
|
|
3454
|
+
scopes: [...CREDENTIALS_SCOPES],
|
|
3455
|
+
baseUrl: credentialsBaseUrl2
|
|
3456
|
+
})
|
|
3457
|
+
});
|
|
3458
|
+
} catch (storeErr) {
|
|
3459
|
+
try {
|
|
3460
|
+
await withRetry({
|
|
3461
|
+
action: () => deleteCredentialsOnServer(api2, clientId)
|
|
3462
|
+
});
|
|
3463
|
+
} catch {
|
|
3464
|
+
console.error(
|
|
3465
|
+
`Failed to roll back orphaned credential ${clientId}. Delete it manually with: zapier-sdk delete-client-credentials ${clientId}`
|
|
3166
3466
|
);
|
|
3167
|
-
await updateLogin(data, { storage: "config" });
|
|
3168
|
-
} else {
|
|
3169
|
-
throw err;
|
|
3170
3467
|
}
|
|
3468
|
+
throw storeErr;
|
|
3171
3469
|
}
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3470
|
+
return { clientId };
|
|
3471
|
+
}
|
|
3472
|
+
function getBaseUrlFromResolvedCredentials(credentials2) {
|
|
3473
|
+
if (credentials2 && zapierSdk.isCredentialsObject(credentials2)) {
|
|
3474
|
+
return credentials2.baseUrl;
|
|
3475
|
+
}
|
|
3476
|
+
return void 0;
|
|
3477
|
+
}
|
|
3478
|
+
function getBaseUrlFromOptionsCredentials(credentials2) {
|
|
3479
|
+
if (credentials2 && typeof credentials2 === "object" && "baseUrl" in credentials2 && typeof credentials2.baseUrl === "string") {
|
|
3480
|
+
return credentials2.baseUrl;
|
|
3481
|
+
}
|
|
3482
|
+
return void 0;
|
|
3483
|
+
}
|
|
3484
|
+
async function resolveCredentialsBaseUrl(context) {
|
|
3485
|
+
const resolvedCredentials = "resolvedCredentials" in context ? context.resolvedCredentials : await context.resolveCredentials?.();
|
|
3486
|
+
return getBaseUrlFromResolvedCredentials(resolvedCredentials) ?? getBaseUrlFromOptionsCredentials(context.options?.credentials) ?? context.options?.baseUrl;
|
|
3487
|
+
}
|
|
3176
3488
|
var LoginSchema = zod.z.object({
|
|
3177
3489
|
timeout: zod.z.string().optional().describe("Login timeout in seconds (default: 300)")
|
|
3178
3490
|
}).describe("Log in to Zapier to access your account");
|
|
@@ -3189,6 +3501,105 @@ function toPkceCredentials(credentials2) {
|
|
|
3189
3501
|
}
|
|
3190
3502
|
return void 0;
|
|
3191
3503
|
}
|
|
3504
|
+
async function confirmRevokeAndRelogin(activeCredentials) {
|
|
3505
|
+
const { confirmed } = await inquirer__default.default.prompt([
|
|
3506
|
+
{
|
|
3507
|
+
type: "confirm",
|
|
3508
|
+
name: "confirmed",
|
|
3509
|
+
message: `You are already logged in as "${activeCredentials.name}".
|
|
3510
|
+
Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
|
|
3511
|
+
Log out and log in again?`,
|
|
3512
|
+
default: false
|
|
3513
|
+
}
|
|
3514
|
+
]);
|
|
3515
|
+
if (!confirmed) {
|
|
3516
|
+
console.log("Login cancelled.");
|
|
3517
|
+
return false;
|
|
3518
|
+
}
|
|
3519
|
+
return true;
|
|
3520
|
+
}
|
|
3521
|
+
async function confirmJwtMigration() {
|
|
3522
|
+
const { confirmed } = await inquirer__default.default.prompt([
|
|
3523
|
+
{
|
|
3524
|
+
type: "confirm",
|
|
3525
|
+
name: "confirmed",
|
|
3526
|
+
message: "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?",
|
|
3527
|
+
default: true
|
|
3528
|
+
}
|
|
3529
|
+
]);
|
|
3530
|
+
if (!confirmed) {
|
|
3531
|
+
console.log("Login cancelled.");
|
|
3532
|
+
return false;
|
|
3533
|
+
}
|
|
3534
|
+
return true;
|
|
3535
|
+
}
|
|
3536
|
+
async function confirmLocalLoginReset() {
|
|
3537
|
+
const { confirmed } = await inquirer__default.default.prompt([
|
|
3538
|
+
{
|
|
3539
|
+
type: "confirm",
|
|
3540
|
+
name: "confirmed",
|
|
3541
|
+
message: "Login cleanup failed. Reset local session state and continue?",
|
|
3542
|
+
default: false
|
|
3543
|
+
}
|
|
3544
|
+
]);
|
|
3545
|
+
if (!confirmed) {
|
|
3546
|
+
console.log("Login cancelled.");
|
|
3547
|
+
return false;
|
|
3548
|
+
}
|
|
3549
|
+
return true;
|
|
3550
|
+
}
|
|
3551
|
+
function parseTimeoutSeconds(timeout) {
|
|
3552
|
+
const timeoutSeconds = timeout ? parseInt(timeout, 10) : 300;
|
|
3553
|
+
if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
3554
|
+
throw new Error("Timeout must be a positive number");
|
|
3555
|
+
}
|
|
3556
|
+
return timeoutSeconds;
|
|
3557
|
+
}
|
|
3558
|
+
async function promptCredentialsName(email, baseUrl2) {
|
|
3559
|
+
const { credentialName } = await inquirer__default.default.prompt([
|
|
3560
|
+
{
|
|
3561
|
+
type: "input",
|
|
3562
|
+
name: "credentialName",
|
|
3563
|
+
message: "Enter a name to identify them:",
|
|
3564
|
+
default: `${email}@${os.hostname()}`,
|
|
3565
|
+
validate: (input) => {
|
|
3566
|
+
if (!input.trim()) return "Name cannot be empty";
|
|
3567
|
+
if (credentialsNameExists({ name: input.trim(), baseUrl: baseUrl2 })) {
|
|
3568
|
+
return `Credentials named "${input.trim()}" already exist. Please provide a different name.`;
|
|
3569
|
+
}
|
|
3570
|
+
return true;
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
]);
|
|
3574
|
+
return credentialName;
|
|
3575
|
+
}
|
|
3576
|
+
function emitLoginSuccess({
|
|
3577
|
+
sdk,
|
|
3578
|
+
profile
|
|
3579
|
+
}) {
|
|
3580
|
+
sdk.context.eventEmission.emit(
|
|
3581
|
+
"platform.sdk.ApplicationLifecycleEvent",
|
|
3582
|
+
zapierSdk.buildApplicationLifecycleEvent(
|
|
3583
|
+
{ lifecycle_event_type: "login_success" },
|
|
3584
|
+
{
|
|
3585
|
+
customuser_id: profile.user_id,
|
|
3586
|
+
account_id: profile.roles[0]?.account_id ?? null
|
|
3587
|
+
}
|
|
3588
|
+
)
|
|
3589
|
+
);
|
|
3590
|
+
}
|
|
3591
|
+
async function getProfile(api2) {
|
|
3592
|
+
return api2.get("/zapier/api/v4/profile/", {
|
|
3593
|
+
authRequired: true
|
|
3594
|
+
});
|
|
3595
|
+
}
|
|
3596
|
+
async function bestEffortClearLegacyJwtState() {
|
|
3597
|
+
try {
|
|
3598
|
+
await clearLegacyJwtState();
|
|
3599
|
+
} catch (err) {
|
|
3600
|
+
console.error("[login] Best-effort legacy JWT cleanup failed:", err);
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3192
3603
|
var loginPlugin = zapierSdk.definePlugin(
|
|
3193
3604
|
(sdk) => zapierSdk.createPluginMethod(sdk, {
|
|
3194
3605
|
name: "login",
|
|
@@ -3196,25 +3607,61 @@ var loginPlugin = zapierSdk.definePlugin(
|
|
|
3196
3607
|
inputSchema: LoginSchema,
|
|
3197
3608
|
supportsJsonOutput: false,
|
|
3198
3609
|
handler: async ({ sdk: sdk2, options }) => {
|
|
3199
|
-
const timeoutSeconds =
|
|
3200
|
-
if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
3201
|
-
throw new Error("Timeout must be a positive number");
|
|
3202
|
-
}
|
|
3610
|
+
const timeoutSeconds = parseTimeoutSeconds(options.timeout);
|
|
3203
3611
|
const resolvedCredentials = await sdk2.context.resolveCredentials();
|
|
3204
3612
|
const pkceCredentials = toPkceCredentials(resolvedCredentials);
|
|
3205
|
-
await
|
|
3613
|
+
const credentialsBaseUrl2 = await resolveCredentialsBaseUrl({
|
|
3614
|
+
...sdk2.context,
|
|
3615
|
+
resolvedCredentials
|
|
3616
|
+
});
|
|
3617
|
+
const activeCredentials = getActiveCredentials({
|
|
3618
|
+
baseUrl: credentialsBaseUrl2
|
|
3619
|
+
});
|
|
3620
|
+
if (activeCredentials) {
|
|
3621
|
+
if (!await confirmRevokeAndRelogin(activeCredentials)) return;
|
|
3622
|
+
try {
|
|
3623
|
+
await revokeCredentials({
|
|
3624
|
+
api: sdk2.context.api,
|
|
3625
|
+
credentials: activeCredentials
|
|
3626
|
+
});
|
|
3627
|
+
} catch {
|
|
3628
|
+
if (!await confirmLocalLoginReset()) return;
|
|
3629
|
+
await deleteStoredClientCredentials({
|
|
3630
|
+
name: activeCredentials.name,
|
|
3631
|
+
baseUrl: activeCredentials.baseUrl
|
|
3632
|
+
});
|
|
3633
|
+
}
|
|
3634
|
+
} else if (hasLegacyJwtConfig()) {
|
|
3635
|
+
if (!await confirmJwtMigration()) return;
|
|
3636
|
+
}
|
|
3637
|
+
const { accessToken } = await runOauthFlow({
|
|
3206
3638
|
timeoutMs: timeoutSeconds * 1e3,
|
|
3207
|
-
|
|
3639
|
+
pkceCredentials,
|
|
3640
|
+
baseUrl: credentialsBaseUrl2
|
|
3208
3641
|
});
|
|
3209
|
-
const
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3642
|
+
const scopedApi = zapierSdk.getOrCreateApiClient({
|
|
3643
|
+
credentials: accessToken,
|
|
3644
|
+
baseUrl: credentialsBaseUrl2
|
|
3645
|
+
});
|
|
3646
|
+
const profile = await getProfile(scopedApi);
|
|
3647
|
+
console.log(`\u{1F464} Logged in as ${profile.email}`);
|
|
3648
|
+
console.log(
|
|
3649
|
+
"\nGenerating credentials so this machine can make authenticated requests on your behalf."
|
|
3650
|
+
);
|
|
3651
|
+
const credentialName = await promptCredentialsName(
|
|
3652
|
+
profile.email,
|
|
3653
|
+
credentialsBaseUrl2
|
|
3216
3654
|
);
|
|
3217
|
-
|
|
3655
|
+
await setupClientCredentials({
|
|
3656
|
+
api: scopedApi,
|
|
3657
|
+
name: credentialName,
|
|
3658
|
+
credentialsBaseUrl: credentialsBaseUrl2
|
|
3659
|
+
});
|
|
3660
|
+
await bestEffortClearLegacyJwtState();
|
|
3661
|
+
console.log(
|
|
3662
|
+
`\u2705 Credentials "${credentialName}" created and set as default. You are ready to use the Zapier SDK.`
|
|
3663
|
+
);
|
|
3664
|
+
emitLoginSuccess({ sdk: sdk2, profile });
|
|
3218
3665
|
}
|
|
3219
3666
|
})
|
|
3220
3667
|
);
|
|
@@ -3227,8 +3674,36 @@ var logoutPlugin = zapierSdk.definePlugin(
|
|
|
3227
3674
|
categories: ["account"],
|
|
3228
3675
|
inputSchema: LogoutSchema,
|
|
3229
3676
|
supportsJsonOutput: false,
|
|
3230
|
-
handler: async () => {
|
|
3231
|
-
await
|
|
3677
|
+
handler: async ({ sdk: sdk2 }) => {
|
|
3678
|
+
const credentialsBaseUrl2 = await resolveCredentialsBaseUrl(sdk2.context);
|
|
3679
|
+
const activeCredentials = getActiveCredentials({
|
|
3680
|
+
baseUrl: credentialsBaseUrl2
|
|
3681
|
+
});
|
|
3682
|
+
const onEvent = sdk2.context.options?.onEvent;
|
|
3683
|
+
if (!activeCredentials) {
|
|
3684
|
+
await logout({ onEvent });
|
|
3685
|
+
console.log("\u2705 Successfully logged out");
|
|
3686
|
+
return;
|
|
3687
|
+
}
|
|
3688
|
+
const { confirmed } = await inquirer__default.default.prompt([
|
|
3689
|
+
{
|
|
3690
|
+
type: "confirm",
|
|
3691
|
+
name: "confirmed",
|
|
3692
|
+
message: `Logging out will delete credentials "${activeCredentials.name}".
|
|
3693
|
+
This may interrupt other Zapier SDK or CLI sessions using them.
|
|
3694
|
+
Do you want to continue?`,
|
|
3695
|
+
default: true
|
|
3696
|
+
}
|
|
3697
|
+
]);
|
|
3698
|
+
if (!confirmed) {
|
|
3699
|
+
console.log("Logout cancelled.");
|
|
3700
|
+
return;
|
|
3701
|
+
}
|
|
3702
|
+
await revokeCredentials({
|
|
3703
|
+
api: sdk2.context.api,
|
|
3704
|
+
credentials: activeCredentials,
|
|
3705
|
+
onEvent
|
|
3706
|
+
});
|
|
3232
3707
|
console.log("\u2705 Successfully logged out");
|
|
3233
3708
|
}
|
|
3234
3709
|
})
|
|
@@ -3247,6 +3722,7 @@ var mcpPlugin = zapierSdk.definePlugin(
|
|
|
3247
3722
|
await zapierSdkMcp.startMcpServer({
|
|
3248
3723
|
...options,
|
|
3249
3724
|
debug: sdk2.context.options?.debug,
|
|
3725
|
+
maxConcurrentRequests: sdk2.context.options?.maxConcurrentRequests,
|
|
3250
3726
|
extensions: sdk2.context.extensions,
|
|
3251
3727
|
experimental: sdk2.context.experimental
|
|
3252
3728
|
});
|
|
@@ -5745,7 +6221,7 @@ var watchTriggerInboxCliPlugin = zapierSdk.definePlugin(
|
|
|
5745
6221
|
// package.json with { type: 'json' }
|
|
5746
6222
|
var package_default2 = {
|
|
5747
6223
|
name: "@zapier/zapier-sdk-cli",
|
|
5748
|
-
version: "0.
|
|
6224
|
+
version: "0.48.1"};
|
|
5749
6225
|
|
|
5750
6226
|
// src/sdk.ts
|
|
5751
6227
|
zapierSdk.injectCliLogin(login_exports);
|
|
@@ -6007,6 +6483,9 @@ program.name("zapier-sdk").description("CLI for Zapier SDK").version(
|
|
|
6007
6483
|
).option(
|
|
6008
6484
|
"--max-network-retry-delay-ms <ms>",
|
|
6009
6485
|
"Max delay in ms to wait for rate limit retry (default: 60000)"
|
|
6486
|
+
).option(
|
|
6487
|
+
"--max-concurrent-requests <count>",
|
|
6488
|
+
"Max concurrent in-flight HTTP requests (default: 200). Pass 'Infinity' to disable."
|
|
6010
6489
|
).option("--experimental", "Use the experimental SDK / CLI surface");
|
|
6011
6490
|
var booleanFlags = [];
|
|
6012
6491
|
for (const [key, fieldSchema] of Object.entries(
|
|
@@ -6030,8 +6509,13 @@ program.helpOption(
|
|
|
6030
6509
|
);
|
|
6031
6510
|
var isDebugMode = process.env.DEBUG === "true" || process.argv.includes("--debug");
|
|
6032
6511
|
function getFlagValue(flagName) {
|
|
6033
|
-
const
|
|
6034
|
-
|
|
6512
|
+
const prefix = `${flagName}=`;
|
|
6513
|
+
for (let i = 0; i < process.argv.length; i++) {
|
|
6514
|
+
const arg = process.argv[i];
|
|
6515
|
+
if (arg === flagName) return process.argv[i + 1];
|
|
6516
|
+
if (arg.startsWith(prefix)) return arg.slice(prefix.length);
|
|
6517
|
+
}
|
|
6518
|
+
return void 0;
|
|
6035
6519
|
}
|
|
6036
6520
|
var baseUrl = getFlagValue("--base-url");
|
|
6037
6521
|
var credentialsToken = getFlagValue("--credentials");
|
|
@@ -6043,6 +6527,16 @@ var maxNetworkRetriesStr = getFlagValue("--max-network-retries");
|
|
|
6043
6527
|
var maxNetworkRetries = maxNetworkRetriesStr ? parseInt(maxNetworkRetriesStr, 10) : void 0;
|
|
6044
6528
|
var maxNetworkRetryDelayMsStr = getFlagValue("--max-network-retry-delay-ms");
|
|
6045
6529
|
var maxNetworkRetryDelayMs = maxNetworkRetryDelayMsStr ? parseInt(maxNetworkRetryDelayMsStr, 10) : void 0;
|
|
6530
|
+
var maxConcurrentRequestsStr = getFlagValue("--max-concurrent-requests");
|
|
6531
|
+
var maxConcurrentRequests;
|
|
6532
|
+
if (maxConcurrentRequestsStr === void 0) {
|
|
6533
|
+
maxConcurrentRequests = void 0;
|
|
6534
|
+
} else if (maxConcurrentRequestsStr === "Infinity") {
|
|
6535
|
+
maxConcurrentRequests = Infinity;
|
|
6536
|
+
} else {
|
|
6537
|
+
const parsed = parseInt(maxConcurrentRequestsStr, 10);
|
|
6538
|
+
maxConcurrentRequests = Number.isFinite(parsed) ? parsed : NaN;
|
|
6539
|
+
}
|
|
6046
6540
|
function buildCredentialsFromFlags() {
|
|
6047
6541
|
if (credentialsToken) {
|
|
6048
6542
|
return credentialsToken;
|
|
@@ -6085,6 +6579,7 @@ program.exitOverride();
|
|
|
6085
6579
|
trackingBaseUrl,
|
|
6086
6580
|
maxNetworkRetries,
|
|
6087
6581
|
maxNetworkRetryDelayMs,
|
|
6582
|
+
maxConcurrentRequests,
|
|
6088
6583
|
...flagOverrides,
|
|
6089
6584
|
extensions
|
|
6090
6585
|
});
|