@zapier/zapier-sdk-cli 0.42.2 → 0.43.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 +21 -0
- package/dist/cli.cjs +1047 -547
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.mjs +1034 -537
- package/dist/index.cjs +1037 -538
- package/dist/index.d.mts +395 -23
- package/dist/index.d.ts +395 -23
- package/dist/index.mjs +1027 -531
- package/dist/login.cjs +599 -7
- package/dist/login.d.mts +144 -1
- package/dist/login.d.ts +144 -1
- package/dist/login.mjs +565 -1
- package/dist/package.json +5 -2
- package/dist/src/login/filesystem-cache.d.ts +25 -0
- package/dist/src/login/filesystem-cache.js +195 -0
- package/dist/src/login/index.d.ts +115 -0
- package/dist/src/login/index.js +442 -0
- package/dist/src/login/keychain.d.ts +18 -0
- package/dist/src/login/keychain.js +74 -0
- package/dist/src/login.d.ts +10 -1
- package/dist/src/login.js +10 -1
- package/dist/src/plugins/add/index.d.ts +250 -11
- package/dist/src/plugins/add/index.js +8 -16
- package/dist/src/plugins/buildManifest/index.d.ts +116 -9
- package/dist/src/plugins/buildManifest/index.js +14 -23
- package/dist/src/plugins/bundleCode/index.d.ts +19 -10
- package/dist/src/plugins/bundleCode/index.js +7 -17
- package/dist/src/plugins/cliOverrides/index.d.ts +12 -10
- package/dist/src/plugins/cliOverrides/index.js +16 -20
- package/dist/src/plugins/curl/index.d.ts +69 -10
- package/dist/src/plugins/curl/index.js +3 -2
- package/dist/src/plugins/feedback/index.d.ts +18 -13
- package/dist/src/plugins/feedback/index.js +18 -26
- package/dist/src/plugins/generateAppTypes/index.d.ts +261 -9
- package/dist/src/plugins/generateAppTypes/index.js +17 -45
- package/dist/src/plugins/getLoginConfigPath/index.d.ts +12 -10
- package/dist/src/plugins/getLoginConfigPath/index.js +9 -19
- package/dist/src/plugins/init/index.d.ts +15 -11
- package/dist/src/plugins/init/index.js +9 -17
- package/dist/src/plugins/login/index.d.ts +18 -13
- package/dist/src/plugins/login/index.js +10 -18
- package/dist/src/plugins/logout/index.d.ts +12 -11
- package/dist/src/plugins/logout/index.js +11 -17
- package/dist/src/plugins/mcp/index.d.ts +18 -15
- package/dist/src/plugins/mcp/index.js +9 -21
- package/dist/src/sdk.js +1 -1
- package/dist/src/utils/auth/login.d.ts +1 -1
- package/dist/src/utils/auth/login.js +1 -1
- package/dist/src/utils/constants.d.ts +1 -1
- package/dist/src/utils/constants.js +1 -1
- package/dist/src/utils/version-checker.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -4
package/dist/cli.cjs
CHANGED
|
@@ -9,15 +9,18 @@ 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
|
|
13
|
-
var
|
|
12
|
+
var Conf = require('conf');
|
|
13
|
+
var fs = require('fs');
|
|
14
|
+
var jwt = require('jsonwebtoken');
|
|
15
|
+
var crossKeychain = require('cross-keychain');
|
|
14
16
|
var crypto = require('crypto');
|
|
17
|
+
var path = require('path');
|
|
18
|
+
var lockfile = require('proper-lockfile');
|
|
19
|
+
var open = require('open');
|
|
15
20
|
var express = require('express');
|
|
16
21
|
var pkceChallenge = require('pkce-challenge');
|
|
17
22
|
var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
|
|
18
23
|
var esbuild = require('esbuild');
|
|
19
|
-
var fs = require('fs');
|
|
20
|
-
var path = require('path');
|
|
21
24
|
var promises = require('fs/promises');
|
|
22
25
|
var ts = require('typescript');
|
|
23
26
|
var isInstalledGlobally = require('is-installed-globally');
|
|
@@ -53,19 +56,26 @@ var chalk7__default = /*#__PURE__*/_interopDefault(chalk7);
|
|
|
53
56
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
54
57
|
var util__default = /*#__PURE__*/_interopDefault(util);
|
|
55
58
|
var wrapAnsi__default = /*#__PURE__*/_interopDefault(wrapAnsi);
|
|
56
|
-
var
|
|
57
|
-
var
|
|
59
|
+
var Conf__default = /*#__PURE__*/_interopDefault(Conf);
|
|
60
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
61
|
+
var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
|
|
58
62
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
63
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
64
|
+
var lockfile__namespace = /*#__PURE__*/_interopNamespace(lockfile);
|
|
65
|
+
var open__default = /*#__PURE__*/_interopDefault(open);
|
|
59
66
|
var express__default = /*#__PURE__*/_interopDefault(express);
|
|
60
67
|
var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
|
|
61
|
-
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
62
|
-
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
63
68
|
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
64
69
|
var isInstalledGlobally__default = /*#__PURE__*/_interopDefault(isInstalledGlobally);
|
|
65
70
|
var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
|
|
66
71
|
var packageJsonLib__default = /*#__PURE__*/_interopDefault(packageJsonLib);
|
|
67
72
|
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
68
73
|
|
|
74
|
+
var __defProp = Object.defineProperty;
|
|
75
|
+
var __export = (target, all) => {
|
|
76
|
+
for (var name in all)
|
|
77
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
78
|
+
};
|
|
69
79
|
var ZapierCliError = class extends zapierSdk.ZapierError {
|
|
70
80
|
};
|
|
71
81
|
var ZapierCliUserCancellationError = class extends ZapierCliError {
|
|
@@ -1103,7 +1113,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
1103
1113
|
|
|
1104
1114
|
// package.json
|
|
1105
1115
|
var package_default = {
|
|
1106
|
-
version: "0.
|
|
1116
|
+
version: "0.43.1"};
|
|
1107
1117
|
|
|
1108
1118
|
// src/telemetry/builders.ts
|
|
1109
1119
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1833,8 +1843,8 @@ function generateCliCommands(program2, sdk2) {
|
|
|
1833
1843
|
return;
|
|
1834
1844
|
}
|
|
1835
1845
|
const cliCommandName = methodNameToCliCommand(fnInfo.name);
|
|
1836
|
-
const
|
|
1837
|
-
addCommand(program2, cliCommandName,
|
|
1846
|
+
const config2 = createCommandConfig(cliCommandName, fnInfo, sdk2);
|
|
1847
|
+
addCommand(program2, cliCommandName, config2);
|
|
1838
1848
|
});
|
|
1839
1849
|
program2.configureHelp({
|
|
1840
1850
|
formatHelp: (cmd, helper) => {
|
|
@@ -2091,10 +2101,10 @@ function collect(value, previous = []) {
|
|
|
2091
2101
|
previous.push(value);
|
|
2092
2102
|
return previous;
|
|
2093
2103
|
}
|
|
2094
|
-
function addCommand(program2, commandName,
|
|
2095
|
-
const command = program2.command(commandName, { hidden:
|
|
2104
|
+
function addCommand(program2, commandName, config2) {
|
|
2105
|
+
const command = program2.command(commandName, { hidden: config2.hidden ?? false }).description(config2.description);
|
|
2096
2106
|
let hasPositionalArray = false;
|
|
2097
|
-
|
|
2107
|
+
config2.parameters.forEach((param) => {
|
|
2098
2108
|
const kebabName = toKebabCase(param.name);
|
|
2099
2109
|
if (param.hasResolver && param.required) {
|
|
2100
2110
|
command.argument(
|
|
@@ -2128,7 +2138,7 @@ function addCommand(program2, commandName, config) {
|
|
|
2128
2138
|
);
|
|
2129
2139
|
} else {
|
|
2130
2140
|
const flags = [];
|
|
2131
|
-
const alias =
|
|
2141
|
+
const alias = config2.aliases?.[param.name];
|
|
2132
2142
|
if (alias && alias.length === 1) {
|
|
2133
2143
|
flags.push(`-${alias}`);
|
|
2134
2144
|
}
|
|
@@ -2157,13 +2167,13 @@ function addCommand(program2, commandName, config) {
|
|
|
2157
2167
|
}
|
|
2158
2168
|
}
|
|
2159
2169
|
});
|
|
2160
|
-
const paramNames = new Set(
|
|
2170
|
+
const paramNames = new Set(config2.parameters.map((p) => p.name));
|
|
2161
2171
|
SHARED_COMMAND_CLI_OPTIONS.forEach((opt) => {
|
|
2162
2172
|
if (paramNames.has(opt.name)) return;
|
|
2163
|
-
if (
|
|
2173
|
+
if (config2.supportsJsonOutput === false && opt.name === "json") return;
|
|
2164
2174
|
command.option(opt.flag, opt.description);
|
|
2165
2175
|
});
|
|
2166
|
-
command.action(
|
|
2176
|
+
command.action(config2.handler);
|
|
2167
2177
|
}
|
|
2168
2178
|
function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
2169
2179
|
const sdkParams = {};
|
|
@@ -2235,6 +2245,581 @@ function convertValue(value, type, elementType) {
|
|
|
2235
2245
|
return value;
|
|
2236
2246
|
}
|
|
2237
2247
|
}
|
|
2248
|
+
|
|
2249
|
+
// src/login.ts
|
|
2250
|
+
var login_exports = {};
|
|
2251
|
+
__export(login_exports, {
|
|
2252
|
+
AUTH_MODE_HEADER: () => AUTH_MODE_HEADER,
|
|
2253
|
+
ZapierAuthenticationError: () => ZapierAuthenticationError,
|
|
2254
|
+
createCache: () => createCache,
|
|
2255
|
+
getAuthAuthorizeUrl: () => getAuthAuthorizeUrl,
|
|
2256
|
+
getAuthTokenUrl: () => getAuthTokenUrl,
|
|
2257
|
+
getConfig: () => getConfig,
|
|
2258
|
+
getConfigPath: () => getConfigPath,
|
|
2259
|
+
getLoggedInUser: () => getLoggedInUser,
|
|
2260
|
+
getLoginStorageMode: () => getLoginStorageMode,
|
|
2261
|
+
getPkceLoginConfig: () => getPkceLoginConfig,
|
|
2262
|
+
getToken: () => getToken,
|
|
2263
|
+
logout: () => logout,
|
|
2264
|
+
unloadConfig: () => unloadConfig,
|
|
2265
|
+
updateLogin: () => updateLogin
|
|
2266
|
+
});
|
|
2267
|
+
var SERVICE = "zapier-sdk-cli";
|
|
2268
|
+
var ACCOUNT = "login";
|
|
2269
|
+
var cachedBackendInfo;
|
|
2270
|
+
async function getBackendInfo() {
|
|
2271
|
+
if (!cachedBackendInfo) {
|
|
2272
|
+
const keyring = await crossKeychain.getKeyring();
|
|
2273
|
+
cachedBackendInfo = `${keyring.name} (${keyring.id})`;
|
|
2274
|
+
}
|
|
2275
|
+
return cachedBackendInfo;
|
|
2276
|
+
}
|
|
2277
|
+
var keychainQueue = Promise.resolve();
|
|
2278
|
+
function enqueue(fn) {
|
|
2279
|
+
const result = keychainQueue.then(fn, fn);
|
|
2280
|
+
keychainQueue = result.then(
|
|
2281
|
+
() => {
|
|
2282
|
+
},
|
|
2283
|
+
() => {
|
|
2284
|
+
}
|
|
2285
|
+
);
|
|
2286
|
+
return result;
|
|
2287
|
+
}
|
|
2288
|
+
async function getTokensFromKeychain({
|
|
2289
|
+
debugLog
|
|
2290
|
+
} = {}) {
|
|
2291
|
+
return enqueue(async () => {
|
|
2292
|
+
const backendInfo = await getBackendInfo();
|
|
2293
|
+
debugLog?.(`Keychain read via ${backendInfo}`);
|
|
2294
|
+
const startTime = Date.now();
|
|
2295
|
+
const raw = await crossKeychain.getPassword(SERVICE, ACCOUNT);
|
|
2296
|
+
debugLog?.(`Keychain read completed in ${Date.now() - startTime}ms`);
|
|
2297
|
+
if (!raw) {
|
|
2298
|
+
debugLog?.("Keychain returned no data");
|
|
2299
|
+
return void 0;
|
|
2300
|
+
}
|
|
2301
|
+
let parsed;
|
|
2302
|
+
try {
|
|
2303
|
+
parsed = JSON.parse(raw);
|
|
2304
|
+
} catch {
|
|
2305
|
+
debugLog?.("Keychain data is not valid JSON");
|
|
2306
|
+
return void 0;
|
|
2307
|
+
}
|
|
2308
|
+
if (typeof parsed.login_jwt === "string" && typeof parsed.login_refresh_token === "string") {
|
|
2309
|
+
return {
|
|
2310
|
+
login_jwt: parsed.login_jwt,
|
|
2311
|
+
login_refresh_token: parsed.login_refresh_token
|
|
2312
|
+
};
|
|
2313
|
+
}
|
|
2314
|
+
debugLog?.("Keychain data has invalid shape", parsed);
|
|
2315
|
+
return void 0;
|
|
2316
|
+
});
|
|
2317
|
+
}
|
|
2318
|
+
async function setTokensInKeychain({
|
|
2319
|
+
data,
|
|
2320
|
+
debugLog
|
|
2321
|
+
}) {
|
|
2322
|
+
return enqueue(async () => {
|
|
2323
|
+
const backendInfo = await getBackendInfo();
|
|
2324
|
+
debugLog?.(`Keychain write via ${backendInfo}`);
|
|
2325
|
+
const startTime = Date.now();
|
|
2326
|
+
await crossKeychain.setPassword(SERVICE, ACCOUNT, JSON.stringify(data));
|
|
2327
|
+
debugLog?.(`Keychain write completed in ${Date.now() - startTime}ms`);
|
|
2328
|
+
});
|
|
2329
|
+
}
|
|
2330
|
+
async function clearTokensFromKeychain({
|
|
2331
|
+
debugLog
|
|
2332
|
+
} = {}) {
|
|
2333
|
+
return enqueue(async () => {
|
|
2334
|
+
try {
|
|
2335
|
+
const backendInfo = await getBackendInfo();
|
|
2336
|
+
debugLog?.(`Keychain clear via ${backendInfo}`);
|
|
2337
|
+
await crossKeychain.deletePassword(SERVICE, ACCOUNT);
|
|
2338
|
+
} catch {
|
|
2339
|
+
}
|
|
2340
|
+
});
|
|
2341
|
+
}
|
|
2342
|
+
var SERVICE2 = "zapier-sdk-cache";
|
|
2343
|
+
var CONFIG_KEY = "cache";
|
|
2344
|
+
var LOCK_UPDATE_MS = 5e3;
|
|
2345
|
+
var LOCK_STALE_MS = 1e4;
|
|
2346
|
+
var LOCK_RETRY_WAIT_MS = 100;
|
|
2347
|
+
var LOCK_RETRY_MAX_WAIT_MS = 1e3;
|
|
2348
|
+
var LOCK_RETRY_COUNT = 120;
|
|
2349
|
+
function keychainAccount(key) {
|
|
2350
|
+
return crypto.createHash("sha256").update(key).digest("hex");
|
|
2351
|
+
}
|
|
2352
|
+
function readConfigMap() {
|
|
2353
|
+
const cfg = getConfig();
|
|
2354
|
+
const stored = cfg.get(CONFIG_KEY);
|
|
2355
|
+
if (stored && typeof stored === "object") {
|
|
2356
|
+
return stored;
|
|
2357
|
+
}
|
|
2358
|
+
return {};
|
|
2359
|
+
}
|
|
2360
|
+
function writeConfigMap(map) {
|
|
2361
|
+
getConfig().set(CONFIG_KEY, map);
|
|
2362
|
+
}
|
|
2363
|
+
function entryIsExpired(entry) {
|
|
2364
|
+
return entry.expires_at !== void 0 && entry.expires_at <= Date.now();
|
|
2365
|
+
}
|
|
2366
|
+
function createCache() {
|
|
2367
|
+
return {
|
|
2368
|
+
async get(key) {
|
|
2369
|
+
const entry = readConfigMap()[key];
|
|
2370
|
+
if (!entry) return void 0;
|
|
2371
|
+
if (entryIsExpired(entry)) return void 0;
|
|
2372
|
+
if (entry.secret) {
|
|
2373
|
+
const stored = await enqueue(async () => {
|
|
2374
|
+
await getBackendInfo();
|
|
2375
|
+
return crossKeychain.getPassword(SERVICE2, keychainAccount(key));
|
|
2376
|
+
});
|
|
2377
|
+
if (!stored) {
|
|
2378
|
+
return void 0;
|
|
2379
|
+
}
|
|
2380
|
+
return { value: stored, expiresAt: entry.expires_at };
|
|
2381
|
+
}
|
|
2382
|
+
if (entry.value === void 0) return void 0;
|
|
2383
|
+
return { value: entry.value, expiresAt: entry.expires_at };
|
|
2384
|
+
},
|
|
2385
|
+
async set(key, value, options) {
|
|
2386
|
+
const secret = options?.secret ?? false;
|
|
2387
|
+
const expiresAt = options?.ttl ? Date.now() + options.ttl * 1e3 : void 0;
|
|
2388
|
+
if (secret) {
|
|
2389
|
+
try {
|
|
2390
|
+
await enqueue(async () => {
|
|
2391
|
+
await getBackendInfo();
|
|
2392
|
+
await crossKeychain.setPassword(SERVICE2, keychainAccount(key), value);
|
|
2393
|
+
});
|
|
2394
|
+
} catch {
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2397
|
+
const map = readConfigMap();
|
|
2398
|
+
map[key] = { secret: true, expires_at: expiresAt };
|
|
2399
|
+
try {
|
|
2400
|
+
writeConfigMap(map);
|
|
2401
|
+
} catch {
|
|
2402
|
+
}
|
|
2403
|
+
} else {
|
|
2404
|
+
const map = readConfigMap();
|
|
2405
|
+
map[key] = { secret: false, value, expires_at: expiresAt };
|
|
2406
|
+
try {
|
|
2407
|
+
writeConfigMap(map);
|
|
2408
|
+
} catch {
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
},
|
|
2412
|
+
async delete(key) {
|
|
2413
|
+
const map = readConfigMap();
|
|
2414
|
+
const entry = map[key];
|
|
2415
|
+
if (entry) {
|
|
2416
|
+
delete map[key];
|
|
2417
|
+
try {
|
|
2418
|
+
writeConfigMap(map);
|
|
2419
|
+
} catch {
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
if (entry?.secret) {
|
|
2423
|
+
try {
|
|
2424
|
+
await enqueue(async () => {
|
|
2425
|
+
await getBackendInfo();
|
|
2426
|
+
await crossKeychain.deletePassword(SERVICE2, keychainAccount(key));
|
|
2427
|
+
});
|
|
2428
|
+
} catch {
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
},
|
|
2432
|
+
async withLock(_key, fn) {
|
|
2433
|
+
const cfg = getConfig();
|
|
2434
|
+
const lockTarget = `${cfg.path}.cache-lock`;
|
|
2435
|
+
try {
|
|
2436
|
+
fs.mkdirSync(path.dirname(lockTarget), { recursive: true });
|
|
2437
|
+
if (!fs.existsSync(lockTarget)) {
|
|
2438
|
+
fs.writeFileSync(lockTarget, "");
|
|
2439
|
+
}
|
|
2440
|
+
} catch {
|
|
2441
|
+
return fn();
|
|
2442
|
+
}
|
|
2443
|
+
let release = null;
|
|
2444
|
+
try {
|
|
2445
|
+
release = await lockfile__namespace.lock(lockTarget, {
|
|
2446
|
+
stale: LOCK_STALE_MS,
|
|
2447
|
+
update: LOCK_UPDATE_MS,
|
|
2448
|
+
retries: {
|
|
2449
|
+
retries: LOCK_RETRY_COUNT,
|
|
2450
|
+
factor: 1.2,
|
|
2451
|
+
minTimeout: LOCK_RETRY_WAIT_MS,
|
|
2452
|
+
maxTimeout: LOCK_RETRY_MAX_WAIT_MS
|
|
2453
|
+
}
|
|
2454
|
+
});
|
|
2455
|
+
} catch {
|
|
2456
|
+
return fn();
|
|
2457
|
+
}
|
|
2458
|
+
try {
|
|
2459
|
+
return await fn();
|
|
2460
|
+
} finally {
|
|
2461
|
+
try {
|
|
2462
|
+
await release();
|
|
2463
|
+
} catch {
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
};
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
// src/login/index.ts
|
|
2471
|
+
var ZapierAuthenticationError = class extends Error {
|
|
2472
|
+
constructor(message) {
|
|
2473
|
+
super(message);
|
|
2474
|
+
this.name = "ZapierAuthenticationError";
|
|
2475
|
+
}
|
|
2476
|
+
};
|
|
2477
|
+
var config = null;
|
|
2478
|
+
var DEFAULT_AUTH_CLIENT_ID = "grwWZD5hUWGvb4V8ODBuOtXer3h0DBEZ2HR8aay6";
|
|
2479
|
+
var TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
2480
|
+
function createDebugLog(enabled) {
|
|
2481
|
+
if (!enabled) {
|
|
2482
|
+
return () => {
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
return (message, data) => {
|
|
2486
|
+
if (data === void 0) {
|
|
2487
|
+
console.log(`[Zapier SDK CLI Login] ${message}`);
|
|
2488
|
+
} else {
|
|
2489
|
+
console.log(`[Zapier SDK CLI Login] ${message}`, data);
|
|
2490
|
+
}
|
|
2491
|
+
};
|
|
2492
|
+
}
|
|
2493
|
+
function censorHeaderValue(value) {
|
|
2494
|
+
if (value.length > 12) {
|
|
2495
|
+
return `${value.substring(0, 4)}...${value.substring(value.length - 4)}`;
|
|
2496
|
+
}
|
|
2497
|
+
return `${value.charAt(0)}...`;
|
|
2498
|
+
}
|
|
2499
|
+
function getAuthClientId(clientId) {
|
|
2500
|
+
return clientId || DEFAULT_AUTH_CLIENT_ID;
|
|
2501
|
+
}
|
|
2502
|
+
var AUTH_MODE_HEADER = "X-Auth";
|
|
2503
|
+
var DEFAULT_AUTH_BASE_URL = "https://zapier.com";
|
|
2504
|
+
function getAuthTokenUrl(options) {
|
|
2505
|
+
const authBaseUrl = options?.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
2506
|
+
return `${authBaseUrl}/oauth/token/`;
|
|
2507
|
+
}
|
|
2508
|
+
function getAuthAuthorizeUrl(options) {
|
|
2509
|
+
const authBaseUrl = options?.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
2510
|
+
return `${authBaseUrl}/oauth/authorize/`;
|
|
2511
|
+
}
|
|
2512
|
+
function getPkceLoginConfig(options) {
|
|
2513
|
+
return {
|
|
2514
|
+
clientId: getAuthClientId(options?.credentials?.clientId),
|
|
2515
|
+
tokenUrl: getAuthTokenUrl({ baseUrl: options?.credentials?.baseUrl }),
|
|
2516
|
+
authorizeUrl: getAuthAuthorizeUrl({
|
|
2517
|
+
baseUrl: options?.credentials?.baseUrl
|
|
2518
|
+
})
|
|
2519
|
+
};
|
|
2520
|
+
}
|
|
2521
|
+
var cachedLogin;
|
|
2522
|
+
function getConfig() {
|
|
2523
|
+
if (!config) {
|
|
2524
|
+
config = new Conf__default.default({ projectName: "zapier-sdk-cli" });
|
|
2525
|
+
if (!config.has("login_storage_mode")) {
|
|
2526
|
+
config.set(
|
|
2527
|
+
"login_storage_mode",
|
|
2528
|
+
fs.existsSync(config.path) ? "config" : "keychain"
|
|
2529
|
+
);
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
return config;
|
|
2533
|
+
}
|
|
2534
|
+
function unloadConfig() {
|
|
2535
|
+
config = null;
|
|
2536
|
+
cachedLogin = void 0;
|
|
2537
|
+
}
|
|
2538
|
+
async function updateLogin(loginData, options = {}) {
|
|
2539
|
+
const debugLog = createDebugLog(options.debug ?? false);
|
|
2540
|
+
const storage = options.storage ?? cachedLogin?.storage ?? "keychain";
|
|
2541
|
+
const expiresAt = Date.now() + loginData.expires_in * 1e3;
|
|
2542
|
+
const cfg = getConfig();
|
|
2543
|
+
cfg.set("login_storage_mode", storage);
|
|
2544
|
+
if (storage === "keychain") {
|
|
2545
|
+
await setTokensInKeychain({
|
|
2546
|
+
data: {
|
|
2547
|
+
login_jwt: loginData.access_token,
|
|
2548
|
+
login_refresh_token: loginData.refresh_token
|
|
2549
|
+
},
|
|
2550
|
+
debugLog
|
|
2551
|
+
});
|
|
2552
|
+
cfg.set("login_expires_at", expiresAt);
|
|
2553
|
+
cfg.delete("login_jwt");
|
|
2554
|
+
cfg.delete("login_refresh_token");
|
|
2555
|
+
} else {
|
|
2556
|
+
cfg.set("login_jwt", loginData.access_token);
|
|
2557
|
+
cfg.set("login_refresh_token", loginData.refresh_token);
|
|
2558
|
+
cfg.set("login_expires_at", expiresAt);
|
|
2559
|
+
await clearTokensFromKeychain({ debugLog });
|
|
2560
|
+
}
|
|
2561
|
+
cachedLogin = {
|
|
2562
|
+
jwt: loginData.access_token,
|
|
2563
|
+
refreshToken: loginData.refresh_token,
|
|
2564
|
+
expiresAt,
|
|
2565
|
+
storage
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2568
|
+
function decodeJwtOrThrow(token) {
|
|
2569
|
+
if (typeof token !== "string") {
|
|
2570
|
+
throw new Error("Expected JWT to be a string");
|
|
2571
|
+
}
|
|
2572
|
+
const decodedJwt = jwt__namespace.decode(token, { complete: true });
|
|
2573
|
+
if (!decodedJwt) {
|
|
2574
|
+
throw new Error("Could not decode JWT");
|
|
2575
|
+
}
|
|
2576
|
+
if (typeof decodedJwt.payload === "string") {
|
|
2577
|
+
throw new Error("Did not expect JWT payload to be a string");
|
|
2578
|
+
}
|
|
2579
|
+
return decodedJwt;
|
|
2580
|
+
}
|
|
2581
|
+
async function refreshJwt(refreshToken, options = {}) {
|
|
2582
|
+
const {
|
|
2583
|
+
onEvent,
|
|
2584
|
+
fetch: fetch2 = globalThis.fetch,
|
|
2585
|
+
credentials: credentials2,
|
|
2586
|
+
debug = false
|
|
2587
|
+
} = options;
|
|
2588
|
+
const debugLog = createDebugLog(debug);
|
|
2589
|
+
const tokenUrl = getAuthTokenUrl({ baseUrl: credentials2?.baseUrl });
|
|
2590
|
+
const clientId = getAuthClientId(credentials2?.clientId);
|
|
2591
|
+
const startTime = Date.now();
|
|
2592
|
+
try {
|
|
2593
|
+
onEvent?.({
|
|
2594
|
+
type: "auth_refreshing",
|
|
2595
|
+
payload: {
|
|
2596
|
+
message: "Refreshing your token...",
|
|
2597
|
+
operation: "token_refresh"
|
|
2598
|
+
},
|
|
2599
|
+
timestamp: Date.now()
|
|
2600
|
+
});
|
|
2601
|
+
debugLog(`\u2192 POST ${tokenUrl}`, {
|
|
2602
|
+
headers: {
|
|
2603
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
2604
|
+
[AUTH_MODE_HEADER]: "no"
|
|
2605
|
+
},
|
|
2606
|
+
body: {
|
|
2607
|
+
client_id: clientId,
|
|
2608
|
+
refresh_token: censorHeaderValue(refreshToken),
|
|
2609
|
+
grant_type: "refresh_token"
|
|
2610
|
+
}
|
|
2611
|
+
});
|
|
2612
|
+
const response = await fetch2(tokenUrl, {
|
|
2613
|
+
method: "POST",
|
|
2614
|
+
headers: {
|
|
2615
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
2616
|
+
[AUTH_MODE_HEADER]: "no"
|
|
2617
|
+
},
|
|
2618
|
+
body: new URLSearchParams({
|
|
2619
|
+
client_id: clientId,
|
|
2620
|
+
refresh_token: refreshToken,
|
|
2621
|
+
grant_type: "refresh_token"
|
|
2622
|
+
})
|
|
2623
|
+
});
|
|
2624
|
+
const duration = Date.now() - startTime;
|
|
2625
|
+
if (!response.ok) {
|
|
2626
|
+
debugLog(`\u2190 ${response.status} ${response.statusText} (${duration}ms)`);
|
|
2627
|
+
throw new Error(
|
|
2628
|
+
`Token refresh failed: ${response.status} ${response.statusText}`
|
|
2629
|
+
);
|
|
2630
|
+
}
|
|
2631
|
+
debugLog(`\u2190 ${response.status} ${response.statusText} (${duration}ms)`);
|
|
2632
|
+
const data = await response.json();
|
|
2633
|
+
await updateLogin(data, { debug });
|
|
2634
|
+
debugLog(
|
|
2635
|
+
`Token refreshed and saved to ${cachedLogin?.storage ?? "keychain"}`
|
|
2636
|
+
);
|
|
2637
|
+
onEvent?.({
|
|
2638
|
+
type: "auth_success",
|
|
2639
|
+
payload: {
|
|
2640
|
+
message: "Token refreshed successfully",
|
|
2641
|
+
operation: "token_refresh"
|
|
2642
|
+
},
|
|
2643
|
+
timestamp: Date.now()
|
|
2644
|
+
});
|
|
2645
|
+
return data.access_token;
|
|
2646
|
+
} catch (error) {
|
|
2647
|
+
const duration = Date.now() - startTime;
|
|
2648
|
+
debugLog(`\u2716 Token refresh failed (${duration}ms)`, {
|
|
2649
|
+
error: error instanceof Error ? error.message : error
|
|
2650
|
+
});
|
|
2651
|
+
cachedLogin = void 0;
|
|
2652
|
+
const errorMessage = `Token refresh failed: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
2653
|
+
onEvent?.({
|
|
2654
|
+
type: "auth_error",
|
|
2655
|
+
payload: {
|
|
2656
|
+
message: errorMessage,
|
|
2657
|
+
error: errorMessage,
|
|
2658
|
+
operation: "token_refresh"
|
|
2659
|
+
},
|
|
2660
|
+
timestamp: Date.now()
|
|
2661
|
+
});
|
|
2662
|
+
throw error;
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
var pendingRefresh = null;
|
|
2666
|
+
var pendingResolve = null;
|
|
2667
|
+
async function resolveStoredLogin(debugLog) {
|
|
2668
|
+
if (cachedLogin) {
|
|
2669
|
+
debugLog("Using in-memory cached credentials");
|
|
2670
|
+
return cachedLogin;
|
|
2671
|
+
}
|
|
2672
|
+
if (pendingResolve) {
|
|
2673
|
+
debugLog("Waiting for existing keychain read to complete");
|
|
2674
|
+
return pendingResolve;
|
|
2675
|
+
}
|
|
2676
|
+
pendingResolve = resolveStoredLoginFromStorage(debugLog).finally(() => {
|
|
2677
|
+
pendingResolve = null;
|
|
2678
|
+
});
|
|
2679
|
+
return pendingResolve;
|
|
2680
|
+
}
|
|
2681
|
+
async function resolveStoredLoginFromStorage(debugLog) {
|
|
2682
|
+
let cfg;
|
|
2683
|
+
try {
|
|
2684
|
+
cfg = getConfig();
|
|
2685
|
+
} catch (error) {
|
|
2686
|
+
debugLog("Failed to load config", {
|
|
2687
|
+
error: error instanceof Error ? error.message : error
|
|
2688
|
+
});
|
|
2689
|
+
return void 0;
|
|
2690
|
+
}
|
|
2691
|
+
const expiresAt = cfg.get("login_expires_at");
|
|
2692
|
+
const configJwt = cfg.get("login_jwt");
|
|
2693
|
+
const configRefresh = cfg.get("login_refresh_token");
|
|
2694
|
+
if (configJwt && configRefresh && typeof expiresAt === "number") {
|
|
2695
|
+
debugLog("Loaded credentials from config (legacy format)");
|
|
2696
|
+
cachedLogin = {
|
|
2697
|
+
jwt: configJwt,
|
|
2698
|
+
refreshToken: configRefresh,
|
|
2699
|
+
expiresAt,
|
|
2700
|
+
storage: "config"
|
|
2701
|
+
};
|
|
2702
|
+
return cachedLogin;
|
|
2703
|
+
}
|
|
2704
|
+
if (typeof expiresAt !== "number") {
|
|
2705
|
+
debugLog("No stored login credentials found");
|
|
2706
|
+
return void 0;
|
|
2707
|
+
}
|
|
2708
|
+
const keychainData = await getTokensFromKeychain({ debugLog });
|
|
2709
|
+
if (!keychainData) {
|
|
2710
|
+
debugLog("No tokens found in keychain");
|
|
2711
|
+
return void 0;
|
|
2712
|
+
}
|
|
2713
|
+
debugLog("Loaded credentials from keychain");
|
|
2714
|
+
cachedLogin = {
|
|
2715
|
+
jwt: keychainData.login_jwt,
|
|
2716
|
+
refreshToken: keychainData.login_refresh_token,
|
|
2717
|
+
expiresAt,
|
|
2718
|
+
storage: "keychain"
|
|
2719
|
+
};
|
|
2720
|
+
return cachedLogin;
|
|
2721
|
+
}
|
|
2722
|
+
async function resolveOrRefreshToken(options = {}) {
|
|
2723
|
+
const { debug = false } = options;
|
|
2724
|
+
const debugLog = createDebugLog(debug);
|
|
2725
|
+
const stored = await resolveStoredLogin(debugLog);
|
|
2726
|
+
if (!stored) {
|
|
2727
|
+
return void 0;
|
|
2728
|
+
}
|
|
2729
|
+
const { jwt: storedJwt, refreshToken, expiresAt } = stored;
|
|
2730
|
+
if (expiresAt > Date.now() + TOKEN_REFRESH_BUFFER_MS) {
|
|
2731
|
+
debugLog("Using cached token (still valid)");
|
|
2732
|
+
return storedJwt;
|
|
2733
|
+
}
|
|
2734
|
+
debugLog("Token expired, refreshing...");
|
|
2735
|
+
if (pendingRefresh) {
|
|
2736
|
+
debugLog("Waiting for existing refresh to complete");
|
|
2737
|
+
return pendingRefresh;
|
|
2738
|
+
}
|
|
2739
|
+
pendingRefresh = refreshJwt(refreshToken, options).finally(() => {
|
|
2740
|
+
pendingRefresh = null;
|
|
2741
|
+
});
|
|
2742
|
+
return await pendingRefresh;
|
|
2743
|
+
}
|
|
2744
|
+
async function getToken(options = {}) {
|
|
2745
|
+
try {
|
|
2746
|
+
return await resolveOrRefreshToken(options);
|
|
2747
|
+
} catch (error) {
|
|
2748
|
+
const message = error instanceof Error ? error.message : "Token refresh failed";
|
|
2749
|
+
throw new ZapierAuthenticationError(
|
|
2750
|
+
`${message}
|
|
2751
|
+
Please run 'login' to authenticate again.`
|
|
2752
|
+
);
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
async function getLoggedInUser(options = {}) {
|
|
2756
|
+
const jwt2 = await getToken(options).catch(() => void 0);
|
|
2757
|
+
if (!jwt2) {
|
|
2758
|
+
throw new Error(
|
|
2759
|
+
"No valid authentication token available. Please login first."
|
|
2760
|
+
);
|
|
2761
|
+
}
|
|
2762
|
+
let decodedJwt = decodeJwtOrThrow(jwt2);
|
|
2763
|
+
if (decodedJwt.payload["sub_type"] == "service") {
|
|
2764
|
+
decodedJwt = decodeJwtOrThrow(decodedJwt.payload["njwt"]);
|
|
2765
|
+
}
|
|
2766
|
+
if (typeof decodedJwt.payload["zap:acc"] !== "string") {
|
|
2767
|
+
throw new Error("JWT payload does not contain accountId");
|
|
2768
|
+
}
|
|
2769
|
+
const accountId = parseInt(decodedJwt.payload["zap:acc"], 10);
|
|
2770
|
+
if (isNaN(accountId)) {
|
|
2771
|
+
throw new Error("JWT accountId is not a number");
|
|
2772
|
+
}
|
|
2773
|
+
if (decodedJwt.payload["sub_type"] !== "customuser" || typeof decodedJwt.payload["sub"] !== "string") {
|
|
2774
|
+
throw new Error("JWT payload does not contain customUserId");
|
|
2775
|
+
}
|
|
2776
|
+
const customUserId = parseInt(decodedJwt.payload["sub"], 10);
|
|
2777
|
+
if (isNaN(customUserId)) {
|
|
2778
|
+
throw new Error("JWT customUserId is not a number");
|
|
2779
|
+
}
|
|
2780
|
+
const email = decodedJwt.payload["zap:uname"];
|
|
2781
|
+
if (typeof email !== "string") {
|
|
2782
|
+
throw new Error("JWT payload does not contain email");
|
|
2783
|
+
}
|
|
2784
|
+
return {
|
|
2785
|
+
accountId,
|
|
2786
|
+
customUserId,
|
|
2787
|
+
email
|
|
2788
|
+
};
|
|
2789
|
+
}
|
|
2790
|
+
function getLoginStorageMode() {
|
|
2791
|
+
const cfg = getConfig();
|
|
2792
|
+
if (typeof cfg.get("login_jwt") === "string") {
|
|
2793
|
+
return "config";
|
|
2794
|
+
}
|
|
2795
|
+
const explicitMode = cfg.get("login_storage_mode");
|
|
2796
|
+
if (explicitMode === "keychain" || explicitMode === "config") {
|
|
2797
|
+
return explicitMode;
|
|
2798
|
+
}
|
|
2799
|
+
return "keychain";
|
|
2800
|
+
}
|
|
2801
|
+
async function logout(options = {}) {
|
|
2802
|
+
const { onEvent } = options;
|
|
2803
|
+
const mode = getLoginStorageMode();
|
|
2804
|
+
cachedLogin = void 0;
|
|
2805
|
+
await clearTokensFromKeychain();
|
|
2806
|
+
const cfg = getConfig();
|
|
2807
|
+
cfg.set("login_storage_mode", mode);
|
|
2808
|
+
cfg.delete("login_expires_at");
|
|
2809
|
+
cfg.delete("login_jwt");
|
|
2810
|
+
cfg.delete("login_refresh_token");
|
|
2811
|
+
onEvent?.({
|
|
2812
|
+
type: "auth_logout",
|
|
2813
|
+
payload: { message: "Logged out successfully", operation: "logout" },
|
|
2814
|
+
timestamp: Date.now()
|
|
2815
|
+
});
|
|
2816
|
+
}
|
|
2817
|
+
function getConfigPath() {
|
|
2818
|
+
const cfg = getConfig();
|
|
2819
|
+
return cfg.path;
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
// src/utils/constants.ts
|
|
2238
2823
|
var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
2239
2824
|
var LOGIN_TIMEOUT_MS = 3e5;
|
|
2240
2825
|
var spinPromise = async (promise, text) => {
|
|
@@ -2368,13 +2953,13 @@ var login = async ({
|
|
|
2368
2953
|
timeoutMs = LOGIN_TIMEOUT_MS,
|
|
2369
2954
|
credentials: credentials2
|
|
2370
2955
|
}) => {
|
|
2371
|
-
const { clientId, tokenUrl, authorizeUrl } =
|
|
2956
|
+
const { clientId, tokenUrl, authorizeUrl } = getPkceLoginConfig({
|
|
2372
2957
|
credentials: credentials2
|
|
2373
2958
|
});
|
|
2374
2959
|
const scope = ensureOfflineAccess(
|
|
2375
2960
|
credentials2?.scope || "internal credentials"
|
|
2376
2961
|
);
|
|
2377
|
-
await
|
|
2962
|
+
await logout();
|
|
2378
2963
|
const availablePort = await findAvailablePort();
|
|
2379
2964
|
const redirectUri = `http://localhost:${availablePort}/oauth`;
|
|
2380
2965
|
log_default.info(`Using port ${availablePort} for OAuth callback`);
|
|
@@ -2462,13 +3047,13 @@ var login = async ({
|
|
|
2462
3047
|
},
|
|
2463
3048
|
{
|
|
2464
3049
|
headers: {
|
|
2465
|
-
[
|
|
3050
|
+
[AUTH_MODE_HEADER]: "no",
|
|
2466
3051
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
2467
3052
|
}
|
|
2468
3053
|
}
|
|
2469
3054
|
);
|
|
2470
3055
|
let targetStorage;
|
|
2471
|
-
if (
|
|
3056
|
+
if (getLoginStorageMode() === "config") {
|
|
2472
3057
|
const { upgrade } = await inquirer__default.default.prompt([
|
|
2473
3058
|
{
|
|
2474
3059
|
type: "confirm",
|
|
@@ -2482,13 +3067,13 @@ var login = async ({
|
|
|
2482
3067
|
targetStorage = "keychain";
|
|
2483
3068
|
}
|
|
2484
3069
|
try {
|
|
2485
|
-
await
|
|
3070
|
+
await updateLogin(data, { storage: targetStorage });
|
|
2486
3071
|
} catch (err) {
|
|
2487
3072
|
if (targetStorage === "keychain") {
|
|
2488
3073
|
log_default.warn(
|
|
2489
|
-
`Could not store credentials in system keychain. Storing in plaintext at ${
|
|
3074
|
+
`Could not store credentials in system keychain. Storing in plaintext at ${getConfigPath()}.`
|
|
2490
3075
|
);
|
|
2491
|
-
await
|
|
3076
|
+
await updateLogin(data, { storage: "config" });
|
|
2492
3077
|
} else {
|
|
2493
3078
|
throw err;
|
|
2494
3079
|
}
|
|
@@ -2513,85 +3098,65 @@ function toPkceCredentials(credentials2) {
|
|
|
2513
3098
|
}
|
|
2514
3099
|
return void 0;
|
|
2515
3100
|
}
|
|
2516
|
-
var loginPlugin = (
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
credentials: pkceCredentials
|
|
2527
|
-
});
|
|
2528
|
-
const user = await cliLogin.getLoggedInUser();
|
|
2529
|
-
sdk2.context.eventEmission.emit(
|
|
2530
|
-
"platform.sdk.ApplicationLifecycleEvent",
|
|
2531
|
-
zapierSdk.buildApplicationLifecycleEvent(
|
|
2532
|
-
{ lifecycle_event_type: "login_success" },
|
|
2533
|
-
{ customuser_id: user.customUserId, account_id: user.accountId }
|
|
2534
|
-
)
|
|
2535
|
-
);
|
|
2536
|
-
console.log(`\u2705 Successfully logged in as ${user.email}`);
|
|
2537
|
-
};
|
|
2538
|
-
return {
|
|
2539
|
-
login: loginFn,
|
|
2540
|
-
context: {
|
|
2541
|
-
meta: {
|
|
2542
|
-
login: {
|
|
2543
|
-
categories: ["account"],
|
|
2544
|
-
inputSchema: LoginSchema,
|
|
2545
|
-
supportsJsonOutput: false
|
|
2546
|
-
}
|
|
3101
|
+
var loginPlugin = zapierSdk.definePlugin(
|
|
3102
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
3103
|
+
name: "login",
|
|
3104
|
+
categories: ["account"],
|
|
3105
|
+
inputSchema: LoginSchema,
|
|
3106
|
+
supportsJsonOutput: false,
|
|
3107
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3108
|
+
const timeoutSeconds = options.timeout ? parseInt(options.timeout, 10) : 300;
|
|
3109
|
+
if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
3110
|
+
throw new Error("Timeout must be a positive number");
|
|
2547
3111
|
}
|
|
3112
|
+
const resolvedCredentials = await sdk3.context.resolveCredentials();
|
|
3113
|
+
const pkceCredentials = toPkceCredentials(resolvedCredentials);
|
|
3114
|
+
await login_default({
|
|
3115
|
+
timeoutMs: timeoutSeconds * 1e3,
|
|
3116
|
+
credentials: pkceCredentials
|
|
3117
|
+
});
|
|
3118
|
+
const user = await getLoggedInUser();
|
|
3119
|
+
sdk3.context.eventEmission.emit(
|
|
3120
|
+
"platform.sdk.ApplicationLifecycleEvent",
|
|
3121
|
+
zapierSdk.buildApplicationLifecycleEvent(
|
|
3122
|
+
{ lifecycle_event_type: "login_success" },
|
|
3123
|
+
{ customuser_id: user.customUserId, account_id: user.accountId }
|
|
3124
|
+
)
|
|
3125
|
+
);
|
|
3126
|
+
console.log(`\u2705 Successfully logged in as ${user.email}`);
|
|
2548
3127
|
}
|
|
2549
|
-
}
|
|
2550
|
-
|
|
3128
|
+
})
|
|
3129
|
+
);
|
|
2551
3130
|
var LogoutSchema = zod.z.object({}).describe("Log out of your Zapier account");
|
|
2552
3131
|
|
|
2553
3132
|
// src/plugins/logout/index.ts
|
|
2554
|
-
var
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
categories: ["account"],
|
|
2564
|
-
inputSchema: LogoutSchema,
|
|
2565
|
-
supportsJsonOutput: false
|
|
2566
|
-
}
|
|
3133
|
+
var logoutPlugin = zapierSdk.definePlugin(
|
|
3134
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
3135
|
+
name: "logout",
|
|
3136
|
+
categories: ["account"],
|
|
3137
|
+
inputSchema: LogoutSchema,
|
|
3138
|
+
supportsJsonOutput: false,
|
|
3139
|
+
handler: async () => {
|
|
3140
|
+
await logout();
|
|
3141
|
+
console.log("\u2705 Successfully logged out");
|
|
2567
3142
|
}
|
|
2568
|
-
}
|
|
2569
|
-
|
|
3143
|
+
})
|
|
3144
|
+
);
|
|
2570
3145
|
var McpSchema = zod.z.object({
|
|
2571
3146
|
port: zod.z.string().optional().describe("Port to listen on (for future HTTP transport)")
|
|
2572
3147
|
}).describe("Start MCP server for Zapier SDK");
|
|
2573
3148
|
|
|
2574
3149
|
// src/plugins/mcp/index.ts
|
|
2575
|
-
var mcpPlugin = (
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
}
|
|
2581
|
-
|
|
2582
|
-
}, McpSchema);
|
|
2583
|
-
return {
|
|
2584
|
-
mcp: mcpWithSdk,
|
|
2585
|
-
context: {
|
|
2586
|
-
meta: {
|
|
2587
|
-
mcp: {
|
|
2588
|
-
categories: ["utility"],
|
|
2589
|
-
inputSchema: McpSchema
|
|
2590
|
-
}
|
|
2591
|
-
}
|
|
3150
|
+
var mcpPlugin = zapierSdk.definePlugin(
|
|
3151
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
3152
|
+
name: "mcp",
|
|
3153
|
+
categories: ["utility"],
|
|
3154
|
+
inputSchema: McpSchema,
|
|
3155
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3156
|
+
await zapierSdkMcp.startMcpServer({ ...options, debug: sdk3.context.options?.debug });
|
|
2592
3157
|
}
|
|
2593
|
-
}
|
|
2594
|
-
|
|
3158
|
+
})
|
|
3159
|
+
);
|
|
2595
3160
|
var BundleCodeSchema = zod.z.object({
|
|
2596
3161
|
input: zod.z.string().min(1).describe("Input TypeScript file path to bundle"),
|
|
2597
3162
|
output: zapierSdk.OutputPropertySchema.optional().describe(
|
|
@@ -2602,22 +3167,14 @@ var BundleCodeSchema = zod.z.object({
|
|
|
2602
3167
|
target: zod.z.string().optional().describe("ECMAScript target version"),
|
|
2603
3168
|
cjs: zod.z.boolean().optional().describe("Output CommonJS format instead of ESM")
|
|
2604
3169
|
}).describe("Bundle TypeScript code into executable JavaScript");
|
|
2605
|
-
var bundleCodePlugin = (
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
bundleCode: {
|
|
2614
|
-
categories: ["utility", "deprecated"],
|
|
2615
|
-
inputSchema: BundleCodeSchema
|
|
2616
|
-
}
|
|
2617
|
-
}
|
|
2618
|
-
}
|
|
2619
|
-
};
|
|
2620
|
-
};
|
|
3170
|
+
var bundleCodePlugin = zapierSdk.definePlugin(
|
|
3171
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
3172
|
+
name: "bundleCode",
|
|
3173
|
+
categories: ["utility", "deprecated"],
|
|
3174
|
+
inputSchema: BundleCodeSchema,
|
|
3175
|
+
handler: async ({ options }) => bundleCode(options)
|
|
3176
|
+
})
|
|
3177
|
+
);
|
|
2621
3178
|
var ZapierBundleError = class extends Error {
|
|
2622
3179
|
constructor(message, details, originalError) {
|
|
2623
3180
|
super(message);
|
|
@@ -2684,25 +3241,14 @@ async function bundleCode(options) {
|
|
|
2684
3241
|
}
|
|
2685
3242
|
}
|
|
2686
3243
|
var GetLoginConfigPathSchema = zod.z.object({}).describe("Show the path to the login configuration file");
|
|
2687
|
-
var getLoginConfigPathPlugin = (
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
)
|
|
2694
|
-
|
|
2695
|
-
getLoginConfigPath: getLoginConfigPathWithSdk,
|
|
2696
|
-
context: {
|
|
2697
|
-
meta: {
|
|
2698
|
-
getLoginConfigPath: {
|
|
2699
|
-
categories: ["utility"],
|
|
2700
|
-
inputSchema: GetLoginConfigPathSchema
|
|
2701
|
-
}
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
};
|
|
2705
|
-
};
|
|
3244
|
+
var getLoginConfigPathPlugin = zapierSdk.definePlugin(
|
|
3245
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
3246
|
+
name: "getLoginConfigPath",
|
|
3247
|
+
categories: ["utility"],
|
|
3248
|
+
inputSchema: GetLoginConfigPathSchema,
|
|
3249
|
+
handler: async () => getConfigPath()
|
|
3250
|
+
})
|
|
3251
|
+
);
|
|
2706
3252
|
var AddSchema = zod.z.object({
|
|
2707
3253
|
apps: zod.z.array(zod.z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required").describe(
|
|
2708
3254
|
"One or more app keys to add (e.g., 'slack', 'github', 'trello')"
|
|
@@ -2730,111 +3276,105 @@ async function detectTypesOutputDirectory() {
|
|
|
2730
3276
|
}
|
|
2731
3277
|
return "./zapier/apps/";
|
|
2732
3278
|
}
|
|
2733
|
-
var addPlugin = (
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
skipWrite: false,
|
|
2808
|
-
configPath,
|
|
2809
|
-
onProgress: handleManifestProgress
|
|
2810
|
-
});
|
|
2811
|
-
const typesResult = await sdk2.generateAppTypes({
|
|
2812
|
-
apps: appKeys,
|
|
2813
|
-
connections: connectionIds,
|
|
2814
|
-
skipWrite: false,
|
|
2815
|
-
typesOutputDirectory: resolvedTypesOutput,
|
|
2816
|
-
onProgress: handleTypesProgress
|
|
2817
|
-
});
|
|
2818
|
-
const results = manifestResult.manifest?.apps || {};
|
|
2819
|
-
const successfulApps = Object.keys(results).filter(
|
|
2820
|
-
(manifestKey) => typesResult.writtenFiles?.[manifestKey]
|
|
2821
|
-
);
|
|
2822
|
-
if (successfulApps.length > 0) {
|
|
2823
|
-
console.log(`\u2705 Added ${successfulApps.length} app(s) to manifest`);
|
|
2824
|
-
}
|
|
2825
|
-
}, AddSchema);
|
|
2826
|
-
return {
|
|
2827
|
-
add,
|
|
2828
|
-
context: {
|
|
2829
|
-
meta: {
|
|
2830
|
-
add: {
|
|
2831
|
-
categories: ["utility"],
|
|
2832
|
-
inputSchema: AddSchema
|
|
3279
|
+
var addPlugin = zapierSdk.definePlugin(
|
|
3280
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
3281
|
+
name: "add",
|
|
3282
|
+
categories: ["utility"],
|
|
3283
|
+
inputSchema: AddSchema,
|
|
3284
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3285
|
+
const {
|
|
3286
|
+
apps: appKeys,
|
|
3287
|
+
connections: connectionIds,
|
|
3288
|
+
configPath,
|
|
3289
|
+
typesOutput = await detectTypesOutputDirectory()
|
|
3290
|
+
} = options;
|
|
3291
|
+
const resolvedTypesOutput = path.resolve(typesOutput);
|
|
3292
|
+
console.log(`\u{1F4E6} Adding ${appKeys.length} app(s)...`);
|
|
3293
|
+
const appSlugAndKeyMap = /* @__PURE__ */ new Map();
|
|
3294
|
+
const handleManifestProgress = (event) => {
|
|
3295
|
+
switch (event.type) {
|
|
3296
|
+
case "apps_lookup_start":
|
|
3297
|
+
console.log(`\u{1F4E6} Looking up ${event.count} app(s)...`);
|
|
3298
|
+
break;
|
|
3299
|
+
case "app_found":
|
|
3300
|
+
const displayName = event.app.slug ? `${event.app.slug} (${event.app.key})` : event.app.key;
|
|
3301
|
+
appSlugAndKeyMap.set(event.app.key, displayName);
|
|
3302
|
+
break;
|
|
3303
|
+
case "apps_lookup_complete":
|
|
3304
|
+
if (event.count === 0) {
|
|
3305
|
+
console.warn("\u26A0\uFE0F No apps found");
|
|
3306
|
+
}
|
|
3307
|
+
break;
|
|
3308
|
+
case "app_processing_start":
|
|
3309
|
+
const appName = event.slug ? `${event.slug} (${event.app})` : event.app;
|
|
3310
|
+
console.log(`\u{1F4E6} Adding ${appName}...`);
|
|
3311
|
+
break;
|
|
3312
|
+
case "manifest_updated":
|
|
3313
|
+
const appDisplay = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3314
|
+
console.log(
|
|
3315
|
+
`\u{1F4DD} Locked ${appDisplay} to ${event.app}@${event.version} using key '${event.manifestKey}'`
|
|
3316
|
+
);
|
|
3317
|
+
break;
|
|
3318
|
+
case "app_processing_error":
|
|
3319
|
+
const errorApp = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3320
|
+
console.warn(`\u26A0\uFE0F ${event.error} for ${errorApp}`);
|
|
3321
|
+
break;
|
|
3322
|
+
}
|
|
3323
|
+
};
|
|
3324
|
+
const handleTypesProgress = (event) => {
|
|
3325
|
+
switch (event.type) {
|
|
3326
|
+
case "connections_lookup_start":
|
|
3327
|
+
console.log(`\u{1F510} Looking up ${event.count} connection(s)...`);
|
|
3328
|
+
break;
|
|
3329
|
+
case "connections_lookup_complete":
|
|
3330
|
+
console.log(`\u{1F510} Found ${event.count} connection(s)`);
|
|
3331
|
+
break;
|
|
3332
|
+
case "connection_matched":
|
|
3333
|
+
const appWithConnection = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3334
|
+
console.log(
|
|
3335
|
+
`\u{1F510} Using connection ${event.connectionId} (${event.connectionTitle}) for ${appWithConnection}`
|
|
3336
|
+
);
|
|
3337
|
+
break;
|
|
3338
|
+
case "connection_not_matched":
|
|
3339
|
+
const appWithoutConnection = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3340
|
+
console.warn(
|
|
3341
|
+
`\u26A0\uFE0F No matching connection found for ${appWithoutConnection}`
|
|
3342
|
+
);
|
|
3343
|
+
break;
|
|
3344
|
+
case "file_written":
|
|
3345
|
+
console.log(
|
|
3346
|
+
`\u{1F527} Generated types for ${event.manifestKey} at ${event.filePath}`
|
|
3347
|
+
);
|
|
3348
|
+
break;
|
|
3349
|
+
case "app_processing_error":
|
|
3350
|
+
const errorApp = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3351
|
+
console.warn(`\u26A0\uFE0F ${event.error} for ${errorApp}`);
|
|
3352
|
+
break;
|
|
2833
3353
|
}
|
|
3354
|
+
};
|
|
3355
|
+
const manifestResult = await sdk3.buildManifest({
|
|
3356
|
+
apps: appKeys,
|
|
3357
|
+
skipWrite: false,
|
|
3358
|
+
configPath,
|
|
3359
|
+
onProgress: handleManifestProgress
|
|
3360
|
+
});
|
|
3361
|
+
const typesResult = await sdk3.generateAppTypes({
|
|
3362
|
+
apps: appKeys,
|
|
3363
|
+
connections: connectionIds,
|
|
3364
|
+
skipWrite: false,
|
|
3365
|
+
typesOutputDirectory: resolvedTypesOutput,
|
|
3366
|
+
onProgress: handleTypesProgress
|
|
3367
|
+
});
|
|
3368
|
+
const results = manifestResult.manifest?.apps || {};
|
|
3369
|
+
const successfulApps = Object.keys(results).filter(
|
|
3370
|
+
(manifestKey) => typesResult.writtenFiles?.[manifestKey]
|
|
3371
|
+
);
|
|
3372
|
+
if (successfulApps.length > 0) {
|
|
3373
|
+
console.log(`\u2705 Added ${successfulApps.length} app(s) to manifest`);
|
|
2834
3374
|
}
|
|
2835
3375
|
}
|
|
2836
|
-
}
|
|
2837
|
-
|
|
3376
|
+
})
|
|
3377
|
+
);
|
|
2838
3378
|
var GenerateAppTypesSchema = zod.z.object({
|
|
2839
3379
|
apps: zod.z.array(zod.z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required").describe(
|
|
2840
3380
|
"One or more app keys to generate types for (e.g., 'slack', 'github', 'trello')"
|
|
@@ -3441,150 +3981,133 @@ function createManifestEntry(app) {
|
|
|
3441
3981
|
version: app.version
|
|
3442
3982
|
};
|
|
3443
3983
|
}
|
|
3444
|
-
var generateAppTypesPlugin = (
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
}
|
|
3468
|
-
const connections = [];
|
|
3469
|
-
if (connectionIds && connectionIds.length > 0) {
|
|
3470
|
-
onProgress?.({
|
|
3471
|
-
type: "connections_lookup_start",
|
|
3472
|
-
count: connectionIds.length
|
|
3473
|
-
});
|
|
3474
|
-
const connectionsIterable = sdk2.listConnections({ connections: connectionIds }).items();
|
|
3475
|
-
for await (const connection of connectionsIterable) {
|
|
3476
|
-
connections.push(connection);
|
|
3984
|
+
var generateAppTypesPlugin = zapierSdk.definePlugin(
|
|
3985
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
3986
|
+
name: "generateAppTypes",
|
|
3987
|
+
categories: ["utility"],
|
|
3988
|
+
// Cast: schema validates JSON fields only; GenerateAppTypesOptions adds
|
|
3989
|
+
// the runtime-only `onProgress` callback (passthrough via createFunction).
|
|
3990
|
+
inputSchema: GenerateAppTypesSchema,
|
|
3991
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3992
|
+
const {
|
|
3993
|
+
apps: appKeys,
|
|
3994
|
+
connections: connectionIds,
|
|
3995
|
+
skipWrite = false,
|
|
3996
|
+
typesOutputDirectory = await detectTypesOutputDirectory(),
|
|
3997
|
+
onProgress
|
|
3998
|
+
} = options;
|
|
3999
|
+
const resolvedTypesOutput = path.resolve(typesOutputDirectory);
|
|
4000
|
+
const result = { typeDefinitions: {} };
|
|
4001
|
+
onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
|
|
4002
|
+
const appsIterable = sdk3.listApps({ apps: appKeys }).items();
|
|
4003
|
+
const apps = [];
|
|
4004
|
+
for await (const app of appsIterable) {
|
|
4005
|
+
apps.push(app);
|
|
4006
|
+
onProgress?.({ type: "app_found", app });
|
|
3477
4007
|
}
|
|
3478
|
-
onProgress?.({
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
}
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
type: "app_processing_start",
|
|
3492
|
-
app: app.key,
|
|
3493
|
-
slug: app.slug
|
|
3494
|
-
});
|
|
3495
|
-
try {
|
|
3496
|
-
if (!app.version) {
|
|
3497
|
-
const errorMessage = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
|
|
3498
|
-
onProgress?.({
|
|
3499
|
-
type: "app_processing_error",
|
|
3500
|
-
app: app.key,
|
|
3501
|
-
error: errorMessage
|
|
3502
|
-
});
|
|
3503
|
-
throw new zapierSdk.ZapierValidationError(errorMessage, {
|
|
3504
|
-
details: {
|
|
3505
|
-
appKey: app.key,
|
|
3506
|
-
implementationId: app.implementation_id
|
|
3507
|
-
}
|
|
3508
|
-
});
|
|
4008
|
+
onProgress?.({ type: "apps_lookup_complete", count: apps.length });
|
|
4009
|
+
if (apps.length === 0) {
|
|
4010
|
+
return result;
|
|
4011
|
+
}
|
|
4012
|
+
const connections = [];
|
|
4013
|
+
if (connectionIds && connectionIds.length > 0) {
|
|
4014
|
+
onProgress?.({
|
|
4015
|
+
type: "connections_lookup_start",
|
|
4016
|
+
count: connectionIds.length
|
|
4017
|
+
});
|
|
4018
|
+
const connectionsIterable = sdk3.listConnections({ connections: connectionIds }).items();
|
|
4019
|
+
for await (const connection of connectionsIterable) {
|
|
4020
|
+
connections.push(connection);
|
|
3509
4021
|
}
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
4022
|
+
onProgress?.({
|
|
4023
|
+
type: "connections_lookup_complete",
|
|
4024
|
+
count: connections.length
|
|
4025
|
+
});
|
|
4026
|
+
}
|
|
4027
|
+
if (!skipWrite && resolvedTypesOutput) {
|
|
4028
|
+
await promises.mkdir(resolvedTypesOutput, { recursive: true });
|
|
4029
|
+
}
|
|
4030
|
+
if (!skipWrite) {
|
|
4031
|
+
result.writtenFiles = {};
|
|
4032
|
+
}
|
|
4033
|
+
for (const app of apps) {
|
|
4034
|
+
onProgress?.({
|
|
4035
|
+
type: "app_processing_start",
|
|
4036
|
+
app: app.key,
|
|
4037
|
+
slug: app.slug
|
|
4038
|
+
});
|
|
4039
|
+
try {
|
|
4040
|
+
if (!app.version) {
|
|
4041
|
+
const errorMessage = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
|
|
3517
4042
|
onProgress?.({
|
|
3518
|
-
type: "
|
|
4043
|
+
type: "app_processing_error",
|
|
3519
4044
|
app: app.key,
|
|
3520
|
-
|
|
3521
|
-
connectionTitle: matchingConnection.title || ""
|
|
4045
|
+
error: errorMessage
|
|
3522
4046
|
});
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
4047
|
+
throw new zapierSdk.ZapierValidationError(errorMessage, {
|
|
4048
|
+
details: {
|
|
4049
|
+
appKey: app.key,
|
|
4050
|
+
implementationId: app.implementation_id
|
|
4051
|
+
}
|
|
3527
4052
|
});
|
|
3528
4053
|
}
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
4054
|
+
let connectionId;
|
|
4055
|
+
if (connections.length > 0) {
|
|
4056
|
+
const matchingConnection = connections.find(
|
|
4057
|
+
(conn) => conn.app_key === app.key
|
|
4058
|
+
);
|
|
4059
|
+
if (matchingConnection) {
|
|
4060
|
+
connectionId = matchingConnection.id;
|
|
4061
|
+
onProgress?.({
|
|
4062
|
+
type: "connection_matched",
|
|
4063
|
+
app: app.key,
|
|
4064
|
+
connectionId: matchingConnection.id,
|
|
4065
|
+
connectionTitle: matchingConnection.title || ""
|
|
4066
|
+
});
|
|
4067
|
+
} else {
|
|
4068
|
+
onProgress?.({
|
|
4069
|
+
type: "connection_not_matched",
|
|
4070
|
+
app: app.key
|
|
4071
|
+
});
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
const manifestKey = getManifestKey(app);
|
|
4075
|
+
const generator = new AstTypeGenerator();
|
|
4076
|
+
const typeDefinitionString = await generator.generateTypes({
|
|
4077
|
+
app,
|
|
4078
|
+
connectionId,
|
|
4079
|
+
sdk: sdk3
|
|
4080
|
+
});
|
|
4081
|
+
result.typeDefinitions[manifestKey] = typeDefinitionString;
|
|
3547
4082
|
onProgress?.({
|
|
3548
|
-
type: "
|
|
4083
|
+
type: "type_generated",
|
|
3549
4084
|
manifestKey,
|
|
3550
|
-
|
|
4085
|
+
sizeBytes: typeDefinitionString.length
|
|
3551
4086
|
});
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
throw error;
|
|
3566
|
-
} else {
|
|
3567
|
-
throw new zapierSdk.ZapierUnknownError(errorMessage, {
|
|
3568
|
-
cause: error
|
|
3569
|
-
// Works for both Error and non-Error
|
|
4087
|
+
if (!skipWrite && resolvedTypesOutput && result.writtenFiles) {
|
|
4088
|
+
const filePath = path.join(resolvedTypesOutput, `${manifestKey}.d.ts`);
|
|
4089
|
+
await promises.writeFile(filePath, typeDefinitionString, "utf8");
|
|
4090
|
+
result.writtenFiles[manifestKey] = filePath;
|
|
4091
|
+
onProgress?.({ type: "file_written", manifestKey, filePath });
|
|
4092
|
+
}
|
|
4093
|
+
onProgress?.({ type: "app_processing_complete", app: app.key });
|
|
4094
|
+
} catch (error) {
|
|
4095
|
+
const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4096
|
+
onProgress?.({
|
|
4097
|
+
type: "app_processing_error",
|
|
4098
|
+
app: app.key,
|
|
4099
|
+
error: errorMessage
|
|
3570
4100
|
});
|
|
4101
|
+
if (error instanceof zapierSdk.ZapierValidationError) {
|
|
4102
|
+
throw error;
|
|
4103
|
+
}
|
|
4104
|
+
throw new zapierSdk.ZapierUnknownError(errorMessage, { cause: error });
|
|
3571
4105
|
}
|
|
3572
4106
|
}
|
|
4107
|
+
return result;
|
|
3573
4108
|
}
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
return {
|
|
3577
|
-
generateAppTypes,
|
|
3578
|
-
context: {
|
|
3579
|
-
meta: {
|
|
3580
|
-
generateAppTypes: {
|
|
3581
|
-
categories: ["utility"],
|
|
3582
|
-
inputSchema: GenerateAppTypesSchema
|
|
3583
|
-
}
|
|
3584
|
-
}
|
|
3585
|
-
}
|
|
3586
|
-
};
|
|
3587
|
-
};
|
|
4109
|
+
})
|
|
4110
|
+
);
|
|
3588
4111
|
var BuildManifestSchema = zod.z.object({
|
|
3589
4112
|
apps: zod.z.array(zod.z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required").describe(
|
|
3590
4113
|
"One or more app keys to build manifest entries for (e.g., 'slack', 'github', 'trello')"
|
|
@@ -3600,86 +4123,80 @@ var BuildManifestSchema = zod.z.object({
|
|
|
3600
4123
|
);
|
|
3601
4124
|
|
|
3602
4125
|
// src/plugins/buildManifest/index.ts
|
|
3603
|
-
var buildManifestPlugin = (
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
type: "manifest_entry_built",
|
|
3633
|
-
app: app.key,
|
|
3634
|
-
manifestKey: manifestEntry.implementationName,
|
|
3635
|
-
version: manifestEntry.version || ""
|
|
3636
|
-
});
|
|
3637
|
-
const { key: updatedManifestKey, manifest } = await sdk2.context.updateManifestEntry({
|
|
3638
|
-
appKey: app.key,
|
|
3639
|
-
entry: manifestEntry,
|
|
3640
|
-
configPath,
|
|
3641
|
-
skipWrite,
|
|
3642
|
-
manifest: updatedManifest
|
|
3643
|
-
});
|
|
3644
|
-
updatedManifest = manifest;
|
|
3645
|
-
onProgress?.({
|
|
3646
|
-
type: "manifest_updated",
|
|
3647
|
-
app: app.key,
|
|
3648
|
-
manifestKey: updatedManifestKey,
|
|
3649
|
-
version: manifestEntry.version || ""
|
|
3650
|
-
});
|
|
3651
|
-
onProgress?.({ type: "app_processing_complete", app: app.key });
|
|
3652
|
-
} catch (error) {
|
|
3653
|
-
const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4126
|
+
var buildManifestPlugin = zapierSdk.definePlugin(
|
|
4127
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
4128
|
+
name: "buildManifest",
|
|
4129
|
+
categories: ["utility"],
|
|
4130
|
+
// Cast: BuildManifestSchema validates JSON-serializable fields only.
|
|
4131
|
+
// BuildManifestOptions adds an `onProgress` callback that rides through
|
|
4132
|
+
// `createFunction`'s passthrough spread at runtime; this widens TInput
|
|
4133
|
+
// so the handler can read it.
|
|
4134
|
+
inputSchema: BuildManifestSchema,
|
|
4135
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
4136
|
+
const {
|
|
4137
|
+
apps: appKeys,
|
|
4138
|
+
skipWrite = false,
|
|
4139
|
+
configPath,
|
|
4140
|
+
onProgress
|
|
4141
|
+
} = options;
|
|
4142
|
+
onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
|
|
4143
|
+
const appsIterable = sdk3.listApps({ apps: appKeys }).items();
|
|
4144
|
+
const apps = [];
|
|
4145
|
+
for await (const app of appsIterable) {
|
|
4146
|
+
apps.push(app);
|
|
4147
|
+
onProgress?.({ type: "app_found", app });
|
|
4148
|
+
}
|
|
4149
|
+
onProgress?.({ type: "apps_lookup_complete", count: apps.length });
|
|
4150
|
+
if (apps.length === 0) {
|
|
4151
|
+
return {};
|
|
4152
|
+
}
|
|
4153
|
+
let updatedManifest;
|
|
4154
|
+
for (const app of apps) {
|
|
3654
4155
|
onProgress?.({
|
|
3655
|
-
type: "
|
|
4156
|
+
type: "app_processing_start",
|
|
3656
4157
|
app: app.key,
|
|
3657
|
-
|
|
4158
|
+
slug: app.slug
|
|
3658
4159
|
});
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
4160
|
+
try {
|
|
4161
|
+
const manifestEntry = createManifestEntry(app);
|
|
4162
|
+
onProgress?.({
|
|
4163
|
+
type: "manifest_entry_built",
|
|
4164
|
+
app: app.key,
|
|
4165
|
+
manifestKey: manifestEntry.implementationName,
|
|
4166
|
+
version: manifestEntry.version || ""
|
|
3665
4167
|
});
|
|
4168
|
+
const { key: updatedManifestKey, manifest } = await sdk3.context.updateManifestEntry({
|
|
4169
|
+
appKey: app.key,
|
|
4170
|
+
entry: manifestEntry,
|
|
4171
|
+
configPath,
|
|
4172
|
+
skipWrite,
|
|
4173
|
+
manifest: updatedManifest
|
|
4174
|
+
});
|
|
4175
|
+
updatedManifest = manifest;
|
|
4176
|
+
onProgress?.({
|
|
4177
|
+
type: "manifest_updated",
|
|
4178
|
+
app: app.key,
|
|
4179
|
+
manifestKey: updatedManifestKey,
|
|
4180
|
+
version: manifestEntry.version || ""
|
|
4181
|
+
});
|
|
4182
|
+
onProgress?.({ type: "app_processing_complete", app: app.key });
|
|
4183
|
+
} catch (error) {
|
|
4184
|
+
const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4185
|
+
onProgress?.({
|
|
4186
|
+
type: "app_processing_error",
|
|
4187
|
+
app: app.key,
|
|
4188
|
+
error: errorMessage
|
|
4189
|
+
});
|
|
4190
|
+
if (error instanceof zapierSdk.ZapierValidationError) {
|
|
4191
|
+
throw error;
|
|
4192
|
+
}
|
|
4193
|
+
throw new zapierSdk.ZapierUnknownError(errorMessage, { cause: error });
|
|
3666
4194
|
}
|
|
3667
4195
|
}
|
|
4196
|
+
return { manifest: updatedManifest };
|
|
3668
4197
|
}
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
return {
|
|
3672
|
-
buildManifest,
|
|
3673
|
-
context: {
|
|
3674
|
-
meta: {
|
|
3675
|
-
buildManifest: {
|
|
3676
|
-
categories: ["utility"],
|
|
3677
|
-
inputSchema: BuildManifestSchema
|
|
3678
|
-
}
|
|
3679
|
-
}
|
|
3680
|
-
}
|
|
3681
|
-
};
|
|
3682
|
-
};
|
|
4198
|
+
})
|
|
4199
|
+
);
|
|
3683
4200
|
var FeedbackSchema = zod.z.object({
|
|
3684
4201
|
feedback: zod.z.string().describe(
|
|
3685
4202
|
"Your feedback on the Zapier SDK. Describe what worked well, what was frustrating, or any suggestions."
|
|
@@ -3713,37 +4230,31 @@ async function postWithRetry({
|
|
|
3713
4230
|
}
|
|
3714
4231
|
return response;
|
|
3715
4232
|
}
|
|
3716
|
-
var feedbackPlugin = (
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
feedback: {
|
|
3737
|
-
categories: ["utility"],
|
|
3738
|
-
inputSchema: FeedbackSchema,
|
|
3739
|
-
resolvers: {
|
|
3740
|
-
feedback: feedbackResolver
|
|
3741
|
-
}
|
|
3742
|
-
}
|
|
4233
|
+
var feedbackPlugin = zapierSdk.definePlugin(
|
|
4234
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
4235
|
+
name: "feedback",
|
|
4236
|
+
categories: ["utility"],
|
|
4237
|
+
inputSchema: FeedbackSchema,
|
|
4238
|
+
resolvers: { feedback: feedbackResolver },
|
|
4239
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
4240
|
+
const user = await getLoggedInUser();
|
|
4241
|
+
const body = JSON.stringify({
|
|
4242
|
+
email: user.email,
|
|
4243
|
+
customuser_id: user.customUserId,
|
|
4244
|
+
feedback: options.feedback
|
|
4245
|
+
});
|
|
4246
|
+
const response = await postWithRetry({
|
|
4247
|
+
body,
|
|
4248
|
+
attemptsLeft: MAX_RETRIES
|
|
4249
|
+
});
|
|
4250
|
+
if (sdk3.context.options?.debug) {
|
|
4251
|
+
const text = await response.text();
|
|
4252
|
+
console.error("[debug] Webhook response:", text);
|
|
3743
4253
|
}
|
|
4254
|
+
return "Thank you for your feedback!";
|
|
3744
4255
|
}
|
|
3745
|
-
}
|
|
3746
|
-
|
|
4256
|
+
})
|
|
4257
|
+
);
|
|
3747
4258
|
var CurlSchema = zod.z.object({
|
|
3748
4259
|
url: zod.z.string().describe("Request URL"),
|
|
3749
4260
|
request: zod.z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method (defaults to GET, or POST if data is provided)"),
|
|
@@ -3919,7 +4430,7 @@ async function buildFormData(formArgs, formStringArgs) {
|
|
|
3919
4430
|
}
|
|
3920
4431
|
|
|
3921
4432
|
// src/plugins/curl/index.ts
|
|
3922
|
-
var curlPlugin = (sdk2) => {
|
|
4433
|
+
var curlPlugin = zapierSdk.definePlugin((sdk2) => {
|
|
3923
4434
|
async function curl(options) {
|
|
3924
4435
|
const {
|
|
3925
4436
|
url: rawUrl,
|
|
@@ -4162,30 +4673,25 @@ ${Array.from(
|
|
|
4162
4673
|
}
|
|
4163
4674
|
}
|
|
4164
4675
|
};
|
|
4165
|
-
};
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
...sdk2.context.meta.fetch.categories || [],
|
|
4179
|
-
"deprecated"
|
|
4180
|
-
],
|
|
4181
|
-
deprecation: {
|
|
4182
|
-
message: "This command is deprecated and will be removed soon. Use `curl` instead. Learn more: https://docs.zapier.com/sdk/cli-reference#curl"
|
|
4183
|
-
}
|
|
4676
|
+
});
|
|
4677
|
+
var cliOverridesPlugin = zapierSdk.definePlugin(
|
|
4678
|
+
(sdk2) => {
|
|
4679
|
+
const meta = {};
|
|
4680
|
+
if (sdk2.context.meta.fetch) {
|
|
4681
|
+
meta.fetch = {
|
|
4682
|
+
...sdk2.context.meta.fetch,
|
|
4683
|
+
categories: [
|
|
4684
|
+
...sdk2.context.meta.fetch.categories || [],
|
|
4685
|
+
"deprecated"
|
|
4686
|
+
],
|
|
4687
|
+
deprecation: {
|
|
4688
|
+
message: "This command is deprecated and will be removed soon. Use `curl` instead. Learn more: https://docs.zapier.com/sdk/cli-reference#curl"
|
|
4184
4689
|
}
|
|
4185
|
-
}
|
|
4690
|
+
};
|
|
4186
4691
|
}
|
|
4187
|
-
|
|
4188
|
-
}
|
|
4692
|
+
return { context: { meta } };
|
|
4693
|
+
}
|
|
4694
|
+
);
|
|
4189
4695
|
var TEMPLATES = ["basic"];
|
|
4190
4696
|
var InitSchema = zod.z.object({
|
|
4191
4697
|
projectName: zod.z.string().min(1).describe("Name of the project directory to create"),
|
|
@@ -4624,74 +5130,68 @@ function displaySummaryAndNextSteps({
|
|
|
4624
5130
|
}
|
|
4625
5131
|
|
|
4626
5132
|
// src/plugins/init/index.ts
|
|
4627
|
-
var initPlugin = (
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
);
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
packageManager,
|
|
4644
|
-
displayHooks
|
|
4645
|
-
});
|
|
4646
|
-
const completedSetupStepIds = [];
|
|
4647
|
-
for (let i = 0; i < steps.length; i++) {
|
|
4648
|
-
const step = steps[i];
|
|
4649
|
-
const succeeded = await withInterruptCleanup(
|
|
4650
|
-
step.cleanup,
|
|
4651
|
-
() => runStep({
|
|
4652
|
-
step,
|
|
4653
|
-
stepNumber: i + 1,
|
|
4654
|
-
totalSteps: steps.length,
|
|
4655
|
-
skipPrompts,
|
|
4656
|
-
displayHooks
|
|
4657
|
-
})
|
|
4658
|
-
);
|
|
4659
|
-
if (!succeeded) break;
|
|
4660
|
-
completedSetupStepIds.push(step.id);
|
|
4661
|
-
}
|
|
4662
|
-
if (completedSetupStepIds.length === 0) {
|
|
4663
|
-
throw new ZapierCliExitError(
|
|
4664
|
-
"Project setup failed \u2014 no steps completed."
|
|
4665
|
-
);
|
|
4666
|
-
}
|
|
4667
|
-
displaySummaryAndNextSteps({
|
|
4668
|
-
projectName,
|
|
4669
|
-
steps,
|
|
4670
|
-
completedSetupStepIds,
|
|
4671
|
-
packageManager
|
|
4672
|
-
});
|
|
4673
|
-
}, InitSchema);
|
|
4674
|
-
return {
|
|
4675
|
-
init,
|
|
4676
|
-
context: {
|
|
4677
|
-
meta: {
|
|
4678
|
-
init: {
|
|
4679
|
-
categories: ["utility"],
|
|
4680
|
-
inputSchema: InitSchema,
|
|
4681
|
-
supportsJsonOutput: false
|
|
4682
|
-
}
|
|
5133
|
+
var initPlugin = zapierSdk.definePlugin(
|
|
5134
|
+
(sdk2) => zapierSdk.createPluginMethod(sdk2, {
|
|
5135
|
+
name: "init",
|
|
5136
|
+
categories: ["utility"],
|
|
5137
|
+
inputSchema: InitSchema,
|
|
5138
|
+
supportsJsonOutput: false,
|
|
5139
|
+
handler: async ({ options }) => {
|
|
5140
|
+
const { projectName: rawName, skipPrompts = false } = options;
|
|
5141
|
+
const cwd = process.cwd();
|
|
5142
|
+
const { projectName, projectDir } = validateInitOptions({ rawName, cwd });
|
|
5143
|
+
const displayHooks = createConsoleDisplayHooks();
|
|
5144
|
+
const packageManagerInfo = detectPackageManager(cwd);
|
|
5145
|
+
if (packageManagerInfo.name === "unknown") {
|
|
5146
|
+
displayHooks.onWarn(
|
|
5147
|
+
"Could not detect package manager, defaulting to npm."
|
|
5148
|
+
);
|
|
4683
5149
|
}
|
|
5150
|
+
const packageManager = packageManagerInfo.name === "unknown" ? "npm" : packageManagerInfo.name;
|
|
5151
|
+
const steps = getInitSteps({
|
|
5152
|
+
projectDir,
|
|
5153
|
+
projectName,
|
|
5154
|
+
packageManager,
|
|
5155
|
+
displayHooks
|
|
5156
|
+
});
|
|
5157
|
+
const completedSetupStepIds = [];
|
|
5158
|
+
for (let i = 0; i < steps.length; i++) {
|
|
5159
|
+
const step = steps[i];
|
|
5160
|
+
const succeeded = await withInterruptCleanup(
|
|
5161
|
+
step.cleanup,
|
|
5162
|
+
() => runStep({
|
|
5163
|
+
step,
|
|
5164
|
+
stepNumber: i + 1,
|
|
5165
|
+
totalSteps: steps.length,
|
|
5166
|
+
skipPrompts,
|
|
5167
|
+
displayHooks
|
|
5168
|
+
})
|
|
5169
|
+
);
|
|
5170
|
+
if (!succeeded) break;
|
|
5171
|
+
completedSetupStepIds.push(step.id);
|
|
5172
|
+
}
|
|
5173
|
+
if (completedSetupStepIds.length === 0) {
|
|
5174
|
+
throw new ZapierCliExitError(
|
|
5175
|
+
"Project setup failed \u2014 no steps completed."
|
|
5176
|
+
);
|
|
5177
|
+
}
|
|
5178
|
+
displaySummaryAndNextSteps({
|
|
5179
|
+
projectName,
|
|
5180
|
+
steps,
|
|
5181
|
+
completedSetupStepIds,
|
|
5182
|
+
packageManager
|
|
5183
|
+
});
|
|
4684
5184
|
}
|
|
4685
|
-
}
|
|
4686
|
-
|
|
5185
|
+
})
|
|
5186
|
+
);
|
|
4687
5187
|
|
|
4688
5188
|
// package.json with { type: 'json' }
|
|
4689
5189
|
var package_default2 = {
|
|
4690
5190
|
name: "@zapier/zapier-sdk-cli",
|
|
4691
|
-
version: "0.
|
|
5191
|
+
version: "0.43.1"};
|
|
4692
5192
|
|
|
4693
5193
|
// src/sdk.ts
|
|
4694
|
-
zapierSdk.injectCliLogin(
|
|
5194
|
+
zapierSdk.injectCliLogin(login_exports);
|
|
4695
5195
|
function createZapierCliSdk(options = {}) {
|
|
4696
5196
|
return zapierSdk.createZapierSdk({
|
|
4697
5197
|
...options,
|
|
@@ -4710,14 +5210,14 @@ var CACHE_RESET_INTERVAL_MS = (() => {
|
|
|
4710
5210
|
})();
|
|
4711
5211
|
function getVersionCache() {
|
|
4712
5212
|
try {
|
|
4713
|
-
const cache =
|
|
5213
|
+
const cache = getConfig().get("version_cache");
|
|
4714
5214
|
const now = Date.now();
|
|
4715
5215
|
if (!cache || !cache.last_reset_timestamp || now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MS) {
|
|
4716
5216
|
const newCache = {
|
|
4717
5217
|
last_reset_timestamp: now,
|
|
4718
5218
|
packages: {}
|
|
4719
5219
|
};
|
|
4720
|
-
|
|
5220
|
+
getConfig().set("version_cache", newCache);
|
|
4721
5221
|
return newCache;
|
|
4722
5222
|
}
|
|
4723
5223
|
return cache;
|
|
@@ -4736,7 +5236,7 @@ function setCachedPackageInfo(packageName, version, info) {
|
|
|
4736
5236
|
cache.packages[packageName] = {};
|
|
4737
5237
|
}
|
|
4738
5238
|
cache.packages[packageName][version] = info;
|
|
4739
|
-
|
|
5239
|
+
getConfig().set("version_cache", cache);
|
|
4740
5240
|
} catch (error) {
|
|
4741
5241
|
log_default.debug(`Failed to cache package info: ${error}`);
|
|
4742
5242
|
}
|