@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.mjs
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command, CommanderError, Option } from 'commander';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import {
|
|
4
|
+
import { definePlugin, createPluginMethod, buildApplicationLifecycleEvent, OutputPropertySchema, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, injectCliLogin, BaseSdkOptionsSchema, isCredentialsObject, batch, toSnakeCase, createZapierSdk, ZapierError, isPositional, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } from '@zapier/zapier-sdk';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
6
|
import chalk7 from 'chalk';
|
|
7
7
|
import ora from 'ora';
|
|
8
8
|
import util from 'util';
|
|
9
9
|
import wrapAnsi from 'wrap-ansi';
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
10
|
+
import Conf from 'conf';
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import { promises, createWriteStream, existsSync, readdirSync, rmSync, mkdirSync, writeFileSync, copyFileSync, readFileSync } from 'fs';
|
|
13
|
+
import * as jwt from 'jsonwebtoken';
|
|
14
|
+
import { getPassword, getKeyring, setPassword, deletePassword } from 'cross-keychain';
|
|
13
15
|
import crypto, { createHash } from 'crypto';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import { resolve, join, dirname, basename, relative, extname } from 'path';
|
|
18
|
+
import * as lockfile from 'proper-lockfile';
|
|
19
|
+
import open from 'open';
|
|
14
20
|
import express from 'express';
|
|
15
21
|
import pkceChallenge from 'pkce-challenge';
|
|
16
22
|
import { startMcpServer } from '@zapier/zapier-sdk-mcp';
|
|
17
23
|
import { buildSync } from 'esbuild';
|
|
18
|
-
import * as fs from 'fs';
|
|
19
|
-
import { promises, createWriteStream, existsSync, readdirSync, rmSync, mkdirSync, writeFileSync, copyFileSync, readFileSync } from 'fs';
|
|
20
|
-
import * as path from 'path';
|
|
21
|
-
import { resolve, join, dirname, basename, relative, extname } from 'path';
|
|
22
24
|
import { mkdir, writeFile, access } from 'fs/promises';
|
|
23
25
|
import * as ts from 'typescript';
|
|
24
26
|
import isInstalledGlobally from 'is-installed-globally';
|
|
@@ -28,6 +30,11 @@ import { fileURLToPath } from 'url';
|
|
|
28
30
|
import packageJsonLib from 'package-json';
|
|
29
31
|
import semver from 'semver';
|
|
30
32
|
|
|
33
|
+
var __defProp = Object.defineProperty;
|
|
34
|
+
var __export = (target, all) => {
|
|
35
|
+
for (var name in all)
|
|
36
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
37
|
+
};
|
|
31
38
|
var ZapierCliError = class extends ZapierError {
|
|
32
39
|
};
|
|
33
40
|
var ZapierCliUserCancellationError = class extends ZapierCliError {
|
|
@@ -1065,7 +1072,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
1065
1072
|
|
|
1066
1073
|
// package.json
|
|
1067
1074
|
var package_default = {
|
|
1068
|
-
version: "0.
|
|
1075
|
+
version: "0.43.1"};
|
|
1069
1076
|
|
|
1070
1077
|
// src/telemetry/builders.ts
|
|
1071
1078
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1795,8 +1802,8 @@ function generateCliCommands(program2, sdk2) {
|
|
|
1795
1802
|
return;
|
|
1796
1803
|
}
|
|
1797
1804
|
const cliCommandName = methodNameToCliCommand(fnInfo.name);
|
|
1798
|
-
const
|
|
1799
|
-
addCommand(program2, cliCommandName,
|
|
1805
|
+
const config2 = createCommandConfig(cliCommandName, fnInfo, sdk2);
|
|
1806
|
+
addCommand(program2, cliCommandName, config2);
|
|
1800
1807
|
});
|
|
1801
1808
|
program2.configureHelp({
|
|
1802
1809
|
formatHelp: (cmd, helper) => {
|
|
@@ -2053,10 +2060,10 @@ function collect(value, previous = []) {
|
|
|
2053
2060
|
previous.push(value);
|
|
2054
2061
|
return previous;
|
|
2055
2062
|
}
|
|
2056
|
-
function addCommand(program2, commandName,
|
|
2057
|
-
const command = program2.command(commandName, { hidden:
|
|
2063
|
+
function addCommand(program2, commandName, config2) {
|
|
2064
|
+
const command = program2.command(commandName, { hidden: config2.hidden ?? false }).description(config2.description);
|
|
2058
2065
|
let hasPositionalArray = false;
|
|
2059
|
-
|
|
2066
|
+
config2.parameters.forEach((param) => {
|
|
2060
2067
|
const kebabName = toKebabCase(param.name);
|
|
2061
2068
|
if (param.hasResolver && param.required) {
|
|
2062
2069
|
command.argument(
|
|
@@ -2090,7 +2097,7 @@ function addCommand(program2, commandName, config) {
|
|
|
2090
2097
|
);
|
|
2091
2098
|
} else {
|
|
2092
2099
|
const flags = [];
|
|
2093
|
-
const alias =
|
|
2100
|
+
const alias = config2.aliases?.[param.name];
|
|
2094
2101
|
if (alias && alias.length === 1) {
|
|
2095
2102
|
flags.push(`-${alias}`);
|
|
2096
2103
|
}
|
|
@@ -2119,13 +2126,13 @@ function addCommand(program2, commandName, config) {
|
|
|
2119
2126
|
}
|
|
2120
2127
|
}
|
|
2121
2128
|
});
|
|
2122
|
-
const paramNames = new Set(
|
|
2129
|
+
const paramNames = new Set(config2.parameters.map((p) => p.name));
|
|
2123
2130
|
SHARED_COMMAND_CLI_OPTIONS.forEach((opt) => {
|
|
2124
2131
|
if (paramNames.has(opt.name)) return;
|
|
2125
|
-
if (
|
|
2132
|
+
if (config2.supportsJsonOutput === false && opt.name === "json") return;
|
|
2126
2133
|
command.option(opt.flag, opt.description);
|
|
2127
2134
|
});
|
|
2128
|
-
command.action(
|
|
2135
|
+
command.action(config2.handler);
|
|
2129
2136
|
}
|
|
2130
2137
|
function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
2131
2138
|
const sdkParams = {};
|
|
@@ -2197,6 +2204,581 @@ function convertValue(value, type, elementType) {
|
|
|
2197
2204
|
return value;
|
|
2198
2205
|
}
|
|
2199
2206
|
}
|
|
2207
|
+
|
|
2208
|
+
// src/login.ts
|
|
2209
|
+
var login_exports = {};
|
|
2210
|
+
__export(login_exports, {
|
|
2211
|
+
AUTH_MODE_HEADER: () => AUTH_MODE_HEADER,
|
|
2212
|
+
ZapierAuthenticationError: () => ZapierAuthenticationError,
|
|
2213
|
+
createCache: () => createCache,
|
|
2214
|
+
getAuthAuthorizeUrl: () => getAuthAuthorizeUrl,
|
|
2215
|
+
getAuthTokenUrl: () => getAuthTokenUrl,
|
|
2216
|
+
getConfig: () => getConfig,
|
|
2217
|
+
getConfigPath: () => getConfigPath,
|
|
2218
|
+
getLoggedInUser: () => getLoggedInUser,
|
|
2219
|
+
getLoginStorageMode: () => getLoginStorageMode,
|
|
2220
|
+
getPkceLoginConfig: () => getPkceLoginConfig,
|
|
2221
|
+
getToken: () => getToken,
|
|
2222
|
+
logout: () => logout,
|
|
2223
|
+
unloadConfig: () => unloadConfig,
|
|
2224
|
+
updateLogin: () => updateLogin
|
|
2225
|
+
});
|
|
2226
|
+
var SERVICE = "zapier-sdk-cli";
|
|
2227
|
+
var ACCOUNT = "login";
|
|
2228
|
+
var cachedBackendInfo;
|
|
2229
|
+
async function getBackendInfo() {
|
|
2230
|
+
if (!cachedBackendInfo) {
|
|
2231
|
+
const keyring = await getKeyring();
|
|
2232
|
+
cachedBackendInfo = `${keyring.name} (${keyring.id})`;
|
|
2233
|
+
}
|
|
2234
|
+
return cachedBackendInfo;
|
|
2235
|
+
}
|
|
2236
|
+
var keychainQueue = Promise.resolve();
|
|
2237
|
+
function enqueue(fn) {
|
|
2238
|
+
const result = keychainQueue.then(fn, fn);
|
|
2239
|
+
keychainQueue = result.then(
|
|
2240
|
+
() => {
|
|
2241
|
+
},
|
|
2242
|
+
() => {
|
|
2243
|
+
}
|
|
2244
|
+
);
|
|
2245
|
+
return result;
|
|
2246
|
+
}
|
|
2247
|
+
async function getTokensFromKeychain({
|
|
2248
|
+
debugLog
|
|
2249
|
+
} = {}) {
|
|
2250
|
+
return enqueue(async () => {
|
|
2251
|
+
const backendInfo = await getBackendInfo();
|
|
2252
|
+
debugLog?.(`Keychain read via ${backendInfo}`);
|
|
2253
|
+
const startTime = Date.now();
|
|
2254
|
+
const raw = await getPassword(SERVICE, ACCOUNT);
|
|
2255
|
+
debugLog?.(`Keychain read completed in ${Date.now() - startTime}ms`);
|
|
2256
|
+
if (!raw) {
|
|
2257
|
+
debugLog?.("Keychain returned no data");
|
|
2258
|
+
return void 0;
|
|
2259
|
+
}
|
|
2260
|
+
let parsed;
|
|
2261
|
+
try {
|
|
2262
|
+
parsed = JSON.parse(raw);
|
|
2263
|
+
} catch {
|
|
2264
|
+
debugLog?.("Keychain data is not valid JSON");
|
|
2265
|
+
return void 0;
|
|
2266
|
+
}
|
|
2267
|
+
if (typeof parsed.login_jwt === "string" && typeof parsed.login_refresh_token === "string") {
|
|
2268
|
+
return {
|
|
2269
|
+
login_jwt: parsed.login_jwt,
|
|
2270
|
+
login_refresh_token: parsed.login_refresh_token
|
|
2271
|
+
};
|
|
2272
|
+
}
|
|
2273
|
+
debugLog?.("Keychain data has invalid shape", parsed);
|
|
2274
|
+
return void 0;
|
|
2275
|
+
});
|
|
2276
|
+
}
|
|
2277
|
+
async function setTokensInKeychain({
|
|
2278
|
+
data,
|
|
2279
|
+
debugLog
|
|
2280
|
+
}) {
|
|
2281
|
+
return enqueue(async () => {
|
|
2282
|
+
const backendInfo = await getBackendInfo();
|
|
2283
|
+
debugLog?.(`Keychain write via ${backendInfo}`);
|
|
2284
|
+
const startTime = Date.now();
|
|
2285
|
+
await setPassword(SERVICE, ACCOUNT, JSON.stringify(data));
|
|
2286
|
+
debugLog?.(`Keychain write completed in ${Date.now() - startTime}ms`);
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
async function clearTokensFromKeychain({
|
|
2290
|
+
debugLog
|
|
2291
|
+
} = {}) {
|
|
2292
|
+
return enqueue(async () => {
|
|
2293
|
+
try {
|
|
2294
|
+
const backendInfo = await getBackendInfo();
|
|
2295
|
+
debugLog?.(`Keychain clear via ${backendInfo}`);
|
|
2296
|
+
await deletePassword(SERVICE, ACCOUNT);
|
|
2297
|
+
} catch {
|
|
2298
|
+
}
|
|
2299
|
+
});
|
|
2300
|
+
}
|
|
2301
|
+
var SERVICE2 = "zapier-sdk-cache";
|
|
2302
|
+
var CONFIG_KEY = "cache";
|
|
2303
|
+
var LOCK_UPDATE_MS = 5e3;
|
|
2304
|
+
var LOCK_STALE_MS = 1e4;
|
|
2305
|
+
var LOCK_RETRY_WAIT_MS = 100;
|
|
2306
|
+
var LOCK_RETRY_MAX_WAIT_MS = 1e3;
|
|
2307
|
+
var LOCK_RETRY_COUNT = 120;
|
|
2308
|
+
function keychainAccount(key) {
|
|
2309
|
+
return createHash("sha256").update(key).digest("hex");
|
|
2310
|
+
}
|
|
2311
|
+
function readConfigMap() {
|
|
2312
|
+
const cfg = getConfig();
|
|
2313
|
+
const stored = cfg.get(CONFIG_KEY);
|
|
2314
|
+
if (stored && typeof stored === "object") {
|
|
2315
|
+
return stored;
|
|
2316
|
+
}
|
|
2317
|
+
return {};
|
|
2318
|
+
}
|
|
2319
|
+
function writeConfigMap(map) {
|
|
2320
|
+
getConfig().set(CONFIG_KEY, map);
|
|
2321
|
+
}
|
|
2322
|
+
function entryIsExpired(entry) {
|
|
2323
|
+
return entry.expires_at !== void 0 && entry.expires_at <= Date.now();
|
|
2324
|
+
}
|
|
2325
|
+
function createCache() {
|
|
2326
|
+
return {
|
|
2327
|
+
async get(key) {
|
|
2328
|
+
const entry = readConfigMap()[key];
|
|
2329
|
+
if (!entry) return void 0;
|
|
2330
|
+
if (entryIsExpired(entry)) return void 0;
|
|
2331
|
+
if (entry.secret) {
|
|
2332
|
+
const stored = await enqueue(async () => {
|
|
2333
|
+
await getBackendInfo();
|
|
2334
|
+
return getPassword(SERVICE2, keychainAccount(key));
|
|
2335
|
+
});
|
|
2336
|
+
if (!stored) {
|
|
2337
|
+
return void 0;
|
|
2338
|
+
}
|
|
2339
|
+
return { value: stored, expiresAt: entry.expires_at };
|
|
2340
|
+
}
|
|
2341
|
+
if (entry.value === void 0) return void 0;
|
|
2342
|
+
return { value: entry.value, expiresAt: entry.expires_at };
|
|
2343
|
+
},
|
|
2344
|
+
async set(key, value, options) {
|
|
2345
|
+
const secret = options?.secret ?? false;
|
|
2346
|
+
const expiresAt = options?.ttl ? Date.now() + options.ttl * 1e3 : void 0;
|
|
2347
|
+
if (secret) {
|
|
2348
|
+
try {
|
|
2349
|
+
await enqueue(async () => {
|
|
2350
|
+
await getBackendInfo();
|
|
2351
|
+
await setPassword(SERVICE2, keychainAccount(key), value);
|
|
2352
|
+
});
|
|
2353
|
+
} catch {
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
const map = readConfigMap();
|
|
2357
|
+
map[key] = { secret: true, expires_at: expiresAt };
|
|
2358
|
+
try {
|
|
2359
|
+
writeConfigMap(map);
|
|
2360
|
+
} catch {
|
|
2361
|
+
}
|
|
2362
|
+
} else {
|
|
2363
|
+
const map = readConfigMap();
|
|
2364
|
+
map[key] = { secret: false, value, expires_at: expiresAt };
|
|
2365
|
+
try {
|
|
2366
|
+
writeConfigMap(map);
|
|
2367
|
+
} catch {
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
},
|
|
2371
|
+
async delete(key) {
|
|
2372
|
+
const map = readConfigMap();
|
|
2373
|
+
const entry = map[key];
|
|
2374
|
+
if (entry) {
|
|
2375
|
+
delete map[key];
|
|
2376
|
+
try {
|
|
2377
|
+
writeConfigMap(map);
|
|
2378
|
+
} catch {
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
if (entry?.secret) {
|
|
2382
|
+
try {
|
|
2383
|
+
await enqueue(async () => {
|
|
2384
|
+
await getBackendInfo();
|
|
2385
|
+
await deletePassword(SERVICE2, keychainAccount(key));
|
|
2386
|
+
});
|
|
2387
|
+
} catch {
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
},
|
|
2391
|
+
async withLock(_key, fn) {
|
|
2392
|
+
const cfg = getConfig();
|
|
2393
|
+
const lockTarget = `${cfg.path}.cache-lock`;
|
|
2394
|
+
try {
|
|
2395
|
+
mkdirSync(dirname(lockTarget), { recursive: true });
|
|
2396
|
+
if (!existsSync(lockTarget)) {
|
|
2397
|
+
writeFileSync(lockTarget, "");
|
|
2398
|
+
}
|
|
2399
|
+
} catch {
|
|
2400
|
+
return fn();
|
|
2401
|
+
}
|
|
2402
|
+
let release = null;
|
|
2403
|
+
try {
|
|
2404
|
+
release = await lockfile.lock(lockTarget, {
|
|
2405
|
+
stale: LOCK_STALE_MS,
|
|
2406
|
+
update: LOCK_UPDATE_MS,
|
|
2407
|
+
retries: {
|
|
2408
|
+
retries: LOCK_RETRY_COUNT,
|
|
2409
|
+
factor: 1.2,
|
|
2410
|
+
minTimeout: LOCK_RETRY_WAIT_MS,
|
|
2411
|
+
maxTimeout: LOCK_RETRY_MAX_WAIT_MS
|
|
2412
|
+
}
|
|
2413
|
+
});
|
|
2414
|
+
} catch {
|
|
2415
|
+
return fn();
|
|
2416
|
+
}
|
|
2417
|
+
try {
|
|
2418
|
+
return await fn();
|
|
2419
|
+
} finally {
|
|
2420
|
+
try {
|
|
2421
|
+
await release();
|
|
2422
|
+
} catch {
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
// src/login/index.ts
|
|
2430
|
+
var ZapierAuthenticationError = class extends Error {
|
|
2431
|
+
constructor(message) {
|
|
2432
|
+
super(message);
|
|
2433
|
+
this.name = "ZapierAuthenticationError";
|
|
2434
|
+
}
|
|
2435
|
+
};
|
|
2436
|
+
var config = null;
|
|
2437
|
+
var DEFAULT_AUTH_CLIENT_ID = "grwWZD5hUWGvb4V8ODBuOtXer3h0DBEZ2HR8aay6";
|
|
2438
|
+
var TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
2439
|
+
function createDebugLog(enabled) {
|
|
2440
|
+
if (!enabled) {
|
|
2441
|
+
return () => {
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2444
|
+
return (message, data) => {
|
|
2445
|
+
if (data === void 0) {
|
|
2446
|
+
console.log(`[Zapier SDK CLI Login] ${message}`);
|
|
2447
|
+
} else {
|
|
2448
|
+
console.log(`[Zapier SDK CLI Login] ${message}`, data);
|
|
2449
|
+
}
|
|
2450
|
+
};
|
|
2451
|
+
}
|
|
2452
|
+
function censorHeaderValue(value) {
|
|
2453
|
+
if (value.length > 12) {
|
|
2454
|
+
return `${value.substring(0, 4)}...${value.substring(value.length - 4)}`;
|
|
2455
|
+
}
|
|
2456
|
+
return `${value.charAt(0)}...`;
|
|
2457
|
+
}
|
|
2458
|
+
function getAuthClientId(clientId) {
|
|
2459
|
+
return clientId || DEFAULT_AUTH_CLIENT_ID;
|
|
2460
|
+
}
|
|
2461
|
+
var AUTH_MODE_HEADER = "X-Auth";
|
|
2462
|
+
var DEFAULT_AUTH_BASE_URL = "https://zapier.com";
|
|
2463
|
+
function getAuthTokenUrl(options) {
|
|
2464
|
+
const authBaseUrl = options?.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
2465
|
+
return `${authBaseUrl}/oauth/token/`;
|
|
2466
|
+
}
|
|
2467
|
+
function getAuthAuthorizeUrl(options) {
|
|
2468
|
+
const authBaseUrl = options?.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
2469
|
+
return `${authBaseUrl}/oauth/authorize/`;
|
|
2470
|
+
}
|
|
2471
|
+
function getPkceLoginConfig(options) {
|
|
2472
|
+
return {
|
|
2473
|
+
clientId: getAuthClientId(options?.credentials?.clientId),
|
|
2474
|
+
tokenUrl: getAuthTokenUrl({ baseUrl: options?.credentials?.baseUrl }),
|
|
2475
|
+
authorizeUrl: getAuthAuthorizeUrl({
|
|
2476
|
+
baseUrl: options?.credentials?.baseUrl
|
|
2477
|
+
})
|
|
2478
|
+
};
|
|
2479
|
+
}
|
|
2480
|
+
var cachedLogin;
|
|
2481
|
+
function getConfig() {
|
|
2482
|
+
if (!config) {
|
|
2483
|
+
config = new Conf({ projectName: "zapier-sdk-cli" });
|
|
2484
|
+
if (!config.has("login_storage_mode")) {
|
|
2485
|
+
config.set(
|
|
2486
|
+
"login_storage_mode",
|
|
2487
|
+
existsSync(config.path) ? "config" : "keychain"
|
|
2488
|
+
);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
return config;
|
|
2492
|
+
}
|
|
2493
|
+
function unloadConfig() {
|
|
2494
|
+
config = null;
|
|
2495
|
+
cachedLogin = void 0;
|
|
2496
|
+
}
|
|
2497
|
+
async function updateLogin(loginData, options = {}) {
|
|
2498
|
+
const debugLog = createDebugLog(options.debug ?? false);
|
|
2499
|
+
const storage = options.storage ?? cachedLogin?.storage ?? "keychain";
|
|
2500
|
+
const expiresAt = Date.now() + loginData.expires_in * 1e3;
|
|
2501
|
+
const cfg = getConfig();
|
|
2502
|
+
cfg.set("login_storage_mode", storage);
|
|
2503
|
+
if (storage === "keychain") {
|
|
2504
|
+
await setTokensInKeychain({
|
|
2505
|
+
data: {
|
|
2506
|
+
login_jwt: loginData.access_token,
|
|
2507
|
+
login_refresh_token: loginData.refresh_token
|
|
2508
|
+
},
|
|
2509
|
+
debugLog
|
|
2510
|
+
});
|
|
2511
|
+
cfg.set("login_expires_at", expiresAt);
|
|
2512
|
+
cfg.delete("login_jwt");
|
|
2513
|
+
cfg.delete("login_refresh_token");
|
|
2514
|
+
} else {
|
|
2515
|
+
cfg.set("login_jwt", loginData.access_token);
|
|
2516
|
+
cfg.set("login_refresh_token", loginData.refresh_token);
|
|
2517
|
+
cfg.set("login_expires_at", expiresAt);
|
|
2518
|
+
await clearTokensFromKeychain({ debugLog });
|
|
2519
|
+
}
|
|
2520
|
+
cachedLogin = {
|
|
2521
|
+
jwt: loginData.access_token,
|
|
2522
|
+
refreshToken: loginData.refresh_token,
|
|
2523
|
+
expiresAt,
|
|
2524
|
+
storage
|
|
2525
|
+
};
|
|
2526
|
+
}
|
|
2527
|
+
function decodeJwtOrThrow(token) {
|
|
2528
|
+
if (typeof token !== "string") {
|
|
2529
|
+
throw new Error("Expected JWT to be a string");
|
|
2530
|
+
}
|
|
2531
|
+
const decodedJwt = jwt.decode(token, { complete: true });
|
|
2532
|
+
if (!decodedJwt) {
|
|
2533
|
+
throw new Error("Could not decode JWT");
|
|
2534
|
+
}
|
|
2535
|
+
if (typeof decodedJwt.payload === "string") {
|
|
2536
|
+
throw new Error("Did not expect JWT payload to be a string");
|
|
2537
|
+
}
|
|
2538
|
+
return decodedJwt;
|
|
2539
|
+
}
|
|
2540
|
+
async function refreshJwt(refreshToken, options = {}) {
|
|
2541
|
+
const {
|
|
2542
|
+
onEvent,
|
|
2543
|
+
fetch: fetch2 = globalThis.fetch,
|
|
2544
|
+
credentials: credentials2,
|
|
2545
|
+
debug = false
|
|
2546
|
+
} = options;
|
|
2547
|
+
const debugLog = createDebugLog(debug);
|
|
2548
|
+
const tokenUrl = getAuthTokenUrl({ baseUrl: credentials2?.baseUrl });
|
|
2549
|
+
const clientId = getAuthClientId(credentials2?.clientId);
|
|
2550
|
+
const startTime = Date.now();
|
|
2551
|
+
try {
|
|
2552
|
+
onEvent?.({
|
|
2553
|
+
type: "auth_refreshing",
|
|
2554
|
+
payload: {
|
|
2555
|
+
message: "Refreshing your token...",
|
|
2556
|
+
operation: "token_refresh"
|
|
2557
|
+
},
|
|
2558
|
+
timestamp: Date.now()
|
|
2559
|
+
});
|
|
2560
|
+
debugLog(`\u2192 POST ${tokenUrl}`, {
|
|
2561
|
+
headers: {
|
|
2562
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
2563
|
+
[AUTH_MODE_HEADER]: "no"
|
|
2564
|
+
},
|
|
2565
|
+
body: {
|
|
2566
|
+
client_id: clientId,
|
|
2567
|
+
refresh_token: censorHeaderValue(refreshToken),
|
|
2568
|
+
grant_type: "refresh_token"
|
|
2569
|
+
}
|
|
2570
|
+
});
|
|
2571
|
+
const response = await fetch2(tokenUrl, {
|
|
2572
|
+
method: "POST",
|
|
2573
|
+
headers: {
|
|
2574
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
2575
|
+
[AUTH_MODE_HEADER]: "no"
|
|
2576
|
+
},
|
|
2577
|
+
body: new URLSearchParams({
|
|
2578
|
+
client_id: clientId,
|
|
2579
|
+
refresh_token: refreshToken,
|
|
2580
|
+
grant_type: "refresh_token"
|
|
2581
|
+
})
|
|
2582
|
+
});
|
|
2583
|
+
const duration = Date.now() - startTime;
|
|
2584
|
+
if (!response.ok) {
|
|
2585
|
+
debugLog(`\u2190 ${response.status} ${response.statusText} (${duration}ms)`);
|
|
2586
|
+
throw new Error(
|
|
2587
|
+
`Token refresh failed: ${response.status} ${response.statusText}`
|
|
2588
|
+
);
|
|
2589
|
+
}
|
|
2590
|
+
debugLog(`\u2190 ${response.status} ${response.statusText} (${duration}ms)`);
|
|
2591
|
+
const data = await response.json();
|
|
2592
|
+
await updateLogin(data, { debug });
|
|
2593
|
+
debugLog(
|
|
2594
|
+
`Token refreshed and saved to ${cachedLogin?.storage ?? "keychain"}`
|
|
2595
|
+
);
|
|
2596
|
+
onEvent?.({
|
|
2597
|
+
type: "auth_success",
|
|
2598
|
+
payload: {
|
|
2599
|
+
message: "Token refreshed successfully",
|
|
2600
|
+
operation: "token_refresh"
|
|
2601
|
+
},
|
|
2602
|
+
timestamp: Date.now()
|
|
2603
|
+
});
|
|
2604
|
+
return data.access_token;
|
|
2605
|
+
} catch (error) {
|
|
2606
|
+
const duration = Date.now() - startTime;
|
|
2607
|
+
debugLog(`\u2716 Token refresh failed (${duration}ms)`, {
|
|
2608
|
+
error: error instanceof Error ? error.message : error
|
|
2609
|
+
});
|
|
2610
|
+
cachedLogin = void 0;
|
|
2611
|
+
const errorMessage = `Token refresh failed: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
2612
|
+
onEvent?.({
|
|
2613
|
+
type: "auth_error",
|
|
2614
|
+
payload: {
|
|
2615
|
+
message: errorMessage,
|
|
2616
|
+
error: errorMessage,
|
|
2617
|
+
operation: "token_refresh"
|
|
2618
|
+
},
|
|
2619
|
+
timestamp: Date.now()
|
|
2620
|
+
});
|
|
2621
|
+
throw error;
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
var pendingRefresh = null;
|
|
2625
|
+
var pendingResolve = null;
|
|
2626
|
+
async function resolveStoredLogin(debugLog) {
|
|
2627
|
+
if (cachedLogin) {
|
|
2628
|
+
debugLog("Using in-memory cached credentials");
|
|
2629
|
+
return cachedLogin;
|
|
2630
|
+
}
|
|
2631
|
+
if (pendingResolve) {
|
|
2632
|
+
debugLog("Waiting for existing keychain read to complete");
|
|
2633
|
+
return pendingResolve;
|
|
2634
|
+
}
|
|
2635
|
+
pendingResolve = resolveStoredLoginFromStorage(debugLog).finally(() => {
|
|
2636
|
+
pendingResolve = null;
|
|
2637
|
+
});
|
|
2638
|
+
return pendingResolve;
|
|
2639
|
+
}
|
|
2640
|
+
async function resolveStoredLoginFromStorage(debugLog) {
|
|
2641
|
+
let cfg;
|
|
2642
|
+
try {
|
|
2643
|
+
cfg = getConfig();
|
|
2644
|
+
} catch (error) {
|
|
2645
|
+
debugLog("Failed to load config", {
|
|
2646
|
+
error: error instanceof Error ? error.message : error
|
|
2647
|
+
});
|
|
2648
|
+
return void 0;
|
|
2649
|
+
}
|
|
2650
|
+
const expiresAt = cfg.get("login_expires_at");
|
|
2651
|
+
const configJwt = cfg.get("login_jwt");
|
|
2652
|
+
const configRefresh = cfg.get("login_refresh_token");
|
|
2653
|
+
if (configJwt && configRefresh && typeof expiresAt === "number") {
|
|
2654
|
+
debugLog("Loaded credentials from config (legacy format)");
|
|
2655
|
+
cachedLogin = {
|
|
2656
|
+
jwt: configJwt,
|
|
2657
|
+
refreshToken: configRefresh,
|
|
2658
|
+
expiresAt,
|
|
2659
|
+
storage: "config"
|
|
2660
|
+
};
|
|
2661
|
+
return cachedLogin;
|
|
2662
|
+
}
|
|
2663
|
+
if (typeof expiresAt !== "number") {
|
|
2664
|
+
debugLog("No stored login credentials found");
|
|
2665
|
+
return void 0;
|
|
2666
|
+
}
|
|
2667
|
+
const keychainData = await getTokensFromKeychain({ debugLog });
|
|
2668
|
+
if (!keychainData) {
|
|
2669
|
+
debugLog("No tokens found in keychain");
|
|
2670
|
+
return void 0;
|
|
2671
|
+
}
|
|
2672
|
+
debugLog("Loaded credentials from keychain");
|
|
2673
|
+
cachedLogin = {
|
|
2674
|
+
jwt: keychainData.login_jwt,
|
|
2675
|
+
refreshToken: keychainData.login_refresh_token,
|
|
2676
|
+
expiresAt,
|
|
2677
|
+
storage: "keychain"
|
|
2678
|
+
};
|
|
2679
|
+
return cachedLogin;
|
|
2680
|
+
}
|
|
2681
|
+
async function resolveOrRefreshToken(options = {}) {
|
|
2682
|
+
const { debug = false } = options;
|
|
2683
|
+
const debugLog = createDebugLog(debug);
|
|
2684
|
+
const stored = await resolveStoredLogin(debugLog);
|
|
2685
|
+
if (!stored) {
|
|
2686
|
+
return void 0;
|
|
2687
|
+
}
|
|
2688
|
+
const { jwt: storedJwt, refreshToken, expiresAt } = stored;
|
|
2689
|
+
if (expiresAt > Date.now() + TOKEN_REFRESH_BUFFER_MS) {
|
|
2690
|
+
debugLog("Using cached token (still valid)");
|
|
2691
|
+
return storedJwt;
|
|
2692
|
+
}
|
|
2693
|
+
debugLog("Token expired, refreshing...");
|
|
2694
|
+
if (pendingRefresh) {
|
|
2695
|
+
debugLog("Waiting for existing refresh to complete");
|
|
2696
|
+
return pendingRefresh;
|
|
2697
|
+
}
|
|
2698
|
+
pendingRefresh = refreshJwt(refreshToken, options).finally(() => {
|
|
2699
|
+
pendingRefresh = null;
|
|
2700
|
+
});
|
|
2701
|
+
return await pendingRefresh;
|
|
2702
|
+
}
|
|
2703
|
+
async function getToken(options = {}) {
|
|
2704
|
+
try {
|
|
2705
|
+
return await resolveOrRefreshToken(options);
|
|
2706
|
+
} catch (error) {
|
|
2707
|
+
const message = error instanceof Error ? error.message : "Token refresh failed";
|
|
2708
|
+
throw new ZapierAuthenticationError(
|
|
2709
|
+
`${message}
|
|
2710
|
+
Please run 'login' to authenticate again.`
|
|
2711
|
+
);
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
async function getLoggedInUser(options = {}) {
|
|
2715
|
+
const jwt2 = await getToken(options).catch(() => void 0);
|
|
2716
|
+
if (!jwt2) {
|
|
2717
|
+
throw new Error(
|
|
2718
|
+
"No valid authentication token available. Please login first."
|
|
2719
|
+
);
|
|
2720
|
+
}
|
|
2721
|
+
let decodedJwt = decodeJwtOrThrow(jwt2);
|
|
2722
|
+
if (decodedJwt.payload["sub_type"] == "service") {
|
|
2723
|
+
decodedJwt = decodeJwtOrThrow(decodedJwt.payload["njwt"]);
|
|
2724
|
+
}
|
|
2725
|
+
if (typeof decodedJwt.payload["zap:acc"] !== "string") {
|
|
2726
|
+
throw new Error("JWT payload does not contain accountId");
|
|
2727
|
+
}
|
|
2728
|
+
const accountId = parseInt(decodedJwt.payload["zap:acc"], 10);
|
|
2729
|
+
if (isNaN(accountId)) {
|
|
2730
|
+
throw new Error("JWT accountId is not a number");
|
|
2731
|
+
}
|
|
2732
|
+
if (decodedJwt.payload["sub_type"] !== "customuser" || typeof decodedJwt.payload["sub"] !== "string") {
|
|
2733
|
+
throw new Error("JWT payload does not contain customUserId");
|
|
2734
|
+
}
|
|
2735
|
+
const customUserId = parseInt(decodedJwt.payload["sub"], 10);
|
|
2736
|
+
if (isNaN(customUserId)) {
|
|
2737
|
+
throw new Error("JWT customUserId is not a number");
|
|
2738
|
+
}
|
|
2739
|
+
const email = decodedJwt.payload["zap:uname"];
|
|
2740
|
+
if (typeof email !== "string") {
|
|
2741
|
+
throw new Error("JWT payload does not contain email");
|
|
2742
|
+
}
|
|
2743
|
+
return {
|
|
2744
|
+
accountId,
|
|
2745
|
+
customUserId,
|
|
2746
|
+
email
|
|
2747
|
+
};
|
|
2748
|
+
}
|
|
2749
|
+
function getLoginStorageMode() {
|
|
2750
|
+
const cfg = getConfig();
|
|
2751
|
+
if (typeof cfg.get("login_jwt") === "string") {
|
|
2752
|
+
return "config";
|
|
2753
|
+
}
|
|
2754
|
+
const explicitMode = cfg.get("login_storage_mode");
|
|
2755
|
+
if (explicitMode === "keychain" || explicitMode === "config") {
|
|
2756
|
+
return explicitMode;
|
|
2757
|
+
}
|
|
2758
|
+
return "keychain";
|
|
2759
|
+
}
|
|
2760
|
+
async function logout(options = {}) {
|
|
2761
|
+
const { onEvent } = options;
|
|
2762
|
+
const mode = getLoginStorageMode();
|
|
2763
|
+
cachedLogin = void 0;
|
|
2764
|
+
await clearTokensFromKeychain();
|
|
2765
|
+
const cfg = getConfig();
|
|
2766
|
+
cfg.set("login_storage_mode", mode);
|
|
2767
|
+
cfg.delete("login_expires_at");
|
|
2768
|
+
cfg.delete("login_jwt");
|
|
2769
|
+
cfg.delete("login_refresh_token");
|
|
2770
|
+
onEvent?.({
|
|
2771
|
+
type: "auth_logout",
|
|
2772
|
+
payload: { message: "Logged out successfully", operation: "logout" },
|
|
2773
|
+
timestamp: Date.now()
|
|
2774
|
+
});
|
|
2775
|
+
}
|
|
2776
|
+
function getConfigPath() {
|
|
2777
|
+
const cfg = getConfig();
|
|
2778
|
+
return cfg.path;
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
// src/utils/constants.ts
|
|
2200
2782
|
var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
2201
2783
|
var LOGIN_TIMEOUT_MS = 3e5;
|
|
2202
2784
|
var spinPromise = async (promise, text) => {
|
|
@@ -2475,85 +3057,65 @@ function toPkceCredentials(credentials2) {
|
|
|
2475
3057
|
}
|
|
2476
3058
|
return void 0;
|
|
2477
3059
|
}
|
|
2478
|
-
var loginPlugin = (
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
credentials: pkceCredentials
|
|
2489
|
-
});
|
|
2490
|
-
const user = await getLoggedInUser();
|
|
2491
|
-
sdk2.context.eventEmission.emit(
|
|
2492
|
-
"platform.sdk.ApplicationLifecycleEvent",
|
|
2493
|
-
buildApplicationLifecycleEvent(
|
|
2494
|
-
{ lifecycle_event_type: "login_success" },
|
|
2495
|
-
{ customuser_id: user.customUserId, account_id: user.accountId }
|
|
2496
|
-
)
|
|
2497
|
-
);
|
|
2498
|
-
console.log(`\u2705 Successfully logged in as ${user.email}`);
|
|
2499
|
-
};
|
|
2500
|
-
return {
|
|
2501
|
-
login: loginFn,
|
|
2502
|
-
context: {
|
|
2503
|
-
meta: {
|
|
2504
|
-
login: {
|
|
2505
|
-
categories: ["account"],
|
|
2506
|
-
inputSchema: LoginSchema,
|
|
2507
|
-
supportsJsonOutput: false
|
|
2508
|
-
}
|
|
3060
|
+
var loginPlugin = definePlugin(
|
|
3061
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
3062
|
+
name: "login",
|
|
3063
|
+
categories: ["account"],
|
|
3064
|
+
inputSchema: LoginSchema,
|
|
3065
|
+
supportsJsonOutput: false,
|
|
3066
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3067
|
+
const timeoutSeconds = options.timeout ? parseInt(options.timeout, 10) : 300;
|
|
3068
|
+
if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
3069
|
+
throw new Error("Timeout must be a positive number");
|
|
2509
3070
|
}
|
|
3071
|
+
const resolvedCredentials = await sdk3.context.resolveCredentials();
|
|
3072
|
+
const pkceCredentials = toPkceCredentials(resolvedCredentials);
|
|
3073
|
+
await login_default({
|
|
3074
|
+
timeoutMs: timeoutSeconds * 1e3,
|
|
3075
|
+
credentials: pkceCredentials
|
|
3076
|
+
});
|
|
3077
|
+
const user = await getLoggedInUser();
|
|
3078
|
+
sdk3.context.eventEmission.emit(
|
|
3079
|
+
"platform.sdk.ApplicationLifecycleEvent",
|
|
3080
|
+
buildApplicationLifecycleEvent(
|
|
3081
|
+
{ lifecycle_event_type: "login_success" },
|
|
3082
|
+
{ customuser_id: user.customUserId, account_id: user.accountId }
|
|
3083
|
+
)
|
|
3084
|
+
);
|
|
3085
|
+
console.log(`\u2705 Successfully logged in as ${user.email}`);
|
|
2510
3086
|
}
|
|
2511
|
-
}
|
|
2512
|
-
|
|
3087
|
+
})
|
|
3088
|
+
);
|
|
2513
3089
|
var LogoutSchema = z.object({}).describe("Log out of your Zapier account");
|
|
2514
3090
|
|
|
2515
3091
|
// src/plugins/logout/index.ts
|
|
2516
|
-
var
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
categories: ["account"],
|
|
2526
|
-
inputSchema: LogoutSchema,
|
|
2527
|
-
supportsJsonOutput: false
|
|
2528
|
-
}
|
|
3092
|
+
var logoutPlugin = definePlugin(
|
|
3093
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
3094
|
+
name: "logout",
|
|
3095
|
+
categories: ["account"],
|
|
3096
|
+
inputSchema: LogoutSchema,
|
|
3097
|
+
supportsJsonOutput: false,
|
|
3098
|
+
handler: async () => {
|
|
3099
|
+
await logout();
|
|
3100
|
+
console.log("\u2705 Successfully logged out");
|
|
2529
3101
|
}
|
|
2530
|
-
}
|
|
2531
|
-
|
|
3102
|
+
})
|
|
3103
|
+
);
|
|
2532
3104
|
var McpSchema = z.object({
|
|
2533
3105
|
port: z.string().optional().describe("Port to listen on (for future HTTP transport)")
|
|
2534
3106
|
}).describe("Start MCP server for Zapier SDK");
|
|
2535
3107
|
|
|
2536
3108
|
// src/plugins/mcp/index.ts
|
|
2537
|
-
var mcpPlugin = (
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
}
|
|
2543
|
-
|
|
2544
|
-
}, McpSchema);
|
|
2545
|
-
return {
|
|
2546
|
-
mcp: mcpWithSdk,
|
|
2547
|
-
context: {
|
|
2548
|
-
meta: {
|
|
2549
|
-
mcp: {
|
|
2550
|
-
categories: ["utility"],
|
|
2551
|
-
inputSchema: McpSchema
|
|
2552
|
-
}
|
|
2553
|
-
}
|
|
3109
|
+
var mcpPlugin = definePlugin(
|
|
3110
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
3111
|
+
name: "mcp",
|
|
3112
|
+
categories: ["utility"],
|
|
3113
|
+
inputSchema: McpSchema,
|
|
3114
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3115
|
+
await startMcpServer({ ...options, debug: sdk3.context.options?.debug });
|
|
2554
3116
|
}
|
|
2555
|
-
}
|
|
2556
|
-
|
|
3117
|
+
})
|
|
3118
|
+
);
|
|
2557
3119
|
var BundleCodeSchema = z.object({
|
|
2558
3120
|
input: z.string().min(1).describe("Input TypeScript file path to bundle"),
|
|
2559
3121
|
output: OutputPropertySchema.optional().describe(
|
|
@@ -2564,22 +3126,14 @@ var BundleCodeSchema = z.object({
|
|
|
2564
3126
|
target: z.string().optional().describe("ECMAScript target version"),
|
|
2565
3127
|
cjs: z.boolean().optional().describe("Output CommonJS format instead of ESM")
|
|
2566
3128
|
}).describe("Bundle TypeScript code into executable JavaScript");
|
|
2567
|
-
var bundleCodePlugin = (
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
bundleCode: {
|
|
2576
|
-
categories: ["utility", "deprecated"],
|
|
2577
|
-
inputSchema: BundleCodeSchema
|
|
2578
|
-
}
|
|
2579
|
-
}
|
|
2580
|
-
}
|
|
2581
|
-
};
|
|
2582
|
-
};
|
|
3129
|
+
var bundleCodePlugin = definePlugin(
|
|
3130
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
3131
|
+
name: "bundleCode",
|
|
3132
|
+
categories: ["utility", "deprecated"],
|
|
3133
|
+
inputSchema: BundleCodeSchema,
|
|
3134
|
+
handler: async ({ options }) => bundleCode(options)
|
|
3135
|
+
})
|
|
3136
|
+
);
|
|
2583
3137
|
var ZapierBundleError = class extends Error {
|
|
2584
3138
|
constructor(message, details, originalError) {
|
|
2585
3139
|
super(message);
|
|
@@ -2646,25 +3200,14 @@ async function bundleCode(options) {
|
|
|
2646
3200
|
}
|
|
2647
3201
|
}
|
|
2648
3202
|
var GetLoginConfigPathSchema = z.object({}).describe("Show the path to the login configuration file");
|
|
2649
|
-
var getLoginConfigPathPlugin = (
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
)
|
|
2656
|
-
|
|
2657
|
-
getLoginConfigPath: getLoginConfigPathWithSdk,
|
|
2658
|
-
context: {
|
|
2659
|
-
meta: {
|
|
2660
|
-
getLoginConfigPath: {
|
|
2661
|
-
categories: ["utility"],
|
|
2662
|
-
inputSchema: GetLoginConfigPathSchema
|
|
2663
|
-
}
|
|
2664
|
-
}
|
|
2665
|
-
}
|
|
2666
|
-
};
|
|
2667
|
-
};
|
|
3203
|
+
var getLoginConfigPathPlugin = definePlugin(
|
|
3204
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
3205
|
+
name: "getLoginConfigPath",
|
|
3206
|
+
categories: ["utility"],
|
|
3207
|
+
inputSchema: GetLoginConfigPathSchema,
|
|
3208
|
+
handler: async () => getConfigPath()
|
|
3209
|
+
})
|
|
3210
|
+
);
|
|
2668
3211
|
var AddSchema = z.object({
|
|
2669
3212
|
apps: z.array(z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required").describe(
|
|
2670
3213
|
"One or more app keys to add (e.g., 'slack', 'github', 'trello')"
|
|
@@ -2692,111 +3235,105 @@ async function detectTypesOutputDirectory() {
|
|
|
2692
3235
|
}
|
|
2693
3236
|
return "./zapier/apps/";
|
|
2694
3237
|
}
|
|
2695
|
-
var addPlugin = (
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
case "connections_lookup_start":
|
|
2739
|
-
console.log(`\u{1F510} Looking up ${event.count} connection(s)...`);
|
|
2740
|
-
break;
|
|
2741
|
-
case "connections_lookup_complete":
|
|
2742
|
-
console.log(`\u{1F510} Found ${event.count} connection(s)`);
|
|
2743
|
-
break;
|
|
2744
|
-
case "connection_matched":
|
|
2745
|
-
const appWithConnection = appSlugAndKeyMap.get(event.app) || event.app;
|
|
2746
|
-
console.log(
|
|
2747
|
-
`\u{1F510} Using connection ${event.connectionId} (${event.connectionTitle}) for ${appWithConnection}`
|
|
2748
|
-
);
|
|
2749
|
-
break;
|
|
2750
|
-
case "connection_not_matched":
|
|
2751
|
-
const appWithoutConnection = appSlugAndKeyMap.get(event.app) || event.app;
|
|
2752
|
-
console.warn(
|
|
2753
|
-
`\u26A0\uFE0F No matching connection found for ${appWithoutConnection}`
|
|
2754
|
-
);
|
|
2755
|
-
break;
|
|
2756
|
-
case "file_written":
|
|
2757
|
-
console.log(
|
|
2758
|
-
`\u{1F527} Generated types for ${event.manifestKey} at ${event.filePath}`
|
|
2759
|
-
);
|
|
2760
|
-
break;
|
|
2761
|
-
case "app_processing_error":
|
|
2762
|
-
const errorApp = appSlugAndKeyMap.get(event.app) || event.app;
|
|
2763
|
-
console.warn(`\u26A0\uFE0F ${event.error} for ${errorApp}`);
|
|
2764
|
-
break;
|
|
2765
|
-
}
|
|
2766
|
-
};
|
|
2767
|
-
const manifestResult = await sdk2.buildManifest({
|
|
2768
|
-
apps: appKeys,
|
|
2769
|
-
skipWrite: false,
|
|
2770
|
-
configPath,
|
|
2771
|
-
onProgress: handleManifestProgress
|
|
2772
|
-
});
|
|
2773
|
-
const typesResult = await sdk2.generateAppTypes({
|
|
2774
|
-
apps: appKeys,
|
|
2775
|
-
connections: connectionIds,
|
|
2776
|
-
skipWrite: false,
|
|
2777
|
-
typesOutputDirectory: resolvedTypesOutput,
|
|
2778
|
-
onProgress: handleTypesProgress
|
|
2779
|
-
});
|
|
2780
|
-
const results = manifestResult.manifest?.apps || {};
|
|
2781
|
-
const successfulApps = Object.keys(results).filter(
|
|
2782
|
-
(manifestKey) => typesResult.writtenFiles?.[manifestKey]
|
|
2783
|
-
);
|
|
2784
|
-
if (successfulApps.length > 0) {
|
|
2785
|
-
console.log(`\u2705 Added ${successfulApps.length} app(s) to manifest`);
|
|
2786
|
-
}
|
|
2787
|
-
}, AddSchema);
|
|
2788
|
-
return {
|
|
2789
|
-
add,
|
|
2790
|
-
context: {
|
|
2791
|
-
meta: {
|
|
2792
|
-
add: {
|
|
2793
|
-
categories: ["utility"],
|
|
2794
|
-
inputSchema: AddSchema
|
|
3238
|
+
var addPlugin = definePlugin(
|
|
3239
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
3240
|
+
name: "add",
|
|
3241
|
+
categories: ["utility"],
|
|
3242
|
+
inputSchema: AddSchema,
|
|
3243
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3244
|
+
const {
|
|
3245
|
+
apps: appKeys,
|
|
3246
|
+
connections: connectionIds,
|
|
3247
|
+
configPath,
|
|
3248
|
+
typesOutput = await detectTypesOutputDirectory()
|
|
3249
|
+
} = options;
|
|
3250
|
+
const resolvedTypesOutput = resolve(typesOutput);
|
|
3251
|
+
console.log(`\u{1F4E6} Adding ${appKeys.length} app(s)...`);
|
|
3252
|
+
const appSlugAndKeyMap = /* @__PURE__ */ new Map();
|
|
3253
|
+
const handleManifestProgress = (event) => {
|
|
3254
|
+
switch (event.type) {
|
|
3255
|
+
case "apps_lookup_start":
|
|
3256
|
+
console.log(`\u{1F4E6} Looking up ${event.count} app(s)...`);
|
|
3257
|
+
break;
|
|
3258
|
+
case "app_found":
|
|
3259
|
+
const displayName = event.app.slug ? `${event.app.slug} (${event.app.key})` : event.app.key;
|
|
3260
|
+
appSlugAndKeyMap.set(event.app.key, displayName);
|
|
3261
|
+
break;
|
|
3262
|
+
case "apps_lookup_complete":
|
|
3263
|
+
if (event.count === 0) {
|
|
3264
|
+
console.warn("\u26A0\uFE0F No apps found");
|
|
3265
|
+
}
|
|
3266
|
+
break;
|
|
3267
|
+
case "app_processing_start":
|
|
3268
|
+
const appName = event.slug ? `${event.slug} (${event.app})` : event.app;
|
|
3269
|
+
console.log(`\u{1F4E6} Adding ${appName}...`);
|
|
3270
|
+
break;
|
|
3271
|
+
case "manifest_updated":
|
|
3272
|
+
const appDisplay = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3273
|
+
console.log(
|
|
3274
|
+
`\u{1F4DD} Locked ${appDisplay} to ${event.app}@${event.version} using key '${event.manifestKey}'`
|
|
3275
|
+
);
|
|
3276
|
+
break;
|
|
3277
|
+
case "app_processing_error":
|
|
3278
|
+
const errorApp = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3279
|
+
console.warn(`\u26A0\uFE0F ${event.error} for ${errorApp}`);
|
|
3280
|
+
break;
|
|
2795
3281
|
}
|
|
3282
|
+
};
|
|
3283
|
+
const handleTypesProgress = (event) => {
|
|
3284
|
+
switch (event.type) {
|
|
3285
|
+
case "connections_lookup_start":
|
|
3286
|
+
console.log(`\u{1F510} Looking up ${event.count} connection(s)...`);
|
|
3287
|
+
break;
|
|
3288
|
+
case "connections_lookup_complete":
|
|
3289
|
+
console.log(`\u{1F510} Found ${event.count} connection(s)`);
|
|
3290
|
+
break;
|
|
3291
|
+
case "connection_matched":
|
|
3292
|
+
const appWithConnection = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3293
|
+
console.log(
|
|
3294
|
+
`\u{1F510} Using connection ${event.connectionId} (${event.connectionTitle}) for ${appWithConnection}`
|
|
3295
|
+
);
|
|
3296
|
+
break;
|
|
3297
|
+
case "connection_not_matched":
|
|
3298
|
+
const appWithoutConnection = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3299
|
+
console.warn(
|
|
3300
|
+
`\u26A0\uFE0F No matching connection found for ${appWithoutConnection}`
|
|
3301
|
+
);
|
|
3302
|
+
break;
|
|
3303
|
+
case "file_written":
|
|
3304
|
+
console.log(
|
|
3305
|
+
`\u{1F527} Generated types for ${event.manifestKey} at ${event.filePath}`
|
|
3306
|
+
);
|
|
3307
|
+
break;
|
|
3308
|
+
case "app_processing_error":
|
|
3309
|
+
const errorApp = appSlugAndKeyMap.get(event.app) || event.app;
|
|
3310
|
+
console.warn(`\u26A0\uFE0F ${event.error} for ${errorApp}`);
|
|
3311
|
+
break;
|
|
3312
|
+
}
|
|
3313
|
+
};
|
|
3314
|
+
const manifestResult = await sdk3.buildManifest({
|
|
3315
|
+
apps: appKeys,
|
|
3316
|
+
skipWrite: false,
|
|
3317
|
+
configPath,
|
|
3318
|
+
onProgress: handleManifestProgress
|
|
3319
|
+
});
|
|
3320
|
+
const typesResult = await sdk3.generateAppTypes({
|
|
3321
|
+
apps: appKeys,
|
|
3322
|
+
connections: connectionIds,
|
|
3323
|
+
skipWrite: false,
|
|
3324
|
+
typesOutputDirectory: resolvedTypesOutput,
|
|
3325
|
+
onProgress: handleTypesProgress
|
|
3326
|
+
});
|
|
3327
|
+
const results = manifestResult.manifest?.apps || {};
|
|
3328
|
+
const successfulApps = Object.keys(results).filter(
|
|
3329
|
+
(manifestKey) => typesResult.writtenFiles?.[manifestKey]
|
|
3330
|
+
);
|
|
3331
|
+
if (successfulApps.length > 0) {
|
|
3332
|
+
console.log(`\u2705 Added ${successfulApps.length} app(s) to manifest`);
|
|
2796
3333
|
}
|
|
2797
3334
|
}
|
|
2798
|
-
}
|
|
2799
|
-
|
|
3335
|
+
})
|
|
3336
|
+
);
|
|
2800
3337
|
var GenerateAppTypesSchema = z.object({
|
|
2801
3338
|
apps: z.array(z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required").describe(
|
|
2802
3339
|
"One or more app keys to generate types for (e.g., 'slack', 'github', 'trello')"
|
|
@@ -3403,150 +3940,133 @@ function createManifestEntry(app) {
|
|
|
3403
3940
|
version: app.version
|
|
3404
3941
|
};
|
|
3405
3942
|
}
|
|
3406
|
-
var generateAppTypesPlugin = (
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
}
|
|
3430
|
-
const connections = [];
|
|
3431
|
-
if (connectionIds && connectionIds.length > 0) {
|
|
3432
|
-
onProgress?.({
|
|
3433
|
-
type: "connections_lookup_start",
|
|
3434
|
-
count: connectionIds.length
|
|
3435
|
-
});
|
|
3436
|
-
const connectionsIterable = sdk2.listConnections({ connections: connectionIds }).items();
|
|
3437
|
-
for await (const connection of connectionsIterable) {
|
|
3438
|
-
connections.push(connection);
|
|
3943
|
+
var generateAppTypesPlugin = definePlugin(
|
|
3944
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
3945
|
+
name: "generateAppTypes",
|
|
3946
|
+
categories: ["utility"],
|
|
3947
|
+
// Cast: schema validates JSON fields only; GenerateAppTypesOptions adds
|
|
3948
|
+
// the runtime-only `onProgress` callback (passthrough via createFunction).
|
|
3949
|
+
inputSchema: GenerateAppTypesSchema,
|
|
3950
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
3951
|
+
const {
|
|
3952
|
+
apps: appKeys,
|
|
3953
|
+
connections: connectionIds,
|
|
3954
|
+
skipWrite = false,
|
|
3955
|
+
typesOutputDirectory = await detectTypesOutputDirectory(),
|
|
3956
|
+
onProgress
|
|
3957
|
+
} = options;
|
|
3958
|
+
const resolvedTypesOutput = resolve(typesOutputDirectory);
|
|
3959
|
+
const result = { typeDefinitions: {} };
|
|
3960
|
+
onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
|
|
3961
|
+
const appsIterable = sdk3.listApps({ apps: appKeys }).items();
|
|
3962
|
+
const apps = [];
|
|
3963
|
+
for await (const app of appsIterable) {
|
|
3964
|
+
apps.push(app);
|
|
3965
|
+
onProgress?.({ type: "app_found", app });
|
|
3439
3966
|
}
|
|
3440
|
-
onProgress?.({
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
}
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
type: "app_processing_start",
|
|
3454
|
-
app: app.key,
|
|
3455
|
-
slug: app.slug
|
|
3456
|
-
});
|
|
3457
|
-
try {
|
|
3458
|
-
if (!app.version) {
|
|
3459
|
-
const errorMessage = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
|
|
3460
|
-
onProgress?.({
|
|
3461
|
-
type: "app_processing_error",
|
|
3462
|
-
app: app.key,
|
|
3463
|
-
error: errorMessage
|
|
3464
|
-
});
|
|
3465
|
-
throw new ZapierValidationError(errorMessage, {
|
|
3466
|
-
details: {
|
|
3467
|
-
appKey: app.key,
|
|
3468
|
-
implementationId: app.implementation_id
|
|
3469
|
-
}
|
|
3470
|
-
});
|
|
3967
|
+
onProgress?.({ type: "apps_lookup_complete", count: apps.length });
|
|
3968
|
+
if (apps.length === 0) {
|
|
3969
|
+
return result;
|
|
3970
|
+
}
|
|
3971
|
+
const connections = [];
|
|
3972
|
+
if (connectionIds && connectionIds.length > 0) {
|
|
3973
|
+
onProgress?.({
|
|
3974
|
+
type: "connections_lookup_start",
|
|
3975
|
+
count: connectionIds.length
|
|
3976
|
+
});
|
|
3977
|
+
const connectionsIterable = sdk3.listConnections({ connections: connectionIds }).items();
|
|
3978
|
+
for await (const connection of connectionsIterable) {
|
|
3979
|
+
connections.push(connection);
|
|
3471
3980
|
}
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3981
|
+
onProgress?.({
|
|
3982
|
+
type: "connections_lookup_complete",
|
|
3983
|
+
count: connections.length
|
|
3984
|
+
});
|
|
3985
|
+
}
|
|
3986
|
+
if (!skipWrite && resolvedTypesOutput) {
|
|
3987
|
+
await mkdir(resolvedTypesOutput, { recursive: true });
|
|
3988
|
+
}
|
|
3989
|
+
if (!skipWrite) {
|
|
3990
|
+
result.writtenFiles = {};
|
|
3991
|
+
}
|
|
3992
|
+
for (const app of apps) {
|
|
3993
|
+
onProgress?.({
|
|
3994
|
+
type: "app_processing_start",
|
|
3995
|
+
app: app.key,
|
|
3996
|
+
slug: app.slug
|
|
3997
|
+
});
|
|
3998
|
+
try {
|
|
3999
|
+
if (!app.version) {
|
|
4000
|
+
const errorMessage = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
|
|
3479
4001
|
onProgress?.({
|
|
3480
|
-
type: "
|
|
4002
|
+
type: "app_processing_error",
|
|
3481
4003
|
app: app.key,
|
|
3482
|
-
|
|
3483
|
-
connectionTitle: matchingConnection.title || ""
|
|
4004
|
+
error: errorMessage
|
|
3484
4005
|
});
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
4006
|
+
throw new ZapierValidationError(errorMessage, {
|
|
4007
|
+
details: {
|
|
4008
|
+
appKey: app.key,
|
|
4009
|
+
implementationId: app.implementation_id
|
|
4010
|
+
}
|
|
3489
4011
|
});
|
|
3490
4012
|
}
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
4013
|
+
let connectionId;
|
|
4014
|
+
if (connections.length > 0) {
|
|
4015
|
+
const matchingConnection = connections.find(
|
|
4016
|
+
(conn) => conn.app_key === app.key
|
|
4017
|
+
);
|
|
4018
|
+
if (matchingConnection) {
|
|
4019
|
+
connectionId = matchingConnection.id;
|
|
4020
|
+
onProgress?.({
|
|
4021
|
+
type: "connection_matched",
|
|
4022
|
+
app: app.key,
|
|
4023
|
+
connectionId: matchingConnection.id,
|
|
4024
|
+
connectionTitle: matchingConnection.title || ""
|
|
4025
|
+
});
|
|
4026
|
+
} else {
|
|
4027
|
+
onProgress?.({
|
|
4028
|
+
type: "connection_not_matched",
|
|
4029
|
+
app: app.key
|
|
4030
|
+
});
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
const manifestKey = getManifestKey(app);
|
|
4034
|
+
const generator = new AstTypeGenerator();
|
|
4035
|
+
const typeDefinitionString = await generator.generateTypes({
|
|
4036
|
+
app,
|
|
4037
|
+
connectionId,
|
|
4038
|
+
sdk: sdk3
|
|
4039
|
+
});
|
|
4040
|
+
result.typeDefinitions[manifestKey] = typeDefinitionString;
|
|
3509
4041
|
onProgress?.({
|
|
3510
|
-
type: "
|
|
4042
|
+
type: "type_generated",
|
|
3511
4043
|
manifestKey,
|
|
3512
|
-
|
|
4044
|
+
sizeBytes: typeDefinitionString.length
|
|
3513
4045
|
});
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
throw error;
|
|
3528
|
-
} else {
|
|
3529
|
-
throw new ZapierUnknownError(errorMessage, {
|
|
3530
|
-
cause: error
|
|
3531
|
-
// Works for both Error and non-Error
|
|
4046
|
+
if (!skipWrite && resolvedTypesOutput && result.writtenFiles) {
|
|
4047
|
+
const filePath = join(resolvedTypesOutput, `${manifestKey}.d.ts`);
|
|
4048
|
+
await writeFile(filePath, typeDefinitionString, "utf8");
|
|
4049
|
+
result.writtenFiles[manifestKey] = filePath;
|
|
4050
|
+
onProgress?.({ type: "file_written", manifestKey, filePath });
|
|
4051
|
+
}
|
|
4052
|
+
onProgress?.({ type: "app_processing_complete", app: app.key });
|
|
4053
|
+
} catch (error) {
|
|
4054
|
+
const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4055
|
+
onProgress?.({
|
|
4056
|
+
type: "app_processing_error",
|
|
4057
|
+
app: app.key,
|
|
4058
|
+
error: errorMessage
|
|
3532
4059
|
});
|
|
4060
|
+
if (error instanceof ZapierValidationError) {
|
|
4061
|
+
throw error;
|
|
4062
|
+
}
|
|
4063
|
+
throw new ZapierUnknownError(errorMessage, { cause: error });
|
|
3533
4064
|
}
|
|
3534
4065
|
}
|
|
4066
|
+
return result;
|
|
3535
4067
|
}
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
return {
|
|
3539
|
-
generateAppTypes,
|
|
3540
|
-
context: {
|
|
3541
|
-
meta: {
|
|
3542
|
-
generateAppTypes: {
|
|
3543
|
-
categories: ["utility"],
|
|
3544
|
-
inputSchema: GenerateAppTypesSchema
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
}
|
|
3548
|
-
};
|
|
3549
|
-
};
|
|
4068
|
+
})
|
|
4069
|
+
);
|
|
3550
4070
|
var BuildManifestSchema = z.object({
|
|
3551
4071
|
apps: z.array(z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required").describe(
|
|
3552
4072
|
"One or more app keys to build manifest entries for (e.g., 'slack', 'github', 'trello')"
|
|
@@ -3562,86 +4082,80 @@ var BuildManifestSchema = z.object({
|
|
|
3562
4082
|
);
|
|
3563
4083
|
|
|
3564
4084
|
// src/plugins/buildManifest/index.ts
|
|
3565
|
-
var buildManifestPlugin = (
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
type: "manifest_entry_built",
|
|
3595
|
-
app: app.key,
|
|
3596
|
-
manifestKey: manifestEntry.implementationName,
|
|
3597
|
-
version: manifestEntry.version || ""
|
|
3598
|
-
});
|
|
3599
|
-
const { key: updatedManifestKey, manifest } = await sdk2.context.updateManifestEntry({
|
|
3600
|
-
appKey: app.key,
|
|
3601
|
-
entry: manifestEntry,
|
|
3602
|
-
configPath,
|
|
3603
|
-
skipWrite,
|
|
3604
|
-
manifest: updatedManifest
|
|
3605
|
-
});
|
|
3606
|
-
updatedManifest = manifest;
|
|
3607
|
-
onProgress?.({
|
|
3608
|
-
type: "manifest_updated",
|
|
3609
|
-
app: app.key,
|
|
3610
|
-
manifestKey: updatedManifestKey,
|
|
3611
|
-
version: manifestEntry.version || ""
|
|
3612
|
-
});
|
|
3613
|
-
onProgress?.({ type: "app_processing_complete", app: app.key });
|
|
3614
|
-
} catch (error) {
|
|
3615
|
-
const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4085
|
+
var buildManifestPlugin = definePlugin(
|
|
4086
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
4087
|
+
name: "buildManifest",
|
|
4088
|
+
categories: ["utility"],
|
|
4089
|
+
// Cast: BuildManifestSchema validates JSON-serializable fields only.
|
|
4090
|
+
// BuildManifestOptions adds an `onProgress` callback that rides through
|
|
4091
|
+
// `createFunction`'s passthrough spread at runtime; this widens TInput
|
|
4092
|
+
// so the handler can read it.
|
|
4093
|
+
inputSchema: BuildManifestSchema,
|
|
4094
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
4095
|
+
const {
|
|
4096
|
+
apps: appKeys,
|
|
4097
|
+
skipWrite = false,
|
|
4098
|
+
configPath,
|
|
4099
|
+
onProgress
|
|
4100
|
+
} = options;
|
|
4101
|
+
onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
|
|
4102
|
+
const appsIterable = sdk3.listApps({ apps: appKeys }).items();
|
|
4103
|
+
const apps = [];
|
|
4104
|
+
for await (const app of appsIterable) {
|
|
4105
|
+
apps.push(app);
|
|
4106
|
+
onProgress?.({ type: "app_found", app });
|
|
4107
|
+
}
|
|
4108
|
+
onProgress?.({ type: "apps_lookup_complete", count: apps.length });
|
|
4109
|
+
if (apps.length === 0) {
|
|
4110
|
+
return {};
|
|
4111
|
+
}
|
|
4112
|
+
let updatedManifest;
|
|
4113
|
+
for (const app of apps) {
|
|
3616
4114
|
onProgress?.({
|
|
3617
|
-
type: "
|
|
4115
|
+
type: "app_processing_start",
|
|
3618
4116
|
app: app.key,
|
|
3619
|
-
|
|
4117
|
+
slug: app.slug
|
|
3620
4118
|
});
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
4119
|
+
try {
|
|
4120
|
+
const manifestEntry = createManifestEntry(app);
|
|
4121
|
+
onProgress?.({
|
|
4122
|
+
type: "manifest_entry_built",
|
|
4123
|
+
app: app.key,
|
|
4124
|
+
manifestKey: manifestEntry.implementationName,
|
|
4125
|
+
version: manifestEntry.version || ""
|
|
3627
4126
|
});
|
|
4127
|
+
const { key: updatedManifestKey, manifest } = await sdk3.context.updateManifestEntry({
|
|
4128
|
+
appKey: app.key,
|
|
4129
|
+
entry: manifestEntry,
|
|
4130
|
+
configPath,
|
|
4131
|
+
skipWrite,
|
|
4132
|
+
manifest: updatedManifest
|
|
4133
|
+
});
|
|
4134
|
+
updatedManifest = manifest;
|
|
4135
|
+
onProgress?.({
|
|
4136
|
+
type: "manifest_updated",
|
|
4137
|
+
app: app.key,
|
|
4138
|
+
manifestKey: updatedManifestKey,
|
|
4139
|
+
version: manifestEntry.version || ""
|
|
4140
|
+
});
|
|
4141
|
+
onProgress?.({ type: "app_processing_complete", app: app.key });
|
|
4142
|
+
} catch (error) {
|
|
4143
|
+
const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
|
|
4144
|
+
onProgress?.({
|
|
4145
|
+
type: "app_processing_error",
|
|
4146
|
+
app: app.key,
|
|
4147
|
+
error: errorMessage
|
|
4148
|
+
});
|
|
4149
|
+
if (error instanceof ZapierValidationError) {
|
|
4150
|
+
throw error;
|
|
4151
|
+
}
|
|
4152
|
+
throw new ZapierUnknownError(errorMessage, { cause: error });
|
|
3628
4153
|
}
|
|
3629
4154
|
}
|
|
4155
|
+
return { manifest: updatedManifest };
|
|
3630
4156
|
}
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
return {
|
|
3634
|
-
buildManifest,
|
|
3635
|
-
context: {
|
|
3636
|
-
meta: {
|
|
3637
|
-
buildManifest: {
|
|
3638
|
-
categories: ["utility"],
|
|
3639
|
-
inputSchema: BuildManifestSchema
|
|
3640
|
-
}
|
|
3641
|
-
}
|
|
3642
|
-
}
|
|
3643
|
-
};
|
|
3644
|
-
};
|
|
4157
|
+
})
|
|
4158
|
+
);
|
|
3645
4159
|
var FeedbackSchema = z.object({
|
|
3646
4160
|
feedback: z.string().describe(
|
|
3647
4161
|
"Your feedback on the Zapier SDK. Describe what worked well, what was frustrating, or any suggestions."
|
|
@@ -3675,37 +4189,31 @@ async function postWithRetry({
|
|
|
3675
4189
|
}
|
|
3676
4190
|
return response;
|
|
3677
4191
|
}
|
|
3678
|
-
var feedbackPlugin = (
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
feedback: {
|
|
3699
|
-
categories: ["utility"],
|
|
3700
|
-
inputSchema: FeedbackSchema,
|
|
3701
|
-
resolvers: {
|
|
3702
|
-
feedback: feedbackResolver
|
|
3703
|
-
}
|
|
3704
|
-
}
|
|
4192
|
+
var feedbackPlugin = definePlugin(
|
|
4193
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
4194
|
+
name: "feedback",
|
|
4195
|
+
categories: ["utility"],
|
|
4196
|
+
inputSchema: FeedbackSchema,
|
|
4197
|
+
resolvers: { feedback: feedbackResolver },
|
|
4198
|
+
handler: async ({ sdk: sdk3, options }) => {
|
|
4199
|
+
const user = await getLoggedInUser();
|
|
4200
|
+
const body = JSON.stringify({
|
|
4201
|
+
email: user.email,
|
|
4202
|
+
customuser_id: user.customUserId,
|
|
4203
|
+
feedback: options.feedback
|
|
4204
|
+
});
|
|
4205
|
+
const response = await postWithRetry({
|
|
4206
|
+
body,
|
|
4207
|
+
attemptsLeft: MAX_RETRIES
|
|
4208
|
+
});
|
|
4209
|
+
if (sdk3.context.options?.debug) {
|
|
4210
|
+
const text = await response.text();
|
|
4211
|
+
console.error("[debug] Webhook response:", text);
|
|
3705
4212
|
}
|
|
4213
|
+
return "Thank you for your feedback!";
|
|
3706
4214
|
}
|
|
3707
|
-
}
|
|
3708
|
-
|
|
4215
|
+
})
|
|
4216
|
+
);
|
|
3709
4217
|
var CurlSchema = z.object({
|
|
3710
4218
|
url: z.string().describe("Request URL"),
|
|
3711
4219
|
request: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method (defaults to GET, or POST if data is provided)"),
|
|
@@ -3881,7 +4389,7 @@ async function buildFormData(formArgs, formStringArgs) {
|
|
|
3881
4389
|
}
|
|
3882
4390
|
|
|
3883
4391
|
// src/plugins/curl/index.ts
|
|
3884
|
-
var curlPlugin = (sdk2) => {
|
|
4392
|
+
var curlPlugin = definePlugin((sdk2) => {
|
|
3885
4393
|
async function curl(options) {
|
|
3886
4394
|
const {
|
|
3887
4395
|
url: rawUrl,
|
|
@@ -4124,30 +4632,25 @@ ${Array.from(
|
|
|
4124
4632
|
}
|
|
4125
4633
|
}
|
|
4126
4634
|
};
|
|
4127
|
-
};
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
...sdk2.context.meta.fetch.categories || [],
|
|
4141
|
-
"deprecated"
|
|
4142
|
-
],
|
|
4143
|
-
deprecation: {
|
|
4144
|
-
message: "This command is deprecated and will be removed soon. Use `curl` instead. Learn more: https://docs.zapier.com/sdk/cli-reference#curl"
|
|
4145
|
-
}
|
|
4635
|
+
});
|
|
4636
|
+
var cliOverridesPlugin = definePlugin(
|
|
4637
|
+
(sdk2) => {
|
|
4638
|
+
const meta = {};
|
|
4639
|
+
if (sdk2.context.meta.fetch) {
|
|
4640
|
+
meta.fetch = {
|
|
4641
|
+
...sdk2.context.meta.fetch,
|
|
4642
|
+
categories: [
|
|
4643
|
+
...sdk2.context.meta.fetch.categories || [],
|
|
4644
|
+
"deprecated"
|
|
4645
|
+
],
|
|
4646
|
+
deprecation: {
|
|
4647
|
+
message: "This command is deprecated and will be removed soon. Use `curl` instead. Learn more: https://docs.zapier.com/sdk/cli-reference#curl"
|
|
4146
4648
|
}
|
|
4147
|
-
}
|
|
4649
|
+
};
|
|
4148
4650
|
}
|
|
4149
|
-
|
|
4150
|
-
}
|
|
4651
|
+
return { context: { meta } };
|
|
4652
|
+
}
|
|
4653
|
+
);
|
|
4151
4654
|
var TEMPLATES = ["basic"];
|
|
4152
4655
|
var InitSchema = z.object({
|
|
4153
4656
|
projectName: z.string().min(1).describe("Name of the project directory to create"),
|
|
@@ -4586,74 +5089,68 @@ function displaySummaryAndNextSteps({
|
|
|
4586
5089
|
}
|
|
4587
5090
|
|
|
4588
5091
|
// src/plugins/init/index.ts
|
|
4589
|
-
var initPlugin = (
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
);
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
packageManager,
|
|
4606
|
-
displayHooks
|
|
4607
|
-
});
|
|
4608
|
-
const completedSetupStepIds = [];
|
|
4609
|
-
for (let i = 0; i < steps.length; i++) {
|
|
4610
|
-
const step = steps[i];
|
|
4611
|
-
const succeeded = await withInterruptCleanup(
|
|
4612
|
-
step.cleanup,
|
|
4613
|
-
() => runStep({
|
|
4614
|
-
step,
|
|
4615
|
-
stepNumber: i + 1,
|
|
4616
|
-
totalSteps: steps.length,
|
|
4617
|
-
skipPrompts,
|
|
4618
|
-
displayHooks
|
|
4619
|
-
})
|
|
4620
|
-
);
|
|
4621
|
-
if (!succeeded) break;
|
|
4622
|
-
completedSetupStepIds.push(step.id);
|
|
4623
|
-
}
|
|
4624
|
-
if (completedSetupStepIds.length === 0) {
|
|
4625
|
-
throw new ZapierCliExitError(
|
|
4626
|
-
"Project setup failed \u2014 no steps completed."
|
|
4627
|
-
);
|
|
4628
|
-
}
|
|
4629
|
-
displaySummaryAndNextSteps({
|
|
4630
|
-
projectName,
|
|
4631
|
-
steps,
|
|
4632
|
-
completedSetupStepIds,
|
|
4633
|
-
packageManager
|
|
4634
|
-
});
|
|
4635
|
-
}, InitSchema);
|
|
4636
|
-
return {
|
|
4637
|
-
init,
|
|
4638
|
-
context: {
|
|
4639
|
-
meta: {
|
|
4640
|
-
init: {
|
|
4641
|
-
categories: ["utility"],
|
|
4642
|
-
inputSchema: InitSchema,
|
|
4643
|
-
supportsJsonOutput: false
|
|
4644
|
-
}
|
|
5092
|
+
var initPlugin = definePlugin(
|
|
5093
|
+
(sdk2) => createPluginMethod(sdk2, {
|
|
5094
|
+
name: "init",
|
|
5095
|
+
categories: ["utility"],
|
|
5096
|
+
inputSchema: InitSchema,
|
|
5097
|
+
supportsJsonOutput: false,
|
|
5098
|
+
handler: async ({ options }) => {
|
|
5099
|
+
const { projectName: rawName, skipPrompts = false } = options;
|
|
5100
|
+
const cwd = process.cwd();
|
|
5101
|
+
const { projectName, projectDir } = validateInitOptions({ rawName, cwd });
|
|
5102
|
+
const displayHooks = createConsoleDisplayHooks();
|
|
5103
|
+
const packageManagerInfo = detectPackageManager(cwd);
|
|
5104
|
+
if (packageManagerInfo.name === "unknown") {
|
|
5105
|
+
displayHooks.onWarn(
|
|
5106
|
+
"Could not detect package manager, defaulting to npm."
|
|
5107
|
+
);
|
|
4645
5108
|
}
|
|
5109
|
+
const packageManager = packageManagerInfo.name === "unknown" ? "npm" : packageManagerInfo.name;
|
|
5110
|
+
const steps = getInitSteps({
|
|
5111
|
+
projectDir,
|
|
5112
|
+
projectName,
|
|
5113
|
+
packageManager,
|
|
5114
|
+
displayHooks
|
|
5115
|
+
});
|
|
5116
|
+
const completedSetupStepIds = [];
|
|
5117
|
+
for (let i = 0; i < steps.length; i++) {
|
|
5118
|
+
const step = steps[i];
|
|
5119
|
+
const succeeded = await withInterruptCleanup(
|
|
5120
|
+
step.cleanup,
|
|
5121
|
+
() => runStep({
|
|
5122
|
+
step,
|
|
5123
|
+
stepNumber: i + 1,
|
|
5124
|
+
totalSteps: steps.length,
|
|
5125
|
+
skipPrompts,
|
|
5126
|
+
displayHooks
|
|
5127
|
+
})
|
|
5128
|
+
);
|
|
5129
|
+
if (!succeeded) break;
|
|
5130
|
+
completedSetupStepIds.push(step.id);
|
|
5131
|
+
}
|
|
5132
|
+
if (completedSetupStepIds.length === 0) {
|
|
5133
|
+
throw new ZapierCliExitError(
|
|
5134
|
+
"Project setup failed \u2014 no steps completed."
|
|
5135
|
+
);
|
|
5136
|
+
}
|
|
5137
|
+
displaySummaryAndNextSteps({
|
|
5138
|
+
projectName,
|
|
5139
|
+
steps,
|
|
5140
|
+
completedSetupStepIds,
|
|
5141
|
+
packageManager
|
|
5142
|
+
});
|
|
4646
5143
|
}
|
|
4647
|
-
}
|
|
4648
|
-
|
|
5144
|
+
})
|
|
5145
|
+
);
|
|
4649
5146
|
|
|
4650
5147
|
// package.json with { type: 'json' }
|
|
4651
5148
|
var package_default2 = {
|
|
4652
5149
|
name: "@zapier/zapier-sdk-cli",
|
|
4653
|
-
version: "0.
|
|
5150
|
+
version: "0.43.1"};
|
|
4654
5151
|
|
|
4655
5152
|
// src/sdk.ts
|
|
4656
|
-
injectCliLogin(
|
|
5153
|
+
injectCliLogin(login_exports);
|
|
4657
5154
|
function createZapierCliSdk(options = {}) {
|
|
4658
5155
|
return createZapierSdk({
|
|
4659
5156
|
...options,
|