@zapier/zapier-sdk-cli 0.67.6 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +33 -15
- package/dist/cli.cjs +1598 -328
- package/dist/cli.mjs +1599 -331
- package/dist/experimental.cjs +1793 -30
- package/dist/experimental.d.mts +1 -1
- package/dist/experimental.d.ts +1 -1
- package/dist/experimental.mjs +1791 -33
- package/dist/{extensions-CU5Oy_Wv.d.mts → extensions-DSCQgX9d.d.mts} +177 -2
- package/dist/{extensions-CU5Oy_Wv.d.ts → extensions-DSCQgX9d.d.ts} +177 -2
- package/dist/index.cjs +1794 -33
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1790 -34
- package/package.json +6 -4
- package/templates/setup/zapier-slack-test.mjs +38 -0
- package/templates/setup/zapier-slack-test.ts +38 -0
package/dist/cli.cjs
CHANGED
|
@@ -8,14 +8,15 @@ var inquirer = require('inquirer');
|
|
|
8
8
|
var chalk8 = require('chalk');
|
|
9
9
|
var core = require('@inquirer/core');
|
|
10
10
|
var ora = require('ora');
|
|
11
|
+
var fs = require('fs');
|
|
12
|
+
var path = require('path');
|
|
13
|
+
var isInstalledGlobally = require('is-installed-globally');
|
|
11
14
|
var util = require('util');
|
|
12
|
-
var
|
|
15
|
+
var wrapAnsi4 = require('wrap-ansi');
|
|
13
16
|
var jwt = require('jsonwebtoken');
|
|
14
17
|
var crossKeychain = require('cross-keychain');
|
|
15
18
|
var Conf = require('conf');
|
|
16
|
-
var fs = require('fs');
|
|
17
19
|
var crypto = require('crypto');
|
|
18
|
-
var path = require('path');
|
|
19
20
|
var lockfile = require('proper-lockfile');
|
|
20
21
|
var os = require('os');
|
|
21
22
|
var express = require('express');
|
|
@@ -26,13 +27,14 @@ var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
|
|
|
26
27
|
var esbuild = require('esbuild');
|
|
27
28
|
var promises = require('fs/promises');
|
|
28
29
|
var ts = require('typescript');
|
|
29
|
-
var isInstalledGlobally = require('is-installed-globally');
|
|
30
30
|
var child_process = require('child_process');
|
|
31
31
|
var Handlebars = require('handlebars');
|
|
32
32
|
var url = require('url');
|
|
33
|
-
var experimental = require('@zapier/zapier-sdk/experimental');
|
|
34
33
|
var packageJsonLib = require('package-json');
|
|
35
34
|
var semver = require('semver');
|
|
35
|
+
var crossSpawn = require('cross-spawn');
|
|
36
|
+
var Table = require('cli-table3');
|
|
37
|
+
var experimental = require('@zapier/zapier-sdk/experimental');
|
|
36
38
|
var readline = require('readline');
|
|
37
39
|
|
|
38
40
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -59,22 +61,24 @@ function _interopNamespace(e) {
|
|
|
59
61
|
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
60
62
|
var chalk8__default = /*#__PURE__*/_interopDefault(chalk8);
|
|
61
63
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
64
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
65
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
66
|
+
var isInstalledGlobally__default = /*#__PURE__*/_interopDefault(isInstalledGlobally);
|
|
62
67
|
var util__default = /*#__PURE__*/_interopDefault(util);
|
|
63
|
-
var
|
|
68
|
+
var wrapAnsi4__default = /*#__PURE__*/_interopDefault(wrapAnsi4);
|
|
64
69
|
var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
|
|
65
70
|
var Conf__default = /*#__PURE__*/_interopDefault(Conf);
|
|
66
|
-
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
67
71
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
68
|
-
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
69
72
|
var lockfile__namespace = /*#__PURE__*/_interopNamespace(lockfile);
|
|
70
73
|
var express__default = /*#__PURE__*/_interopDefault(express);
|
|
71
74
|
var open__default = /*#__PURE__*/_interopDefault(open);
|
|
72
75
|
var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
|
|
73
76
|
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
74
|
-
var isInstalledGlobally__default = /*#__PURE__*/_interopDefault(isInstalledGlobally);
|
|
75
77
|
var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
|
|
76
78
|
var packageJsonLib__default = /*#__PURE__*/_interopDefault(packageJsonLib);
|
|
77
79
|
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
80
|
+
var crossSpawn__default = /*#__PURE__*/_interopDefault(crossSpawn);
|
|
81
|
+
var Table__default = /*#__PURE__*/_interopDefault(Table);
|
|
78
82
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
79
83
|
|
|
80
84
|
var __defProp = Object.defineProperty;
|
|
@@ -236,11 +240,21 @@ async function promptText({
|
|
|
236
240
|
password
|
|
237
241
|
}) {
|
|
238
242
|
const { value } = await inquirer__default.default.prompt([
|
|
239
|
-
{
|
|
243
|
+
{
|
|
244
|
+
type: password ? "password" : "input",
|
|
245
|
+
name: "value",
|
|
246
|
+
message,
|
|
247
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
248
|
+
}
|
|
240
249
|
]);
|
|
241
250
|
return value;
|
|
242
251
|
}
|
|
243
252
|
var display = (c) => c.hint ? `${c.label} ${chalk8__default.default.dim(`(${c.hint})`)}` : c.label;
|
|
253
|
+
var HIGH_CONTRAST_PROMPT_THEME = {
|
|
254
|
+
style: {
|
|
255
|
+
answer: (text) => chalk8__default.default.inverse.bold(` ${text} `)
|
|
256
|
+
}
|
|
257
|
+
};
|
|
244
258
|
function buildSelectRows(question, term) {
|
|
245
259
|
const row = (name, action) => ({
|
|
246
260
|
name,
|
|
@@ -307,9 +321,39 @@ function foldPage(acc, question, field) {
|
|
|
307
321
|
checked: []
|
|
308
322
|
};
|
|
309
323
|
}
|
|
310
|
-
async function answerSelect(question, field, box, failed
|
|
324
|
+
async function answerSelect(question, field, box, failed, mode) {
|
|
311
325
|
const acc = failed ? void 0 : box.acc = foldPage(box.acc, question, field);
|
|
312
326
|
const view = acc ? { ...question, choices: acc.choices } : question;
|
|
327
|
+
const isClosedListPrompt = mode === "closed-list" && !failed && !view.multiple;
|
|
328
|
+
const booleanValues = view.choices.map(({ value: value2 }) => value2);
|
|
329
|
+
if (isClosedListPrompt && booleanValues.length === 2 && booleanValues.includes("true") && booleanValues.includes("false")) {
|
|
330
|
+
const { value: value2 } = await inquirer__default.default.prompt([
|
|
331
|
+
{
|
|
332
|
+
type: "confirm",
|
|
333
|
+
name: "value",
|
|
334
|
+
message: view.message,
|
|
335
|
+
default: booleanValues[0] === "true",
|
|
336
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
337
|
+
}
|
|
338
|
+
]);
|
|
339
|
+
return { type: "choose", value: String(value2) };
|
|
340
|
+
}
|
|
341
|
+
if (isClosedListPrompt && view.choices.length > 0 && !offers(view, "search") && !offers(view, "next_page") && !offers(view, "retry")) {
|
|
342
|
+
const choices = view.choices.map((choice) => ({
|
|
343
|
+
name: display(choice),
|
|
344
|
+
value: choice.value
|
|
345
|
+
}));
|
|
346
|
+
const { value: value2 } = await inquirer__default.default.prompt([
|
|
347
|
+
{
|
|
348
|
+
type: "list",
|
|
349
|
+
name: "value",
|
|
350
|
+
message: view.message,
|
|
351
|
+
choices,
|
|
352
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
353
|
+
}
|
|
354
|
+
]);
|
|
355
|
+
return { type: "choose", value: value2 };
|
|
356
|
+
}
|
|
313
357
|
if (question.multiple && acc) {
|
|
314
358
|
if (acc.newStart > 0 && process.stdout.isTTY) {
|
|
315
359
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
@@ -333,7 +377,13 @@ async function answerSelect(question, field, box, failed = false) {
|
|
|
333
377
|
}))
|
|
334
378
|
];
|
|
335
379
|
const { values } = await inquirer__default.default.prompt([
|
|
336
|
-
{
|
|
380
|
+
{
|
|
381
|
+
type: "checkbox",
|
|
382
|
+
name: "values",
|
|
383
|
+
message: question.message,
|
|
384
|
+
choices,
|
|
385
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
386
|
+
}
|
|
337
387
|
]);
|
|
338
388
|
const selected = values;
|
|
339
389
|
const picked = selected.filter((v) => !isActionRow(v));
|
|
@@ -428,7 +478,8 @@ async function answerCollection(question) {
|
|
|
428
478
|
type: "confirm",
|
|
429
479
|
name: "again",
|
|
430
480
|
message: question.message,
|
|
431
|
-
default: false
|
|
481
|
+
default: false,
|
|
482
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
432
483
|
}
|
|
433
484
|
]);
|
|
434
485
|
return again ? { type: "add" } : { type: "done" };
|
|
@@ -443,22 +494,37 @@ function withEngineSpinner(answer, spinner) {
|
|
|
443
494
|
}
|
|
444
495
|
};
|
|
445
496
|
}
|
|
446
|
-
function createCliAnswer(
|
|
497
|
+
function createCliAnswer({
|
|
498
|
+
mode = "search"
|
|
499
|
+
} = {}) {
|
|
447
500
|
const box = {};
|
|
448
|
-
return ({ result }) => {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
501
|
+
return async ({ result }) => {
|
|
502
|
+
try {
|
|
503
|
+
if (result.error !== void 0) {
|
|
504
|
+
const message = typeof result.error === "string" ? result.error : result.error.message;
|
|
505
|
+
console.log(chalk8__default.default.yellow(`! ${message}`));
|
|
506
|
+
}
|
|
507
|
+
const question = result.question;
|
|
508
|
+
const field = question.path.length ? question.path.join(".") : "value";
|
|
509
|
+
switch (question.type) {
|
|
510
|
+
case "select":
|
|
511
|
+
return await answerSelect(
|
|
512
|
+
question,
|
|
513
|
+
field,
|
|
514
|
+
box,
|
|
515
|
+
result.status === "failed",
|
|
516
|
+
mode
|
|
517
|
+
);
|
|
518
|
+
case "input":
|
|
519
|
+
return await answerInput(question);
|
|
520
|
+
case "collection":
|
|
521
|
+
return await answerCollection(question);
|
|
522
|
+
}
|
|
523
|
+
} catch (error) {
|
|
524
|
+
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
525
|
+
return { type: "cancel" };
|
|
526
|
+
}
|
|
527
|
+
throw error;
|
|
462
528
|
}
|
|
463
529
|
};
|
|
464
530
|
}
|
|
@@ -536,7 +602,86 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
536
602
|
|
|
537
603
|
// package.json
|
|
538
604
|
var package_default = {
|
|
539
|
-
version: "0.
|
|
605
|
+
version: "0.69.0"};
|
|
606
|
+
var PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
|
|
607
|
+
var LOCKFILES = [
|
|
608
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
609
|
+
["yarn.lock", "yarn"],
|
|
610
|
+
["bun.lock", "bun"],
|
|
611
|
+
["bun.lockb", "bun"],
|
|
612
|
+
["package-lock.json", "npm"]
|
|
613
|
+
];
|
|
614
|
+
function readDeclaredPackageManager(cwd) {
|
|
615
|
+
try {
|
|
616
|
+
const manifest = JSON.parse(
|
|
617
|
+
fs.readFileSync(path.join(cwd, "package.json"), "utf8")
|
|
618
|
+
);
|
|
619
|
+
if (typeof manifest !== "object" || manifest === null || !("packageManager" in manifest) || typeof manifest.packageManager !== "string") {
|
|
620
|
+
return void 0;
|
|
621
|
+
}
|
|
622
|
+
const [name] = manifest.packageManager.split("@", 1);
|
|
623
|
+
return PACKAGE_MANAGERS.find((packageManager) => packageManager === name);
|
|
624
|
+
} catch {
|
|
625
|
+
return void 0;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
function detectPackageManager(cwd = process.cwd()) {
|
|
629
|
+
const lockfileManagers = new Set(
|
|
630
|
+
LOCKFILES.filter(([file]) => fs.existsSync(path.join(cwd, file))).map(
|
|
631
|
+
([, packageManager]) => packageManager
|
|
632
|
+
)
|
|
633
|
+
);
|
|
634
|
+
if (lockfileManagers.size === 1) {
|
|
635
|
+
return { name: [...lockfileManagers][0], source: "lockfile" };
|
|
636
|
+
}
|
|
637
|
+
const declaredPackageManager = readDeclaredPackageManager(cwd);
|
|
638
|
+
if (declaredPackageManager) {
|
|
639
|
+
return { name: declaredPackageManager, source: "package-json" };
|
|
640
|
+
}
|
|
641
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
642
|
+
if (userAgent) {
|
|
643
|
+
if (userAgent.includes("yarn")) {
|
|
644
|
+
return { name: "yarn", source: "runtime" };
|
|
645
|
+
}
|
|
646
|
+
if (userAgent.includes("pnpm")) {
|
|
647
|
+
return { name: "pnpm", source: "runtime" };
|
|
648
|
+
}
|
|
649
|
+
if (userAgent.includes("bun")) {
|
|
650
|
+
return { name: "bun", source: "runtime" };
|
|
651
|
+
}
|
|
652
|
+
if (userAgent.includes("npm")) {
|
|
653
|
+
return { name: "npm", source: "runtime" };
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return { name: "npm", source: "fallback" };
|
|
657
|
+
}
|
|
658
|
+
function getUpdateCommand(packageName) {
|
|
659
|
+
const pm = detectPackageManager();
|
|
660
|
+
const isGlobal = isInstalledGlobally__default.default;
|
|
661
|
+
if (isGlobal) {
|
|
662
|
+
switch (pm.name) {
|
|
663
|
+
case "yarn":
|
|
664
|
+
return `yarn global upgrade ${packageName}@latest`;
|
|
665
|
+
case "pnpm":
|
|
666
|
+
return `pnpm update -g ${packageName}@latest`;
|
|
667
|
+
case "bun":
|
|
668
|
+
return `bun update -g ${packageName}@latest`;
|
|
669
|
+
default:
|
|
670
|
+
return `npm install -g ${packageName}@latest`;
|
|
671
|
+
}
|
|
672
|
+
} else {
|
|
673
|
+
switch (pm.name) {
|
|
674
|
+
case "yarn":
|
|
675
|
+
return `yarn upgrade ${packageName}@latest`;
|
|
676
|
+
case "pnpm":
|
|
677
|
+
return `pnpm update ${packageName}@latest`;
|
|
678
|
+
case "bun":
|
|
679
|
+
return `bun update ${packageName}@latest`;
|
|
680
|
+
default:
|
|
681
|
+
return `npm install ${packageName}@latest`;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
540
685
|
|
|
541
686
|
// src/telemetry/builders.ts
|
|
542
687
|
function createCliBaseEvent(context = {}) {
|
|
@@ -584,8 +729,7 @@ function buildCliCommandExecutedEvent({
|
|
|
584
729
|
ci_platform: zapierSdk.getCiPlatform(),
|
|
585
730
|
...zapierSdk.getTtyContext(),
|
|
586
731
|
agent: zapierSdk.getAgent(),
|
|
587
|
-
package_manager: data.package_manager ??
|
|
588
|
-
// Default based on project setup
|
|
732
|
+
package_manager: data.package_manager ?? detectPackageManager(process.cwd()).name,
|
|
589
733
|
made_network_requests: data.made_network_requests ?? null,
|
|
590
734
|
files_modified_count: data.files_modified_count ?? null,
|
|
591
735
|
files_created_count: data.files_created_count ?? null,
|
|
@@ -679,7 +823,7 @@ var DETAIL_INDENT = " ";
|
|
|
679
823
|
var DETAIL_MAX_LINES = 5;
|
|
680
824
|
function formatDetailText(text, indent = DETAIL_INDENT) {
|
|
681
825
|
const columns = Math.max((process.stdout.columns || 80) - indent.length, 40);
|
|
682
|
-
const wrapped =
|
|
826
|
+
const wrapped = wrapAnsi4__default.default(text, columns, { hard: true, trim: false });
|
|
683
827
|
const lines = wrapped.split("\n");
|
|
684
828
|
if (lines.length <= DETAIL_MAX_LINES) {
|
|
685
829
|
return lines.join("\n" + indent);
|
|
@@ -740,11 +884,13 @@ function buildJsonErrors(error) {
|
|
|
740
884
|
const code = zapierSdk.isZapierError(error) ? error.code : "UNKNOWN_ERROR";
|
|
741
885
|
const message = error instanceof Error ? error.message : String(error);
|
|
742
886
|
const reason = getApprovalReason(error);
|
|
887
|
+
const meta = zapierSdk.isZapierConflictError(error) ? error.meta : void 0;
|
|
743
888
|
return [
|
|
744
889
|
{
|
|
745
890
|
code,
|
|
746
891
|
message,
|
|
747
|
-
...reason ? { reason } : {}
|
|
892
|
+
...reason ? { reason } : {},
|
|
893
|
+
...meta ? { meta } : {}
|
|
748
894
|
}
|
|
749
895
|
];
|
|
750
896
|
}
|
|
@@ -5755,54 +5901,6 @@ var InitSchema = zod.z.object({
|
|
|
5755
5901
|
}).describe(
|
|
5756
5902
|
"Create a new Zapier SDK project in a new directory with starter files"
|
|
5757
5903
|
);
|
|
5758
|
-
function detectPackageManager(cwd = process.cwd()) {
|
|
5759
|
-
const ua = process.env.npm_config_user_agent;
|
|
5760
|
-
if (ua) {
|
|
5761
|
-
if (ua.includes("yarn")) return { name: "yarn", source: "runtime" };
|
|
5762
|
-
if (ua.includes("pnpm")) return { name: "pnpm", source: "runtime" };
|
|
5763
|
-
if (ua.includes("bun")) return { name: "bun", source: "runtime" };
|
|
5764
|
-
if (ua.includes("npm")) return { name: "npm", source: "runtime" };
|
|
5765
|
-
}
|
|
5766
|
-
const files = [
|
|
5767
|
-
["pnpm-lock.yaml", "pnpm"],
|
|
5768
|
-
["yarn.lock", "yarn"],
|
|
5769
|
-
["bun.lockb", "bun"],
|
|
5770
|
-
["package-lock.json", "npm"]
|
|
5771
|
-
];
|
|
5772
|
-
for (const [file, name] of files) {
|
|
5773
|
-
if (fs.existsSync(path.join(cwd, file))) {
|
|
5774
|
-
return { name, source: "lockfile" };
|
|
5775
|
-
}
|
|
5776
|
-
}
|
|
5777
|
-
return { name: "unknown", source: "fallback" };
|
|
5778
|
-
}
|
|
5779
|
-
function getUpdateCommand(packageName) {
|
|
5780
|
-
const pm = detectPackageManager();
|
|
5781
|
-
const isGlobal = isInstalledGlobally__default.default;
|
|
5782
|
-
if (isGlobal) {
|
|
5783
|
-
switch (pm.name) {
|
|
5784
|
-
case "yarn":
|
|
5785
|
-
return `yarn global upgrade ${packageName}@latest`;
|
|
5786
|
-
case "pnpm":
|
|
5787
|
-
return `pnpm update -g ${packageName}@latest`;
|
|
5788
|
-
case "bun":
|
|
5789
|
-
return `bun update -g ${packageName}@latest`;
|
|
5790
|
-
default:
|
|
5791
|
-
return `npm install -g ${packageName}@latest`;
|
|
5792
|
-
}
|
|
5793
|
-
} else {
|
|
5794
|
-
switch (pm.name) {
|
|
5795
|
-
case "yarn":
|
|
5796
|
-
return `yarn upgrade ${packageName}@latest`;
|
|
5797
|
-
case "pnpm":
|
|
5798
|
-
return `pnpm update ${packageName}@latest`;
|
|
5799
|
-
case "bun":
|
|
5800
|
-
return `bun update ${packageName}@latest`;
|
|
5801
|
-
default:
|
|
5802
|
-
return `npm install ${packageName}@latest`;
|
|
5803
|
-
}
|
|
5804
|
-
}
|
|
5805
|
-
}
|
|
5806
5904
|
function getDirentParentPath(entry) {
|
|
5807
5905
|
const e = entry;
|
|
5808
5906
|
const parent = e.parentPath ?? e.path;
|
|
@@ -6199,17 +6297,16 @@ var initPlugin = zapierSdk.defineMethod({
|
|
|
6199
6297
|
const cwd = process.cwd();
|
|
6200
6298
|
const { projectName, projectDir } = validateInitOptions({ rawName, cwd });
|
|
6201
6299
|
const displayHooks = createConsoleDisplayHooks();
|
|
6202
|
-
const
|
|
6203
|
-
if (
|
|
6300
|
+
const packageManager = detectPackageManager(cwd);
|
|
6301
|
+
if (packageManager.source === "fallback") {
|
|
6204
6302
|
displayHooks.onWarn(
|
|
6205
6303
|
"Could not detect package manager, defaulting to npm."
|
|
6206
6304
|
);
|
|
6207
6305
|
}
|
|
6208
|
-
const packageManager = packageManagerInfo.name === "unknown" ? "npm" : packageManagerInfo.name;
|
|
6209
6306
|
const steps = getInitSteps({
|
|
6210
6307
|
projectDir,
|
|
6211
6308
|
projectName,
|
|
6212
|
-
packageManager,
|
|
6309
|
+
packageManager: packageManager.name,
|
|
6213
6310
|
displayHooks
|
|
6214
6311
|
});
|
|
6215
6312
|
const completedSetupStepIds = [];
|
|
@@ -6237,95 +6334,1423 @@ var initPlugin = zapierSdk.defineMethod({
|
|
|
6237
6334
|
projectName,
|
|
6238
6335
|
steps,
|
|
6239
6336
|
completedSetupStepIds,
|
|
6240
|
-
packageManager
|
|
6337
|
+
packageManager: packageManager.name
|
|
6241
6338
|
});
|
|
6242
6339
|
}
|
|
6243
6340
|
});
|
|
6244
|
-
var
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6341
|
+
var ONE_DAY_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
6342
|
+
var CACHE_RESET_INTERVAL_MILLISECONDS = (() => {
|
|
6343
|
+
const {
|
|
6344
|
+
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS,
|
|
6345
|
+
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS
|
|
6346
|
+
} = process.env;
|
|
6347
|
+
let intervalMs;
|
|
6348
|
+
if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS !== void 0) {
|
|
6349
|
+
const seconds = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS);
|
|
6350
|
+
intervalMs = isNaN(seconds) ? NaN : seconds * 1e3;
|
|
6351
|
+
} else if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS !== void 0) {
|
|
6352
|
+
intervalMs = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
|
|
6353
|
+
} else {
|
|
6354
|
+
intervalMs = ONE_DAY_MILLISECONDS;
|
|
6248
6355
|
}
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
return
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
)
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6356
|
+
if (isNaN(intervalMs) || intervalMs < 0) {
|
|
6357
|
+
return -1;
|
|
6358
|
+
}
|
|
6359
|
+
return intervalMs;
|
|
6360
|
+
})();
|
|
6361
|
+
function getVersionCache() {
|
|
6362
|
+
try {
|
|
6363
|
+
const cache = getConfig().get("version_cache");
|
|
6364
|
+
const now = Date.now();
|
|
6365
|
+
if (!cache || !cache.last_reset_timestamp || now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MILLISECONDS) {
|
|
6366
|
+
const newCache = {
|
|
6367
|
+
last_reset_timestamp: now,
|
|
6368
|
+
packages: {}
|
|
6369
|
+
};
|
|
6370
|
+
getConfig().set("version_cache", newCache);
|
|
6371
|
+
return newCache;
|
|
6264
6372
|
}
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
{ name: "Skip (let lease expire)", value: "skip-expire" },
|
|
6280
|
-
{ name: "View payload", value: "view" },
|
|
6281
|
-
{ name: "Quit", value: "quit" }
|
|
6282
|
-
]
|
|
6283
|
-
}
|
|
6284
|
-
]);
|
|
6285
|
-
action = answer.action;
|
|
6286
|
-
} catch (error) {
|
|
6287
|
-
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
6288
|
-
throw new zapierSdk.ZapierAbortDrainSignal("user pressed Ctrl-C");
|
|
6289
|
-
}
|
|
6290
|
-
throw error;
|
|
6291
|
-
}
|
|
6292
|
-
if (action === "view") {
|
|
6293
|
-
console.log(chalk8__default.default.dim(JSON.stringify(message.payload, null, 2)));
|
|
6294
|
-
continue;
|
|
6295
|
-
}
|
|
6296
|
-
if (action === "ack") {
|
|
6297
|
-
return;
|
|
6298
|
-
}
|
|
6299
|
-
if (action === "skip-release") {
|
|
6300
|
-
throw new zapierSdk.ZapierReleaseTriggerMessageSignal("user skipped (release)");
|
|
6301
|
-
}
|
|
6302
|
-
if (action === "skip-expire") {
|
|
6303
|
-
throw new CliSkipLeaseExpireError();
|
|
6304
|
-
}
|
|
6305
|
-
if (action === "quit") {
|
|
6306
|
-
throw new zapierSdk.ZapierAbortDrainSignal("user requested quit");
|
|
6307
|
-
}
|
|
6373
|
+
return cache;
|
|
6374
|
+
} catch (error) {
|
|
6375
|
+
log_default.debug(`Failed to read version cache: ${error}`);
|
|
6376
|
+
return {
|
|
6377
|
+
last_reset_timestamp: Date.now(),
|
|
6378
|
+
packages: {}
|
|
6379
|
+
};
|
|
6380
|
+
}
|
|
6381
|
+
}
|
|
6382
|
+
function setCachedPackageInfo(packageName, version, info) {
|
|
6383
|
+
try {
|
|
6384
|
+
const cache = getVersionCache();
|
|
6385
|
+
if (!cache.packages[packageName]) {
|
|
6386
|
+
cache.packages[packageName] = {};
|
|
6308
6387
|
}
|
|
6309
|
-
|
|
6388
|
+
cache.packages[packageName][version] = info;
|
|
6389
|
+
getConfig().set("version_cache", cache);
|
|
6390
|
+
} catch (error) {
|
|
6391
|
+
log_default.debug(`Failed to cache package info: ${error}`);
|
|
6392
|
+
}
|
|
6310
6393
|
}
|
|
6311
|
-
function
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
});
|
|
6317
|
-
|
|
6394
|
+
function getCachedPackageInfo(packageName, version) {
|
|
6395
|
+
try {
|
|
6396
|
+
const cache = getVersionCache();
|
|
6397
|
+
return cache.packages[packageName]?.[version];
|
|
6398
|
+
} catch (error) {
|
|
6399
|
+
log_default.debug(`Failed to get cached package info: ${error}`);
|
|
6400
|
+
return void 0;
|
|
6401
|
+
}
|
|
6318
6402
|
}
|
|
6319
|
-
function
|
|
6320
|
-
const
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6403
|
+
async function fetchCachedPackageInfo(packageName, version) {
|
|
6404
|
+
const cacheKey = version || "latest";
|
|
6405
|
+
let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
|
|
6406
|
+
if (cachedInfo) {
|
|
6407
|
+
return cachedInfo;
|
|
6408
|
+
}
|
|
6409
|
+
const packageInfo = await packageJsonLib__default.default(packageName, {
|
|
6410
|
+
version,
|
|
6411
|
+
fullMetadata: true
|
|
6412
|
+
});
|
|
6413
|
+
const info = {
|
|
6414
|
+
version: packageInfo.version,
|
|
6415
|
+
deprecated: packageInfo.deprecated,
|
|
6416
|
+
fetched_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6417
|
+
};
|
|
6418
|
+
setCachedPackageInfo(packageName, cacheKey, info);
|
|
6419
|
+
return info;
|
|
6420
|
+
}
|
|
6421
|
+
async function checkForUpdates({
|
|
6422
|
+
packageName,
|
|
6423
|
+
currentVersion
|
|
6424
|
+
}) {
|
|
6425
|
+
try {
|
|
6426
|
+
const latestPackageInfo = await fetchCachedPackageInfo(packageName);
|
|
6427
|
+
const latestVersion = latestPackageInfo.version;
|
|
6428
|
+
const hasUpdate = semver__default.default.gt(latestVersion, currentVersion);
|
|
6429
|
+
let currentPackageInfo;
|
|
6430
|
+
try {
|
|
6431
|
+
currentPackageInfo = await fetchCachedPackageInfo(
|
|
6432
|
+
packageName,
|
|
6433
|
+
currentVersion
|
|
6434
|
+
);
|
|
6435
|
+
} catch (error) {
|
|
6436
|
+
if (!(error instanceof packageJsonLib.VersionNotFoundError)) {
|
|
6437
|
+
log_default.debug(`Failed to check deprecation for current version: ${error}`);
|
|
6438
|
+
}
|
|
6439
|
+
currentPackageInfo = latestPackageInfo;
|
|
6440
|
+
}
|
|
6441
|
+
const isDeprecated = Boolean(currentPackageInfo.deprecated);
|
|
6442
|
+
const deprecationMessage = isDeprecated ? String(currentPackageInfo.deprecated) : void 0;
|
|
6443
|
+
return {
|
|
6444
|
+
hasUpdate,
|
|
6445
|
+
latestVersion,
|
|
6446
|
+
currentVersion,
|
|
6447
|
+
isDeprecated,
|
|
6448
|
+
deprecationMessage
|
|
6449
|
+
};
|
|
6450
|
+
} catch (error) {
|
|
6451
|
+
log_default.debug(`Failed to check for updates: ${error}`);
|
|
6452
|
+
return {
|
|
6453
|
+
hasUpdate: false,
|
|
6454
|
+
currentVersion,
|
|
6455
|
+
isDeprecated: false
|
|
6456
|
+
};
|
|
6457
|
+
}
|
|
6458
|
+
}
|
|
6459
|
+
function displayUpdateNotification(versionInfo, packageName) {
|
|
6460
|
+
if (versionInfo.isDeprecated) {
|
|
6461
|
+
console.error();
|
|
6462
|
+
console.error(
|
|
6463
|
+
chalk8__default.default.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8__default.default.red(
|
|
6464
|
+
` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
|
|
6465
|
+
)
|
|
6466
|
+
);
|
|
6467
|
+
if (versionInfo.deprecationMessage) {
|
|
6468
|
+
console.error(chalk8__default.default.red(` ${versionInfo.deprecationMessage}`));
|
|
6469
|
+
}
|
|
6470
|
+
console.error(chalk8__default.default.red(` Please update to the latest version.`));
|
|
6471
|
+
console.error();
|
|
6472
|
+
}
|
|
6473
|
+
if (versionInfo.hasUpdate) {
|
|
6474
|
+
console.error();
|
|
6475
|
+
console.error(
|
|
6476
|
+
chalk8__default.default.yellow.bold("\u{1F4E6} Update available!") + chalk8__default.default.yellow(
|
|
6477
|
+
` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
|
|
6478
|
+
)
|
|
6479
|
+
);
|
|
6480
|
+
console.error(
|
|
6481
|
+
chalk8__default.default.yellow(
|
|
6482
|
+
` Run ${chalk8__default.default.bold(getUpdateCommand(packageName))} to update.`
|
|
6483
|
+
)
|
|
6484
|
+
);
|
|
6485
|
+
console.error();
|
|
6486
|
+
}
|
|
6487
|
+
}
|
|
6488
|
+
async function checkAndNotifyUpdates({
|
|
6489
|
+
packageName,
|
|
6490
|
+
currentVersion
|
|
6491
|
+
}) {
|
|
6492
|
+
if (CACHE_RESET_INTERVAL_MILLISECONDS < 0) {
|
|
6493
|
+
return;
|
|
6494
|
+
}
|
|
6495
|
+
const versionInfo = await checkForUpdates({ packageName, currentVersion });
|
|
6496
|
+
displayUpdateNotification(versionInfo, packageName);
|
|
6497
|
+
}
|
|
6498
|
+
var BRAILLE_BLANK = "\u2800";
|
|
6499
|
+
var LIGHTNING_INTERVAL_MILLISECONDS = 140;
|
|
6500
|
+
var boltRows = [
|
|
6501
|
+
"\u2800\u2800\u2880\u28FE\u2800\u2800\u2800\u2800",
|
|
6502
|
+
"\u2800\u2800\u28E0\u28FF\u28FF\u2800\u2800\u2800",
|
|
6503
|
+
"\u2800\u28FC\u28FF\u28FF\u28FF\u28C0\u28C0\u2840",
|
|
6504
|
+
"\u2808\u2809\u2809\u28FF\u28FF\u28FF\u285F\u2800",
|
|
6505
|
+
"\u2800\u2800\u2800\u28FF\u28FF\u280B\u2800\u2800",
|
|
6506
|
+
"\u2800\u2800\u2800\u287F\u2801\u2800\u2800\u2800"
|
|
6507
|
+
];
|
|
6508
|
+
var boltFillOrder = boltRows.flatMap(
|
|
6509
|
+
(row, rowIndex) => [...row].flatMap(
|
|
6510
|
+
(cell, columnIndex) => cell === BRAILLE_BLANK ? [] : rowIndex * row.length + columnIndex
|
|
6511
|
+
)
|
|
6512
|
+
);
|
|
6513
|
+
var fillStages = [
|
|
6514
|
+
...Array.from({ length: boltFillOrder.length + 1 }, (_, index) => index),
|
|
6515
|
+
boltFillOrder.length,
|
|
6516
|
+
0
|
|
6517
|
+
];
|
|
6518
|
+
var boltFillRanks = new Map(
|
|
6519
|
+
boltFillOrder.map((cellIndex, fillIndex) => [cellIndex, fillIndex])
|
|
6520
|
+
);
|
|
6521
|
+
var STATUS_ROW_INDEX = Math.floor(boltRows.length / 2);
|
|
6522
|
+
function formatPhase({ label, detail }) {
|
|
6523
|
+
return detail ? `${chalk8__default.default.bold(label)} ${chalk8__default.default.dim(detail)}` : chalk8__default.default.bold(label);
|
|
6524
|
+
}
|
|
6525
|
+
function formatLoaderFrame({
|
|
6526
|
+
phase,
|
|
6527
|
+
fillStage
|
|
6528
|
+
}) {
|
|
6529
|
+
return boltRows.map((row, rowIndex) => {
|
|
6530
|
+
const bolt = [...row].map((cell, columnIndex) => {
|
|
6531
|
+
if (cell === BRAILLE_BLANK) return cell;
|
|
6532
|
+
const cellIndex = rowIndex * row.length + columnIndex;
|
|
6533
|
+
const fillRank = boltFillRanks.get(cellIndex);
|
|
6534
|
+
const isFilled = fillRank !== void 0 && fillRank < fillStage;
|
|
6535
|
+
return isFilled ? chalk8__default.default.bold.yellow(cell) : chalk8__default.default.dim.yellow(cell);
|
|
6536
|
+
}).join("");
|
|
6537
|
+
const status = rowIndex === STATUS_ROW_INDEX ? ` ${formatPhase(phase)}` : "";
|
|
6538
|
+
return `${bolt}${status}`;
|
|
6539
|
+
}).join("\n");
|
|
6540
|
+
}
|
|
6541
|
+
async function runWithSetupLoader({
|
|
6542
|
+
promise,
|
|
6543
|
+
...phase
|
|
6544
|
+
}) {
|
|
6545
|
+
const startedAt = Date.now();
|
|
6546
|
+
let fillFrameIndex = 0;
|
|
6547
|
+
const loader = ora__default.default({
|
|
6548
|
+
isEnabled: process.stderr.isTTY === true,
|
|
6549
|
+
spinner: { interval: 80, frames: [""] },
|
|
6550
|
+
text: formatLoaderFrame({
|
|
6551
|
+
phase,
|
|
6552
|
+
fillStage: fillStages[fillFrameIndex]
|
|
6553
|
+
})
|
|
6554
|
+
}).start();
|
|
6555
|
+
const animationTimer = setInterval(() => {
|
|
6556
|
+
fillFrameIndex = (fillFrameIndex + 1) % fillStages.length;
|
|
6557
|
+
loader.text = formatLoaderFrame({
|
|
6558
|
+
phase,
|
|
6559
|
+
fillStage: fillStages[fillFrameIndex]
|
|
6560
|
+
});
|
|
6561
|
+
}, LIGHTNING_INTERVAL_MILLISECONDS);
|
|
6562
|
+
animationTimer.unref?.();
|
|
6563
|
+
try {
|
|
6564
|
+
const result = await promise;
|
|
6565
|
+
clearInterval(animationTimer);
|
|
6566
|
+
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
6567
|
+
loader.succeed(`${formatPhase(phase)} ${chalk8__default.default.dim(`${elapsedSeconds}s`)}`);
|
|
6568
|
+
return result;
|
|
6569
|
+
} catch (error) {
|
|
6570
|
+
clearInterval(animationTimer);
|
|
6571
|
+
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
6572
|
+
loader.fail(`${formatPhase(phase)} ${chalk8__default.default.dim(`${elapsedSeconds}s`)}`);
|
|
6573
|
+
throw error;
|
|
6574
|
+
}
|
|
6575
|
+
}
|
|
6576
|
+
function isRecord(value) {
|
|
6577
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6578
|
+
}
|
|
6579
|
+
function readPackageJson({
|
|
6580
|
+
directory
|
|
6581
|
+
}) {
|
|
6582
|
+
try {
|
|
6583
|
+
const manifest = JSON.parse(
|
|
6584
|
+
fs.readFileSync(path.join(directory, "package.json"), "utf8")
|
|
6585
|
+
);
|
|
6586
|
+
return isRecord(manifest) ? manifest : void 0;
|
|
6587
|
+
} catch {
|
|
6588
|
+
return void 0;
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6591
|
+
var SetupOptionSchema = zod.z.object({
|
|
6592
|
+
label: zod.z.string(),
|
|
6593
|
+
value: zod.z.string()
|
|
6594
|
+
});
|
|
6595
|
+
var SetupOptionsSchema = zod.z.array(SetupOptionSchema).min(1);
|
|
6596
|
+
var SetupDecisionSchema = zod.z.object({
|
|
6597
|
+
message: zod.z.string(),
|
|
6598
|
+
options: SetupOptionsSchema,
|
|
6599
|
+
answer: zod.z.string()
|
|
6600
|
+
});
|
|
6601
|
+
var SetupInputSchema = zod.z.object({
|
|
6602
|
+
message: zod.z.string(),
|
|
6603
|
+
answer: zod.z.string()
|
|
6604
|
+
});
|
|
6605
|
+
var setupDecisionResolver = zapierSdk.defineResolver({
|
|
6606
|
+
requireParameters: ["message", "options"],
|
|
6607
|
+
listItems: ({ input }) => ({ data: input.options }),
|
|
6608
|
+
prompt: ({ items, input }) => ({
|
|
6609
|
+
type: "list",
|
|
6610
|
+
message: input.message,
|
|
6611
|
+
choices: items
|
|
6612
|
+
}),
|
|
6613
|
+
validate: ({ input, value }) => {
|
|
6614
|
+
if (typeof value !== "string") return "Choose an available option.";
|
|
6615
|
+
return input.options.some((option) => option.value === value) || "Choose one of the available options.";
|
|
6616
|
+
}
|
|
6617
|
+
});
|
|
6618
|
+
var setupInputResolver = zapierSdk.defineResolver({
|
|
6619
|
+
type: "static",
|
|
6620
|
+
inputType: "text",
|
|
6621
|
+
requireParameters: ["message"]
|
|
6622
|
+
});
|
|
6623
|
+
var resolveSetupDecisionPlugin = zapierSdk.defineMethod({
|
|
6624
|
+
name: "resolveSetupDecision",
|
|
6625
|
+
description: "Resolve one setup wizard decision.",
|
|
6626
|
+
inputSchema: SetupDecisionSchema,
|
|
6627
|
+
resolvers: { answer: setupDecisionResolver },
|
|
6628
|
+
run: ({ input }) => input
|
|
6629
|
+
});
|
|
6630
|
+
var resolveSetupInputPlugin = zapierSdk.defineMethod({
|
|
6631
|
+
name: "resolveSetupInput",
|
|
6632
|
+
description: "Resolve one setup wizard text input.",
|
|
6633
|
+
inputSchema: SetupInputSchema,
|
|
6634
|
+
resolvers: { answer: setupInputResolver },
|
|
6635
|
+
run: ({ input }) => input
|
|
6636
|
+
});
|
|
6637
|
+
function createSetupController() {
|
|
6638
|
+
const setupResolutionSdk = zapierSdk.createSdk(
|
|
6639
|
+
zapierSdk.definePlugin({
|
|
6640
|
+
name: "setup-resolution",
|
|
6641
|
+
exports: [
|
|
6642
|
+
resolveSetupDecisionPlugin,
|
|
6643
|
+
resolveSetupInputPlugin,
|
|
6644
|
+
zapierSdk.getRegistryPlugin
|
|
6645
|
+
]
|
|
6646
|
+
})
|
|
6647
|
+
);
|
|
6648
|
+
return zapierSdk.createController(setupResolutionSdk);
|
|
6649
|
+
}
|
|
6650
|
+
async function resolveWithCancellation({
|
|
6651
|
+
run
|
|
6652
|
+
}) {
|
|
6653
|
+
try {
|
|
6654
|
+
return await run();
|
|
6655
|
+
} catch (error) {
|
|
6656
|
+
if (zapierSdk.isCoreCancelledSignal(error)) {
|
|
6657
|
+
throw new ZapierCliUserCancellationError();
|
|
6658
|
+
}
|
|
6659
|
+
throw error;
|
|
6660
|
+
}
|
|
6661
|
+
}
|
|
6662
|
+
async function resolveSetupDecision({
|
|
6663
|
+
answer,
|
|
6664
|
+
controller,
|
|
6665
|
+
message,
|
|
6666
|
+
options
|
|
6667
|
+
}) {
|
|
6668
|
+
const parsedOptions = SetupOptionsSchema.parse(options);
|
|
6669
|
+
const resolved = await resolveWithCancellation({
|
|
6670
|
+
run: () => controller.resolve({
|
|
6671
|
+
method: "resolveSetupDecision",
|
|
6672
|
+
input: { message, options: parsedOptions },
|
|
6673
|
+
answer,
|
|
6674
|
+
interactive: true
|
|
6675
|
+
})
|
|
6676
|
+
});
|
|
6677
|
+
return SetupDecisionSchema.parse(resolved).answer;
|
|
6678
|
+
}
|
|
6679
|
+
async function resolveSetupConfirm({
|
|
6680
|
+
answer,
|
|
6681
|
+
controller,
|
|
6682
|
+
defaultValue,
|
|
6683
|
+
message
|
|
6684
|
+
}) {
|
|
6685
|
+
const values = defaultValue ? [true, false] : [false, true];
|
|
6686
|
+
const resolved = await resolveSetupDecision({
|
|
6687
|
+
answer,
|
|
6688
|
+
controller,
|
|
6689
|
+
message,
|
|
6690
|
+
options: values.map((value) => ({
|
|
6691
|
+
label: value ? "Yes" : "No",
|
|
6692
|
+
value: String(value)
|
|
6693
|
+
}))
|
|
6694
|
+
});
|
|
6695
|
+
return resolved === "true";
|
|
6696
|
+
}
|
|
6697
|
+
async function resolveSetupInput({
|
|
6698
|
+
answer,
|
|
6699
|
+
controller,
|
|
6700
|
+
message
|
|
6701
|
+
}) {
|
|
6702
|
+
const resolved = await resolveWithCancellation({
|
|
6703
|
+
run: () => controller.resolve({
|
|
6704
|
+
method: "resolveSetupInput",
|
|
6705
|
+
input: { message },
|
|
6706
|
+
answer: ({ result, state }) => answer({
|
|
6707
|
+
state,
|
|
6708
|
+
result: {
|
|
6709
|
+
...result,
|
|
6710
|
+
question: { ...result.question, message }
|
|
6711
|
+
}
|
|
6712
|
+
}),
|
|
6713
|
+
interactive: true
|
|
6714
|
+
})
|
|
6715
|
+
});
|
|
6716
|
+
return SetupInputSchema.parse(resolved).answer.trim();
|
|
6717
|
+
}
|
|
6718
|
+
async function resolveSetupSelect({
|
|
6719
|
+
answer,
|
|
6720
|
+
controller,
|
|
6721
|
+
choices,
|
|
6722
|
+
message
|
|
6723
|
+
}) {
|
|
6724
|
+
const resolved = await resolveSetupDecision({
|
|
6725
|
+
answer,
|
|
6726
|
+
controller,
|
|
6727
|
+
message,
|
|
6728
|
+
options: choices
|
|
6729
|
+
});
|
|
6730
|
+
const selected = choices.find(({ value }) => value === resolved);
|
|
6731
|
+
if (!selected) {
|
|
6732
|
+
throw new Error("Resolved setup selection is not an available choice.");
|
|
6733
|
+
}
|
|
6734
|
+
return selected.value;
|
|
6735
|
+
}
|
|
6736
|
+
|
|
6737
|
+
// src/plugins/setup/dependencies.ts
|
|
6738
|
+
var REQUIRED_PACKAGES = [
|
|
6739
|
+
{ name: "@zapier/zapier-sdk", dev: false, checkForUpdates: true },
|
|
6740
|
+
{ name: "@zapier/zapier-sdk-cli", dev: true, checkForUpdates: true },
|
|
6741
|
+
{
|
|
6742
|
+
name: "@types/node",
|
|
6743
|
+
dev: true,
|
|
6744
|
+
checkForUpdates: false,
|
|
6745
|
+
typescriptOnly: true
|
|
6746
|
+
},
|
|
6747
|
+
{
|
|
6748
|
+
name: "typescript",
|
|
6749
|
+
dev: true,
|
|
6750
|
+
checkForUpdates: false,
|
|
6751
|
+
typescriptOnly: true
|
|
6752
|
+
},
|
|
6753
|
+
{ name: "tsx", dev: true, checkForUpdates: false, typescriptOnly: true }
|
|
6754
|
+
];
|
|
6755
|
+
function getInstallCommand({
|
|
6756
|
+
packageManager,
|
|
6757
|
+
packages,
|
|
6758
|
+
dev = false
|
|
6759
|
+
}) {
|
|
6760
|
+
const verb = packageManager === "npm" ? "install" : "add";
|
|
6761
|
+
const devFlag = packageManager === "bun" ? "-d" : "-D";
|
|
6762
|
+
return {
|
|
6763
|
+
command: packageManager,
|
|
6764
|
+
args: [verb, ...dev ? [devFlag] : [], ...packages]
|
|
6765
|
+
};
|
|
6766
|
+
}
|
|
6767
|
+
async function executeInstall(context, command) {
|
|
6768
|
+
try {
|
|
6769
|
+
await context.runCommand({ ...command, cwd: context.cwd });
|
|
6770
|
+
} catch (error) {
|
|
6771
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6772
|
+
if (message.includes("EPERM") && message.includes(".npm/_cacache")) {
|
|
6773
|
+
console.error(
|
|
6774
|
+
"This EPERM usually means the command sandbox blocked npm cache writes; it does not usually mean your file permissions are broken."
|
|
6775
|
+
);
|
|
6776
|
+
}
|
|
6777
|
+
throw error;
|
|
6778
|
+
}
|
|
6779
|
+
}
|
|
6780
|
+
function getDeclaredPackageNames(cwd) {
|
|
6781
|
+
const manifest = readPackageJson({ directory: cwd });
|
|
6782
|
+
if (!manifest) return /* @__PURE__ */ new Set();
|
|
6783
|
+
const names = /* @__PURE__ */ new Set();
|
|
6784
|
+
for (const section of ["dependencies", "devDependencies"]) {
|
|
6785
|
+
const dependencies = manifest[section];
|
|
6786
|
+
if (!isRecord(dependencies)) continue;
|
|
6787
|
+
for (const name of Object.keys(dependencies)) names.add(name);
|
|
6788
|
+
}
|
|
6789
|
+
return names;
|
|
6790
|
+
}
|
|
6791
|
+
function getInstalledPackageVersion({
|
|
6792
|
+
cwd,
|
|
6793
|
+
packageName
|
|
6794
|
+
}) {
|
|
6795
|
+
let directory = cwd;
|
|
6796
|
+
while (true) {
|
|
6797
|
+
const manifest = readPackageJson({
|
|
6798
|
+
directory: path.join(directory, "node_modules", ...packageName.split("/"))
|
|
6799
|
+
});
|
|
6800
|
+
if (manifest?.name === packageName && typeof manifest.version === "string") {
|
|
6801
|
+
return manifest.version;
|
|
6802
|
+
}
|
|
6803
|
+
const parent = path.dirname(directory);
|
|
6804
|
+
if (parent === directory) return void 0;
|
|
6805
|
+
directory = parent;
|
|
6806
|
+
}
|
|
6807
|
+
}
|
|
6808
|
+
async function installPackages({
|
|
6809
|
+
context,
|
|
6810
|
+
packages
|
|
6811
|
+
}) {
|
|
6812
|
+
const runtimePackages = packages.filter(({ dependency }) => !dependency.dev).map(({ dependency }) => dependency.name);
|
|
6813
|
+
if (runtimePackages.length > 0) {
|
|
6814
|
+
await executeInstall(
|
|
6815
|
+
context,
|
|
6816
|
+
getInstallCommand({
|
|
6817
|
+
packageManager: context.packageManager,
|
|
6818
|
+
packages: runtimePackages
|
|
6819
|
+
})
|
|
6820
|
+
);
|
|
6821
|
+
}
|
|
6822
|
+
const developmentPackages = packages.filter(({ dependency }) => dependency.dev).map(({ dependency }) => dependency.name);
|
|
6823
|
+
if (developmentPackages.length > 0) {
|
|
6824
|
+
await executeInstall(
|
|
6825
|
+
context,
|
|
6826
|
+
getInstallCommand({
|
|
6827
|
+
packageManager: context.packageManager,
|
|
6828
|
+
packages: developmentPackages,
|
|
6829
|
+
dev: true
|
|
6830
|
+
})
|
|
6831
|
+
);
|
|
6832
|
+
}
|
|
6833
|
+
}
|
|
6834
|
+
async function offerMissingPackageInstall({
|
|
6835
|
+
context,
|
|
6836
|
+
packages
|
|
6837
|
+
}) {
|
|
6838
|
+
if (packages.length === 0) return;
|
|
6839
|
+
const shouldInstall = await resolveSetupConfirm({
|
|
6840
|
+
answer: context.createAnswer(),
|
|
6841
|
+
controller: context.setupController,
|
|
6842
|
+
message: `These packages are required to continue. Install them now: ${packages.map(({ dependency }) => dependency.name).join(", ")}?`,
|
|
6843
|
+
defaultValue: true
|
|
6844
|
+
});
|
|
6845
|
+
if (!shouldInstall) {
|
|
6846
|
+
console.log(
|
|
6847
|
+
"The Zapier SDK packages are required to continue. Setup cancelled without installing dependencies."
|
|
6848
|
+
);
|
|
6849
|
+
throw new ZapierCliUserCancellationError(
|
|
6850
|
+
"Required Zapier SDK packages were not installed"
|
|
6851
|
+
);
|
|
6852
|
+
}
|
|
6853
|
+
await installPackages({ context, packages });
|
|
6854
|
+
}
|
|
6855
|
+
async function offerPackageUpdate({
|
|
6856
|
+
context,
|
|
6857
|
+
packageState
|
|
6858
|
+
}) {
|
|
6859
|
+
const { currentVersion, dependency } = packageState;
|
|
6860
|
+
if (!currentVersion || !dependency.checkForUpdates) return;
|
|
6861
|
+
const update = await runWithSetupLoader({
|
|
6862
|
+
promise: context.checkForUpdates({
|
|
6863
|
+
packageName: dependency.name,
|
|
6864
|
+
currentVersion
|
|
6865
|
+
}),
|
|
6866
|
+
label: "Checking for updates",
|
|
6867
|
+
detail: dependency.name
|
|
6868
|
+
});
|
|
6869
|
+
if (!update.hasUpdate || !update.latestVersion) return;
|
|
6870
|
+
const shouldUpdate = await resolveSetupConfirm({
|
|
6871
|
+
answer: context.createAnswer(),
|
|
6872
|
+
controller: context.setupController,
|
|
6873
|
+
message: `Update ${dependency.name} from ${currentVersion} to ${update.latestVersion}?`,
|
|
6874
|
+
defaultValue: true
|
|
6875
|
+
});
|
|
6876
|
+
if (!shouldUpdate) return;
|
|
6877
|
+
await executeInstall(
|
|
6878
|
+
context,
|
|
6879
|
+
getInstallCommand({
|
|
6880
|
+
packageManager: context.packageManager,
|
|
6881
|
+
packages: [`${dependency.name}@${update.latestVersion}`],
|
|
6882
|
+
dev: dependency.dev
|
|
6883
|
+
})
|
|
6884
|
+
);
|
|
6885
|
+
}
|
|
6886
|
+
async function prepareDependencies(context) {
|
|
6887
|
+
const declaredPackageNames = getDeclaredPackageNames(context.cwd);
|
|
6888
|
+
const requiredPackages = REQUIRED_PACKAGES.filter(
|
|
6889
|
+
({ typescriptOnly }) => !typescriptOnly || context.projectLanguage === "typescript"
|
|
6890
|
+
);
|
|
6891
|
+
const packages = requiredPackages.map((dependency) => ({
|
|
6892
|
+
dependency,
|
|
6893
|
+
currentVersion: declaredPackageNames.has(dependency.name) ? getInstalledPackageVersion({
|
|
6894
|
+
cwd: context.cwd,
|
|
6895
|
+
packageName: dependency.name
|
|
6896
|
+
}) : void 0
|
|
6897
|
+
}));
|
|
6898
|
+
await offerMissingPackageInstall({
|
|
6899
|
+
context,
|
|
6900
|
+
packages: packages.filter(
|
|
6901
|
+
({ dependency }) => !declaredPackageNames.has(dependency.name)
|
|
6902
|
+
)
|
|
6903
|
+
});
|
|
6904
|
+
for (const packageState of packages) {
|
|
6905
|
+
await offerPackageUpdate({ context, packageState });
|
|
6906
|
+
}
|
|
6907
|
+
}
|
|
6908
|
+
|
|
6909
|
+
// src/plugins/setup/package-commands.ts
|
|
6910
|
+
function createLocalPackageCommand({
|
|
6911
|
+
packageManager,
|
|
6912
|
+
binary,
|
|
6913
|
+
args = []
|
|
6914
|
+
}) {
|
|
6915
|
+
const runner = {
|
|
6916
|
+
npm: { command: "npx", args: ["--no-install"] },
|
|
6917
|
+
pnpm: { command: "pnpm", args: ["exec"] },
|
|
6918
|
+
yarn: { command: "yarn", args: ["exec"] },
|
|
6919
|
+
bun: { command: "bunx", args: ["--no-install"] }
|
|
6920
|
+
};
|
|
6921
|
+
return {
|
|
6922
|
+
command: runner[packageManager].command,
|
|
6923
|
+
args: [...runner[packageManager].args, binary, ...args]
|
|
6924
|
+
};
|
|
6925
|
+
}
|
|
6926
|
+
function createPackageRunnerCommand({
|
|
6927
|
+
packageManager,
|
|
6928
|
+
packageName,
|
|
6929
|
+
args = []
|
|
6930
|
+
}) {
|
|
6931
|
+
const runner = {
|
|
6932
|
+
npm: { command: "npx", args: ["--yes"] },
|
|
6933
|
+
pnpm: { command: "pnpm", args: ["dlx"] },
|
|
6934
|
+
yarn: { command: "yarn", args: ["dlx"] },
|
|
6935
|
+
bun: { command: "bunx", args: [] }
|
|
6936
|
+
};
|
|
6937
|
+
return {
|
|
6938
|
+
command: runner[packageManager].command,
|
|
6939
|
+
args: [...runner[packageManager].args, packageName, ...args]
|
|
6940
|
+
};
|
|
6941
|
+
}
|
|
6942
|
+
function formatPackageCommand({
|
|
6943
|
+
command,
|
|
6944
|
+
args
|
|
6945
|
+
}) {
|
|
6946
|
+
return [command, ...args].join(" ");
|
|
6947
|
+
}
|
|
6948
|
+
|
|
6949
|
+
// src/plugins/setup/project.ts
|
|
6950
|
+
var COMMAND_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
6951
|
+
var PROJECT_INIT_COMMANDS = {
|
|
6952
|
+
npm: { command: "npm", args: ["init", "-y"] },
|
|
6953
|
+
pnpm: { command: "pnpm", args: ["init"] },
|
|
6954
|
+
yarn: { command: "yarn", args: ["init", "-y"] },
|
|
6955
|
+
bun: { command: "bun", args: ["init", "-y"] }
|
|
6956
|
+
};
|
|
6957
|
+
var CapturedCommandError = class extends Error {
|
|
6958
|
+
constructor(error, stdout, stderr) {
|
|
6959
|
+
super(error.message);
|
|
6960
|
+
this.stdout = stdout;
|
|
6961
|
+
this.stderr = stderr;
|
|
6962
|
+
}
|
|
6963
|
+
};
|
|
6964
|
+
function commandError({
|
|
6965
|
+
command,
|
|
6966
|
+
code,
|
|
6967
|
+
signal
|
|
6968
|
+
}) {
|
|
6969
|
+
return new Error(
|
|
6970
|
+
signal ? `${command} was terminated by ${signal}` : `${command} exited with code ${code ?? "unknown"}`
|
|
6971
|
+
);
|
|
6972
|
+
}
|
|
6973
|
+
function executeCapturedCommand({
|
|
6974
|
+
command,
|
|
6975
|
+
args,
|
|
6976
|
+
cwd,
|
|
6977
|
+
input
|
|
6978
|
+
}) {
|
|
6979
|
+
return new Promise((resolve4, reject) => {
|
|
6980
|
+
const child = crossSpawn__default.default(command, args, {
|
|
6981
|
+
cwd,
|
|
6982
|
+
shell: false,
|
|
6983
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6984
|
+
});
|
|
6985
|
+
let stdout = "";
|
|
6986
|
+
let stderr = "";
|
|
6987
|
+
const append = ({
|
|
6988
|
+
chunk,
|
|
6989
|
+
stream
|
|
6990
|
+
}) => {
|
|
6991
|
+
if (stream === "stdout") stdout += chunk.toString();
|
|
6992
|
+
else stderr += chunk.toString();
|
|
6993
|
+
if (Buffer.byteLength(stdout) + Buffer.byteLength(stderr) > COMMAND_MAX_BUFFER_BYTES) {
|
|
6994
|
+
child.kill();
|
|
6995
|
+
reject(new Error("Command output exceeded the capture limit."));
|
|
6996
|
+
}
|
|
6997
|
+
};
|
|
6998
|
+
child.stdout?.on(
|
|
6999
|
+
"data",
|
|
7000
|
+
(chunk) => append({ chunk, stream: "stdout" })
|
|
7001
|
+
);
|
|
7002
|
+
child.stderr?.on(
|
|
7003
|
+
"data",
|
|
7004
|
+
(chunk) => append({ chunk, stream: "stderr" })
|
|
7005
|
+
);
|
|
7006
|
+
child.once("error", reject);
|
|
7007
|
+
child.once("close", (code, signal) => {
|
|
7008
|
+
if (code === 0) {
|
|
7009
|
+
resolve4(stdout.trim());
|
|
7010
|
+
return;
|
|
7011
|
+
}
|
|
7012
|
+
reject(
|
|
7013
|
+
new CapturedCommandError(
|
|
7014
|
+
commandError({ command, code, signal }),
|
|
7015
|
+
stdout,
|
|
7016
|
+
stderr
|
|
7017
|
+
)
|
|
7018
|
+
);
|
|
7019
|
+
});
|
|
7020
|
+
child.stdin?.end(input);
|
|
7021
|
+
});
|
|
7022
|
+
}
|
|
7023
|
+
function executeStreamingCommand({
|
|
7024
|
+
command,
|
|
7025
|
+
args,
|
|
7026
|
+
cwd,
|
|
7027
|
+
input
|
|
7028
|
+
}) {
|
|
7029
|
+
return new Promise((resolve4, reject) => {
|
|
7030
|
+
const child = crossSpawn__default.default(command, args, {
|
|
7031
|
+
cwd,
|
|
7032
|
+
shell: false,
|
|
7033
|
+
stdio: [input === void 0 ? "inherit" : "pipe", "inherit", "inherit"]
|
|
7034
|
+
});
|
|
7035
|
+
child.once("error", reject);
|
|
7036
|
+
child.once("close", (code, signal) => {
|
|
7037
|
+
if (code === 0) {
|
|
7038
|
+
resolve4("");
|
|
7039
|
+
return;
|
|
7040
|
+
}
|
|
7041
|
+
reject(commandError({ command, code, signal }));
|
|
7042
|
+
});
|
|
7043
|
+
if (input !== void 0) child.stdin?.end(input);
|
|
7044
|
+
});
|
|
7045
|
+
}
|
|
7046
|
+
async function runCommand({
|
|
7047
|
+
command,
|
|
7048
|
+
args = [],
|
|
7049
|
+
cwd,
|
|
7050
|
+
capture = true,
|
|
7051
|
+
input
|
|
7052
|
+
}) {
|
|
7053
|
+
const commandLabel = `$ ${command} ${args.join(" ")}`.trim();
|
|
7054
|
+
const execute = capture ? executeCapturedCommand({ command, args, cwd, input }) : executeStreamingCommand({ command, args, cwd, input });
|
|
7055
|
+
try {
|
|
7056
|
+
if (capture) {
|
|
7057
|
+
return await runWithSetupLoader({
|
|
7058
|
+
promise: execute,
|
|
7059
|
+
label: "Running command",
|
|
7060
|
+
detail: commandLabel
|
|
7061
|
+
});
|
|
7062
|
+
}
|
|
7063
|
+
console.log(chalk8__default.default.dim(commandLabel));
|
|
7064
|
+
return await execute;
|
|
7065
|
+
} catch (error) {
|
|
7066
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7067
|
+
if (error instanceof CapturedCommandError) {
|
|
7068
|
+
if (error.stdout) process.stdout.write(error.stdout);
|
|
7069
|
+
if (error.stderr) process.stderr.write(error.stderr);
|
|
7070
|
+
if (!error.stdout && !error.stderr) console.error(message);
|
|
7071
|
+
} else {
|
|
7072
|
+
console.error(message);
|
|
7073
|
+
}
|
|
7074
|
+
throw new ZapierCliExitError(message);
|
|
7075
|
+
}
|
|
7076
|
+
}
|
|
7077
|
+
async function chooseDirectory(context) {
|
|
7078
|
+
const useCurrentDirectory = await resolveSetupConfirm({
|
|
7079
|
+
answer: context.createAnswer(),
|
|
7080
|
+
controller: context.setupController,
|
|
7081
|
+
message: `Set up the Zapier SDK in ${context.cwd}?`,
|
|
7082
|
+
defaultValue: true
|
|
7083
|
+
});
|
|
7084
|
+
if (useCurrentDirectory) return;
|
|
7085
|
+
const setupCommand = formatPackageCommand(
|
|
7086
|
+
createLocalPackageCommand({
|
|
7087
|
+
packageManager: context.packageManager,
|
|
7088
|
+
binary: "zapier-sdk",
|
|
7089
|
+
args: ["setup"]
|
|
7090
|
+
})
|
|
7091
|
+
);
|
|
7092
|
+
console.log(
|
|
7093
|
+
`Setup cancelled. Navigate to the intended directory and run \`${setupCommand}\` again.`
|
|
7094
|
+
);
|
|
7095
|
+
throw new ZapierCliUserCancellationError("Setup cancelled by user");
|
|
7096
|
+
}
|
|
7097
|
+
async function ensureSupportedNode(context) {
|
|
7098
|
+
let version;
|
|
7099
|
+
try {
|
|
7100
|
+
version = await context.runCommand({
|
|
7101
|
+
command: "node",
|
|
7102
|
+
args: ["-v"],
|
|
7103
|
+
cwd: context.cwd,
|
|
7104
|
+
capture: true
|
|
7105
|
+
});
|
|
7106
|
+
} catch {
|
|
7107
|
+
console.error(
|
|
7108
|
+
"Node.js 20 or higher is required. Install it from https://nodejs.org, then run setup again."
|
|
7109
|
+
);
|
|
7110
|
+
throw new ZapierCliExitError(
|
|
7111
|
+
"Setup could not continue without Node.js 20 or higher."
|
|
7112
|
+
);
|
|
7113
|
+
}
|
|
7114
|
+
const major = Number(version.replace(/^v/, "").split(".")[0]);
|
|
7115
|
+
if (!Number.isFinite(major) || major < 20) {
|
|
7116
|
+
console.error(
|
|
7117
|
+
`Node.js 20 or higher is required; found ${version}. Upgrade Node.js, then run setup again.`
|
|
7118
|
+
);
|
|
7119
|
+
throw new ZapierCliExitError(
|
|
7120
|
+
"Setup could not continue without Node.js 20 or higher."
|
|
7121
|
+
);
|
|
7122
|
+
}
|
|
7123
|
+
console.log(`Node.js ${version} is ready.`);
|
|
7124
|
+
}
|
|
7125
|
+
function detectProjectLanguage({
|
|
7126
|
+
cwd,
|
|
7127
|
+
hasExistingProject
|
|
7128
|
+
}) {
|
|
7129
|
+
if (!hasExistingProject || fs.existsSync(path.join(cwd, "tsconfig.json"))) {
|
|
7130
|
+
return "typescript";
|
|
7131
|
+
}
|
|
7132
|
+
const manifest = readPackageJson({ directory: cwd });
|
|
7133
|
+
const hasTypeScript = [
|
|
7134
|
+
manifest?.dependencies,
|
|
7135
|
+
manifest?.devDependencies
|
|
7136
|
+
].some(
|
|
7137
|
+
(dependencies) => isRecord(dependencies) && "typescript" in dependencies
|
|
7138
|
+
);
|
|
7139
|
+
return hasTypeScript ? "typescript" : "javascript";
|
|
7140
|
+
}
|
|
7141
|
+
async function prepareProject(context) {
|
|
7142
|
+
context.packageManager = detectPackageManager(context.cwd).name;
|
|
7143
|
+
console.log(`Using ${context.packageManager} for dependency installs.`);
|
|
7144
|
+
const hasExistingProject = fs.existsSync(path.join(context.cwd, "package.json"));
|
|
7145
|
+
context.projectLanguage = detectProjectLanguage({
|
|
7146
|
+
cwd: context.cwd,
|
|
7147
|
+
hasExistingProject
|
|
7148
|
+
});
|
|
7149
|
+
if (hasExistingProject) {
|
|
7150
|
+
console.log("Found package.json; using this project as-is.");
|
|
7151
|
+
} else {
|
|
7152
|
+
await context.runCommand({
|
|
7153
|
+
...PROJECT_INIT_COMMANDS[context.packageManager],
|
|
7154
|
+
cwd: context.cwd
|
|
7155
|
+
});
|
|
7156
|
+
}
|
|
7157
|
+
await prepareDependencies(context);
|
|
7158
|
+
}
|
|
7159
|
+
|
|
7160
|
+
// src/plugins/setup/context.ts
|
|
7161
|
+
function createWizardContext({
|
|
7162
|
+
imports
|
|
7163
|
+
}) {
|
|
7164
|
+
return {
|
|
7165
|
+
cwd: process.cwd(),
|
|
7166
|
+
imports,
|
|
7167
|
+
createAnswer: () => createCliAnswer({ mode: "closed-list" }),
|
|
7168
|
+
setupController: createSetupController(),
|
|
7169
|
+
checkForUpdates,
|
|
7170
|
+
openUrl: async (url) => {
|
|
7171
|
+
await open__default.default(url);
|
|
7172
|
+
},
|
|
7173
|
+
runCommand,
|
|
7174
|
+
packageManager: detectPackageManager(process.cwd()).name,
|
|
7175
|
+
projectLanguage: "typescript"
|
|
7176
|
+
};
|
|
7177
|
+
}
|
|
7178
|
+
var SetupSchema = zod.z.object({}).describe("Set up the Zapier SDK in an existing or new project");
|
|
7179
|
+
function printAuthCommand({
|
|
7180
|
+
context,
|
|
7181
|
+
flow,
|
|
7182
|
+
headless
|
|
7183
|
+
}) {
|
|
7184
|
+
const command = createLocalPackageCommand({
|
|
7185
|
+
packageManager: context.packageManager,
|
|
7186
|
+
binary: "zapier-sdk",
|
|
7187
|
+
args: [flow, ...headless ? ["--headless"] : []]
|
|
7188
|
+
});
|
|
7189
|
+
console.log(`$ ${formatPackageCommand(command)}`);
|
|
7190
|
+
if (headless) {
|
|
7191
|
+
console.log(
|
|
7192
|
+
"Open the printed URL in another browser, then paste the final OAuth callback URL when prompted."
|
|
7193
|
+
);
|
|
7194
|
+
}
|
|
7195
|
+
}
|
|
7196
|
+
function isCredentialWriteError(error) {
|
|
7197
|
+
const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : "";
|
|
7198
|
+
if (/^(eacces|eperm)$/i.test(code)) return true;
|
|
7199
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7200
|
+
return /permission|sandbox|eacces|eperm/i.test(message);
|
|
7201
|
+
}
|
|
7202
|
+
async function authenticate(context) {
|
|
7203
|
+
const activeProfile = await runWithSetupLoader({
|
|
7204
|
+
promise: context.imports.getProfile({}).then(({ data }) => data).catch((error) => {
|
|
7205
|
+
if (zapierSdk.isZapierAuthenticationError(error)) return void 0;
|
|
7206
|
+
throw error;
|
|
7207
|
+
}),
|
|
7208
|
+
label: "Checking Zapier authentication"
|
|
7209
|
+
});
|
|
7210
|
+
if (activeProfile) {
|
|
7211
|
+
const shouldLogout = await resolveSetupConfirm({
|
|
7212
|
+
answer: context.createAnswer(),
|
|
7213
|
+
controller: context.setupController,
|
|
7214
|
+
message: `You are already logged in as "${activeProfile.email}".
|
|
7215
|
+
Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
|
|
7216
|
+
Log out and use a different account?`,
|
|
7217
|
+
defaultValue: false
|
|
7218
|
+
});
|
|
7219
|
+
if (!shouldLogout) {
|
|
7220
|
+
context.accountEmail = activeProfile.email;
|
|
7221
|
+
console.log(`Continuing as ${activeProfile.email}.`);
|
|
7222
|
+
return;
|
|
7223
|
+
}
|
|
7224
|
+
const logoutCommand = createLocalPackageCommand({
|
|
7225
|
+
packageManager: context.packageManager,
|
|
7226
|
+
binary: "zapier-sdk",
|
|
7227
|
+
args: ["logout"]
|
|
7228
|
+
});
|
|
7229
|
+
console.log(`$ ${formatPackageCommand(logoutCommand)}`);
|
|
7230
|
+
await context.imports.logout({});
|
|
7231
|
+
}
|
|
7232
|
+
const flow = await resolveSetupSelect({
|
|
7233
|
+
answer: context.createAnswer(),
|
|
7234
|
+
controller: context.setupController,
|
|
7235
|
+
message: "Zapier account:",
|
|
7236
|
+
choices: [
|
|
7237
|
+
{ label: "Log in to an existing account", value: "login" },
|
|
7238
|
+
{ label: "Create a new Zapier account", value: "signup" }
|
|
7239
|
+
]
|
|
7240
|
+
});
|
|
7241
|
+
const environment = await resolveSetupSelect({
|
|
7242
|
+
answer: context.createAnswer(),
|
|
7243
|
+
controller: context.setupController,
|
|
7244
|
+
message: "Environment:",
|
|
7245
|
+
choices: [
|
|
7246
|
+
{ label: "Local machine with a browser", value: "local" },
|
|
7247
|
+
{ label: "Remote or headless", value: "headless" }
|
|
7248
|
+
]
|
|
7249
|
+
});
|
|
7250
|
+
const headless = environment === "headless";
|
|
7251
|
+
const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
|
|
7252
|
+
printAuthCommand({ context, flow, headless });
|
|
7253
|
+
try {
|
|
7254
|
+
await runAuth({ headless });
|
|
7255
|
+
} catch (error) {
|
|
7256
|
+
if (isCredentialWriteError(error)) {
|
|
7257
|
+
console.error(
|
|
7258
|
+
"Authentication could not write credentials. A permissions or sandbox restriction may be blocking disk access."
|
|
7259
|
+
);
|
|
7260
|
+
}
|
|
7261
|
+
throw error;
|
|
7262
|
+
}
|
|
7263
|
+
const { data: profile } = await runWithSetupLoader({
|
|
7264
|
+
promise: context.imports.getProfile({}),
|
|
7265
|
+
label: "Confirming Zapier account"
|
|
7266
|
+
});
|
|
7267
|
+
context.accountEmail = profile.email;
|
|
7268
|
+
console.log(`Authenticated as ${profile.email}.`);
|
|
7269
|
+
}
|
|
7270
|
+
var agentLabels = {
|
|
7271
|
+
claude: "Claude Code",
|
|
7272
|
+
codex: "Codex",
|
|
7273
|
+
cursor: "Cursor",
|
|
7274
|
+
"vscode-copilot": "VS Code Copilot"
|
|
7275
|
+
};
|
|
7276
|
+
function buildAgentPrompt({ context }) {
|
|
7277
|
+
const listConnectionsCommand = formatPackageCommand(
|
|
7278
|
+
createLocalPackageCommand({
|
|
7279
|
+
packageManager: context.packageManager,
|
|
7280
|
+
binary: "zapier-sdk",
|
|
7281
|
+
args: ["list-connections", "--owner", "me", "--json"]
|
|
7282
|
+
})
|
|
7283
|
+
);
|
|
7284
|
+
const listActionsCommand = formatPackageCommand(
|
|
7285
|
+
createLocalPackageCommand({
|
|
7286
|
+
packageManager: context.packageManager,
|
|
7287
|
+
binary: "zapier-sdk",
|
|
7288
|
+
args: ["list-actions", "APP_KEY"]
|
|
7289
|
+
})
|
|
7290
|
+
);
|
|
7291
|
+
return `Start by running this command to discover my active connected apps outside of your sandbox:
|
|
7292
|
+
|
|
7293
|
+
${listConnectionsCommand}
|
|
7294
|
+
|
|
7295
|
+
Using the connected apps returned by that command:
|
|
7296
|
+
|
|
7297
|
+
- Pick 1-3 apps and show commands I can use to explore their actions, such as: ${listActionsCommand}
|
|
7298
|
+
- Do not run those list-actions commands.
|
|
7299
|
+
- Suggest 3 specific ideas based on my connected apps. Each idea should read from one app, optionally process data, and write to another.
|
|
7300
|
+
- Do not suggest event-driven workflows.
|
|
7301
|
+
- Keep each idea to one sentence. Example: "pull in-progress Jira issues and DM yourself a summary on Slack".
|
|
7302
|
+
|
|
7303
|
+
Do not inspect files or modify the project. If fewer than two distinct apps are listed, explain that cross-app ideas require another active connection instead of inventing apps.`;
|
|
7304
|
+
}
|
|
7305
|
+
function printAgentPrompt({
|
|
7306
|
+
context,
|
|
7307
|
+
message
|
|
7308
|
+
}) {
|
|
7309
|
+
console.log();
|
|
7310
|
+
console.log(chalk8__default.default.bgYellow.black.bold(message));
|
|
7311
|
+
console.log();
|
|
7312
|
+
console.log(buildAgentPrompt({ context }));
|
|
7313
|
+
}
|
|
7314
|
+
async function openAgentHandoff(context) {
|
|
7315
|
+
const agent = await resolveSetupSelect({
|
|
7316
|
+
answer: context.createAnswer(),
|
|
7317
|
+
controller: context.setupController,
|
|
7318
|
+
message: "Want to open your agent and have it give you suggestions to start?",
|
|
7319
|
+
choices: [
|
|
7320
|
+
{ label: "No", value: "none" },
|
|
7321
|
+
{ label: "Claude Code", value: "claude" },
|
|
7322
|
+
{ label: "Cursor", value: "cursor" },
|
|
7323
|
+
{ label: "Codex", value: "codex" },
|
|
7324
|
+
{ label: "VS Code Copilot", value: "vscode-copilot" },
|
|
7325
|
+
{ label: "Other", value: "other" }
|
|
7326
|
+
]
|
|
7327
|
+
});
|
|
7328
|
+
if (agent === "none") return;
|
|
7329
|
+
if (agent === "other") {
|
|
7330
|
+
printAgentPrompt({
|
|
7331
|
+
context,
|
|
7332
|
+
message: "Paste this prompt into your AI agent:"
|
|
7333
|
+
});
|
|
7334
|
+
return;
|
|
7335
|
+
}
|
|
7336
|
+
const prompt = buildAgentPrompt({ context });
|
|
7337
|
+
const encodedPrompt = encodeURIComponent(prompt);
|
|
7338
|
+
const encodedPath = encodeURIComponent(context.cwd);
|
|
7339
|
+
try {
|
|
7340
|
+
switch (agent) {
|
|
7341
|
+
case "claude":
|
|
7342
|
+
await context.openUrl(
|
|
7343
|
+
`claude://code/new?q=${encodedPrompt}&folder=${encodedPath}`
|
|
7344
|
+
);
|
|
7345
|
+
break;
|
|
7346
|
+
case "codex":
|
|
7347
|
+
await context.openUrl(
|
|
7348
|
+
`codex://threads/new?prompt=${encodedPrompt}&path=${encodedPath}`
|
|
7349
|
+
);
|
|
7350
|
+
break;
|
|
7351
|
+
case "cursor":
|
|
7352
|
+
await context.runCommand({
|
|
7353
|
+
command: "cursor",
|
|
7354
|
+
args: ["."],
|
|
7355
|
+
cwd: context.cwd,
|
|
7356
|
+
capture: true
|
|
7357
|
+
});
|
|
7358
|
+
console.log(`Cursor opened in ${context.cwd}.`);
|
|
7359
|
+
break;
|
|
7360
|
+
case "vscode-copilot":
|
|
7361
|
+
await context.runCommand({
|
|
7362
|
+
command: "code",
|
|
7363
|
+
args: ["chat", "--mode", "agent", "-"],
|
|
7364
|
+
cwd: context.cwd,
|
|
7365
|
+
input: prompt
|
|
7366
|
+
});
|
|
7367
|
+
break;
|
|
7368
|
+
default: {
|
|
7369
|
+
const unsupportedAgent = agent;
|
|
7370
|
+
throw new Error(`Unsupported agent: ${unsupportedAgent}`);
|
|
7371
|
+
}
|
|
7372
|
+
}
|
|
7373
|
+
} catch {
|
|
7374
|
+
console.warn(
|
|
7375
|
+
`Could not open ${agentLabels[agent]}. Open it manually to continue.`
|
|
7376
|
+
);
|
|
7377
|
+
}
|
|
7378
|
+
printAgentPrompt({
|
|
7379
|
+
context,
|
|
7380
|
+
message: "If it didn't load correctly, paste this prompt into your agent:"
|
|
7381
|
+
});
|
|
7382
|
+
}
|
|
7383
|
+
var CONNECTIONS_URL = "https://zapier.com/app/assets/connections";
|
|
7384
|
+
var CONNECTION_DISPLAY_LIMIT = 10;
|
|
7385
|
+
async function ensureConnectionsAvailable(context) {
|
|
7386
|
+
const page = await runWithSetupLoader({
|
|
7387
|
+
promise: context.imports.listConnections({
|
|
7388
|
+
owner: "me",
|
|
7389
|
+
maxItems: CONNECTION_DISPLAY_LIMIT
|
|
7390
|
+
}),
|
|
7391
|
+
label: "Loading app connections"
|
|
7392
|
+
});
|
|
7393
|
+
if (page.data.length === 0) {
|
|
7394
|
+
console.log(
|
|
7395
|
+
`No active connections found. Connect or reconnect an app at ${CONNECTIONS_URL}, then come back and run setup again.`
|
|
7396
|
+
);
|
|
7397
|
+
throw new ZapierCliExitError(
|
|
7398
|
+
"Setup stopped before completion because no active connections are available."
|
|
7399
|
+
);
|
|
7400
|
+
}
|
|
7401
|
+
const table = new Table__default.default({
|
|
7402
|
+
head: ["App", "Connection"],
|
|
7403
|
+
style: { compact: true }
|
|
7404
|
+
});
|
|
7405
|
+
table.push(
|
|
7406
|
+
...page.data.map((connection) => [
|
|
7407
|
+
connection.slug || connection.app_key,
|
|
7408
|
+
connection.title
|
|
7409
|
+
])
|
|
7410
|
+
);
|
|
7411
|
+
console.log(
|
|
7412
|
+
`Active Zapier connections (showing up to ${CONNECTION_DISPLAY_LIMIT}):`
|
|
7413
|
+
);
|
|
7414
|
+
console.log(table.toString());
|
|
7415
|
+
}
|
|
7416
|
+
var CONNECTION_PLACEHOLDER = "__ZAPIER_SDK_SLACK_CONNECTION__";
|
|
7417
|
+
var EMAIL_PLACEHOLDER = "__ZAPIER_SDK_ACCOUNT_EMAIL__";
|
|
7418
|
+
var APP_PLACEHOLDER = "__ZAPIER_SDK_SLACK_APP__";
|
|
7419
|
+
var SLACK_SLUG = "slack";
|
|
7420
|
+
function getSlackTestPath(context) {
|
|
7421
|
+
const extension = context.projectLanguage === "typescript" ? "ts" : "mjs";
|
|
7422
|
+
return path.join("src", "sdk-demo", `zapier-slack-test.${extension}`);
|
|
7423
|
+
}
|
|
7424
|
+
function getSlackTestTemplatePath(context) {
|
|
7425
|
+
const extension = context.projectLanguage === "typescript" ? "ts" : "mjs";
|
|
7426
|
+
return path.join(TEMPLATES_DIR, "setup", `zapier-slack-test.${extension}`);
|
|
7427
|
+
}
|
|
7428
|
+
async function findSlackConnection(context) {
|
|
7429
|
+
const page = await runWithSetupLoader({
|
|
7430
|
+
promise: context.imports.listConnections({
|
|
7431
|
+
owner: "me",
|
|
7432
|
+
app: SLACK_SLUG,
|
|
7433
|
+
maxItems: 1
|
|
7434
|
+
}),
|
|
7435
|
+
label: "Looking for a Slack connection"
|
|
7436
|
+
});
|
|
7437
|
+
return page.data.find(({ slug }) => slug === SLACK_SLUG);
|
|
7438
|
+
}
|
|
7439
|
+
function toTemplateString(value) {
|
|
7440
|
+
return JSON.stringify(value).slice(1, -1);
|
|
7441
|
+
}
|
|
7442
|
+
function renderSlackTest({
|
|
7443
|
+
context,
|
|
7444
|
+
app,
|
|
7445
|
+
connection,
|
|
7446
|
+
email
|
|
7447
|
+
}) {
|
|
7448
|
+
return fs.readFileSync(getSlackTestTemplatePath(context), "utf8").replace(APP_PLACEHOLDER, () => toTemplateString(app)).replace(CONNECTION_PLACEHOLDER, () => toTemplateString(connection)).replace(EMAIL_PLACEHOLDER, () => toTemplateString(email));
|
|
7449
|
+
}
|
|
7450
|
+
function writeSlackTest({
|
|
7451
|
+
context,
|
|
7452
|
+
app,
|
|
7453
|
+
connection,
|
|
7454
|
+
email
|
|
7455
|
+
}) {
|
|
7456
|
+
const slackTestPath = getSlackTestPath(context);
|
|
7457
|
+
const path2 = path.join(context.cwd, slackTestPath);
|
|
7458
|
+
if (!fs.existsSync(path.dirname(path2))) fs.mkdirSync(path.dirname(path2), { recursive: true });
|
|
7459
|
+
fs.writeFileSync(path2, renderSlackTest({ context, app, connection, email }));
|
|
7460
|
+
console.log(`Created ${slackTestPath}.`);
|
|
7461
|
+
}
|
|
7462
|
+
async function executeSlackTest(context) {
|
|
7463
|
+
const slackTestPath = getSlackTestPath(context);
|
|
7464
|
+
if (context.projectLanguage === "javascript") {
|
|
7465
|
+
await context.runCommand({
|
|
7466
|
+
command: "node",
|
|
7467
|
+
args: [slackTestPath],
|
|
7468
|
+
cwd: context.cwd,
|
|
7469
|
+
capture: false
|
|
7470
|
+
});
|
|
7471
|
+
return;
|
|
7472
|
+
}
|
|
7473
|
+
const command = context.packageManager === "bun" ? { command: "bun", args: [] } : createLocalPackageCommand({
|
|
7474
|
+
packageManager: context.packageManager,
|
|
7475
|
+
binary: "tsx"
|
|
7476
|
+
});
|
|
7477
|
+
const args = [...command.args, slackTestPath];
|
|
7478
|
+
await context.runCommand({
|
|
7479
|
+
command: command.command,
|
|
7480
|
+
args,
|
|
7481
|
+
cwd: context.cwd,
|
|
7482
|
+
capture: false
|
|
7483
|
+
});
|
|
7484
|
+
}
|
|
7485
|
+
async function trySlackTest(context) {
|
|
7486
|
+
try {
|
|
7487
|
+
await executeSlackTest(context);
|
|
7488
|
+
return true;
|
|
7489
|
+
} catch (error) {
|
|
7490
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7491
|
+
console.warn(`Slack demo failed: ${message}. Setup will continue.`);
|
|
7492
|
+
return false;
|
|
7493
|
+
}
|
|
7494
|
+
}
|
|
7495
|
+
async function offerSlackTest(context) {
|
|
7496
|
+
if (!context.accountEmail) {
|
|
7497
|
+
console.log("No account email found; skipping the Slack demo.");
|
|
7498
|
+
return;
|
|
7499
|
+
}
|
|
7500
|
+
const slackConnection = await findSlackConnection(context);
|
|
7501
|
+
if (!slackConnection) {
|
|
7502
|
+
console.log("No active Slack connection found; skipping the Slack demo.");
|
|
7503
|
+
return;
|
|
7504
|
+
}
|
|
7505
|
+
const slackTestPath = getSlackTestPath(context);
|
|
7506
|
+
const shouldRun = await resolveSetupConfirm({
|
|
7507
|
+
answer: context.createAnswer(),
|
|
7508
|
+
controller: context.setupController,
|
|
7509
|
+
message: `Run the Slack self-DM test using ${context.accountEmail}?`,
|
|
7510
|
+
defaultValue: true
|
|
7511
|
+
});
|
|
7512
|
+
if (!shouldRun) return;
|
|
7513
|
+
const path2 = path.join(context.cwd, slackTestPath);
|
|
7514
|
+
if (fs.existsSync(path2)) {
|
|
7515
|
+
const shouldOverwrite = await resolveSetupConfirm({
|
|
7516
|
+
answer: context.createAnswer(),
|
|
7517
|
+
controller: context.setupController,
|
|
7518
|
+
message: `${slackTestPath} already exists. Is it okay to overwrite it?`,
|
|
7519
|
+
defaultValue: false
|
|
7520
|
+
});
|
|
7521
|
+
if (!shouldOverwrite) {
|
|
7522
|
+
console.log("Keeping the existing Slack test file.");
|
|
7523
|
+
const shouldRunExisting = await resolveSetupConfirm({
|
|
7524
|
+
answer: context.createAnswer(),
|
|
7525
|
+
controller: context.setupController,
|
|
7526
|
+
message: `Run the existing ${slackTestPath}?`,
|
|
7527
|
+
defaultValue: false
|
|
7528
|
+
});
|
|
7529
|
+
if (shouldRunExisting) await trySlackTest(context);
|
|
7530
|
+
return;
|
|
7531
|
+
}
|
|
7532
|
+
}
|
|
7533
|
+
let email = context.accountEmail;
|
|
7534
|
+
writeSlackTest({
|
|
7535
|
+
context,
|
|
7536
|
+
app: SLACK_SLUG,
|
|
7537
|
+
connection: slackConnection.id,
|
|
7538
|
+
email
|
|
7539
|
+
});
|
|
7540
|
+
if (await trySlackTest(context)) return;
|
|
7541
|
+
email = await resolveSetupInput({
|
|
7542
|
+
answer: context.createAnswer(),
|
|
7543
|
+
controller: context.setupController,
|
|
7544
|
+
message: "Slack email for one retry after the failed test:"
|
|
7545
|
+
});
|
|
7546
|
+
if (!email) {
|
|
7547
|
+
console.log("Skipping the Slack test.");
|
|
7548
|
+
return;
|
|
7549
|
+
}
|
|
7550
|
+
writeSlackTest({
|
|
7551
|
+
context,
|
|
7552
|
+
app: SLACK_SLUG,
|
|
7553
|
+
connection: slackConnection.id,
|
|
7554
|
+
email
|
|
7555
|
+
});
|
|
7556
|
+
await trySlackTest(context);
|
|
7557
|
+
}
|
|
7558
|
+
|
|
7559
|
+
// src/plugins/setup/skill.ts
|
|
7560
|
+
async function installOptionalSkill(context) {
|
|
7561
|
+
const shouldInstall = await resolveSetupConfirm({
|
|
7562
|
+
answer: context.createAnswer(),
|
|
7563
|
+
controller: context.setupController,
|
|
7564
|
+
message: "Install the optional Zapier SDK skill for extra agent context? This is not required for SDK setup.",
|
|
7565
|
+
defaultValue: true
|
|
7566
|
+
});
|
|
7567
|
+
if (!shouldInstall) {
|
|
7568
|
+
console.log("Skipping the optional Zapier SDK skill.");
|
|
7569
|
+
return;
|
|
7570
|
+
}
|
|
7571
|
+
const command = createPackageRunnerCommand({
|
|
7572
|
+
packageManager: context.packageManager,
|
|
7573
|
+
packageName: "skills",
|
|
7574
|
+
args: ["add", "zapier/sdk", "-y"]
|
|
7575
|
+
});
|
|
7576
|
+
try {
|
|
7577
|
+
await context.runCommand({
|
|
7578
|
+
...command,
|
|
7579
|
+
cwd: context.cwd,
|
|
7580
|
+
capture: true
|
|
7581
|
+
});
|
|
7582
|
+
} catch {
|
|
7583
|
+
console.warn(
|
|
7584
|
+
`Could not install the optional Zapier SDK skill. To install it manually, run: ${formatPackageCommand(command)}`
|
|
7585
|
+
);
|
|
7586
|
+
}
|
|
7587
|
+
}
|
|
7588
|
+
|
|
7589
|
+
// src/plugins/setup/wizard.ts
|
|
7590
|
+
var PHASE_COUNT = 6;
|
|
7591
|
+
var MINIMUM_MESSAGE_WIDTH = 20;
|
|
7592
|
+
var MAXIMUM_MESSAGE_WIDTH = 88;
|
|
7593
|
+
function showPhase({ number, title }) {
|
|
7594
|
+
console.log();
|
|
7595
|
+
console.log(chalk8__default.default.bgCyan.black.bold(` ${number}/${PHASE_COUNT} ${title} `));
|
|
7596
|
+
}
|
|
7597
|
+
function printWrapped(text) {
|
|
7598
|
+
const width = Math.max(
|
|
7599
|
+
MINIMUM_MESSAGE_WIDTH,
|
|
7600
|
+
Math.min(
|
|
7601
|
+
process.stdout.columns ?? MAXIMUM_MESSAGE_WIDTH,
|
|
7602
|
+
MAXIMUM_MESSAGE_WIDTH
|
|
7603
|
+
)
|
|
7604
|
+
);
|
|
7605
|
+
console.log(wrapAnsi4__default.default(text, width));
|
|
7606
|
+
}
|
|
7607
|
+
function showReadyMessage() {
|
|
7608
|
+
console.log();
|
|
7609
|
+
console.log(chalk8__default.default.bgGreen.black.bold(" \u2713 Zapier SDK setup complete "));
|
|
7610
|
+
console.log();
|
|
7611
|
+
printWrapped(
|
|
7612
|
+
"Use active Zapier connections to access 9,000+ app connectors without managing each app's OAuth, token refresh, or retries."
|
|
7613
|
+
);
|
|
7614
|
+
console.log();
|
|
7615
|
+
printWrapped(
|
|
7616
|
+
"To learn more about the Zapier SDK, visit https://docs.zapier.com/sdk"
|
|
7617
|
+
);
|
|
7618
|
+
console.log();
|
|
7619
|
+
}
|
|
7620
|
+
async function runWizard(context) {
|
|
7621
|
+
console.log(chalk8__default.default.bold("Zapier SDK setup"));
|
|
7622
|
+
showPhase({ number: 1, title: "Project directory" });
|
|
7623
|
+
await chooseDirectory(context);
|
|
7624
|
+
showPhase({ number: 2, title: "Node.js" });
|
|
7625
|
+
await ensureSupportedNode(context);
|
|
7626
|
+
showPhase({ number: 3, title: "Dependencies" });
|
|
7627
|
+
await prepareProject(context);
|
|
7628
|
+
await installOptionalSkill(context);
|
|
7629
|
+
showPhase({ number: 4, title: "Zapier account" });
|
|
7630
|
+
await authenticate(context);
|
|
7631
|
+
showPhase({ number: 5, title: "App connections" });
|
|
7632
|
+
await ensureConnectionsAvailable(context);
|
|
7633
|
+
showPhase({ number: 6, title: "Slack demo" });
|
|
7634
|
+
await offerSlackTest(context);
|
|
7635
|
+
showReadyMessage();
|
|
7636
|
+
console.log(chalk8__default.default.bgCyan.black.bold(" Next steps "));
|
|
7637
|
+
await openAgentHandoff(context);
|
|
7638
|
+
}
|
|
7639
|
+
|
|
7640
|
+
// src/plugins/setup/index.ts
|
|
7641
|
+
var getProfileRef = zapierSdk.declareMethod({ id: "getProfile" });
|
|
7642
|
+
var listConnectionsRef2 = zapierSdk.declareMethod({ id: "listConnections" });
|
|
7643
|
+
var loginRef = zapierSdk.declareMethod({ id: "login" });
|
|
7644
|
+
var logoutRef = zapierSdk.declareMethod({ id: "logout" });
|
|
7645
|
+
var signupRef = zapierSdk.declareMethod({ id: "signup" });
|
|
7646
|
+
var setupImports = [
|
|
7647
|
+
getProfileRef,
|
|
7648
|
+
listConnectionsRef2,
|
|
7649
|
+
loginRef,
|
|
7650
|
+
logoutRef,
|
|
7651
|
+
signupRef
|
|
7652
|
+
];
|
|
7653
|
+
var setupPlugin = zapierSdk.defineMethod({
|
|
7654
|
+
name: "setup",
|
|
7655
|
+
imports: setupImports,
|
|
7656
|
+
categories: ["utility"],
|
|
7657
|
+
supportsJsonOutput: false,
|
|
7658
|
+
inputSchema: SetupSchema,
|
|
7659
|
+
output: "raw",
|
|
7660
|
+
run: async ({ imports }) => {
|
|
7661
|
+
if (process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
|
|
7662
|
+
throw new ZapierCliExitError(
|
|
7663
|
+
"`zapier-sdk setup` requires an interactive terminal."
|
|
7664
|
+
);
|
|
7665
|
+
}
|
|
7666
|
+
await runWizard(createWizardContext({ imports }));
|
|
7667
|
+
}
|
|
7668
|
+
});
|
|
7669
|
+
var CliSkipLeaseExpireError = class extends Error {
|
|
7670
|
+
constructor() {
|
|
7671
|
+
super("user skipped (let lease expire)");
|
|
7672
|
+
this.name = "CliSkipLeaseExpireError";
|
|
7673
|
+
}
|
|
7674
|
+
};
|
|
7675
|
+
function createInteractiveCallback() {
|
|
7676
|
+
let messageNumber = 0;
|
|
7677
|
+
return async (message) => {
|
|
7678
|
+
messageNumber++;
|
|
7679
|
+
const attrs = message.message_attributes;
|
|
7680
|
+
console.log(
|
|
7681
|
+
`
|
|
7682
|
+
${chalk8__default.default.bold(`Message #${messageNumber}`)} ${chalk8__default.default.dim(message.id)} ${chalk8__default.default.dim(`(lease #${attrs.lease_count})`)}`
|
|
7683
|
+
);
|
|
7684
|
+
if (attrs.error_message) {
|
|
7685
|
+
console.log(chalk8__default.default.yellow(` upstream error: ${attrs.error_message}`));
|
|
7686
|
+
}
|
|
7687
|
+
if (attrs.possible_duplicate_data) {
|
|
7688
|
+
console.log(chalk8__default.default.yellow(" possible duplicate data"));
|
|
7689
|
+
}
|
|
7690
|
+
while (true) {
|
|
7691
|
+
let action;
|
|
7692
|
+
try {
|
|
7693
|
+
const answer = await inquirer__default.default.prompt([
|
|
7694
|
+
{
|
|
7695
|
+
type: "list",
|
|
7696
|
+
name: "action",
|
|
7697
|
+
message: "Action?",
|
|
7698
|
+
choices: [
|
|
7699
|
+
{ name: "Ack (remove from inbox)", value: "ack" },
|
|
7700
|
+
{
|
|
7701
|
+
name: "Skip (release after draining)",
|
|
7702
|
+
value: "skip-release"
|
|
7703
|
+
},
|
|
7704
|
+
{ name: "Skip (let lease expire)", value: "skip-expire" },
|
|
7705
|
+
{ name: "View payload", value: "view" },
|
|
7706
|
+
{ name: "Quit", value: "quit" }
|
|
7707
|
+
]
|
|
7708
|
+
}
|
|
7709
|
+
]);
|
|
7710
|
+
action = answer.action;
|
|
7711
|
+
} catch (error) {
|
|
7712
|
+
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
7713
|
+
throw new zapierSdk.ZapierAbortDrainSignal("user pressed Ctrl-C");
|
|
7714
|
+
}
|
|
7715
|
+
throw error;
|
|
7716
|
+
}
|
|
7717
|
+
if (action === "view") {
|
|
7718
|
+
console.log(chalk8__default.default.dim(JSON.stringify(message.payload, null, 2)));
|
|
7719
|
+
continue;
|
|
7720
|
+
}
|
|
7721
|
+
if (action === "ack") {
|
|
7722
|
+
return;
|
|
7723
|
+
}
|
|
7724
|
+
if (action === "skip-release") {
|
|
7725
|
+
throw new zapierSdk.ZapierReleaseTriggerMessageSignal("user skipped (release)");
|
|
7726
|
+
}
|
|
7727
|
+
if (action === "skip-expire") {
|
|
7728
|
+
throw new CliSkipLeaseExpireError();
|
|
7729
|
+
}
|
|
7730
|
+
if (action === "quit") {
|
|
7731
|
+
throw new zapierSdk.ZapierAbortDrainSignal("user requested quit");
|
|
7732
|
+
}
|
|
7733
|
+
}
|
|
7734
|
+
};
|
|
7735
|
+
}
|
|
7736
|
+
function createNdjsonCallback() {
|
|
7737
|
+
return (message) => new Promise((resolve4, reject) => {
|
|
7738
|
+
process.stdout.write(JSON.stringify(message) + "\n", (err) => {
|
|
7739
|
+
if (err) reject(err);
|
|
7740
|
+
else resolve4();
|
|
7741
|
+
});
|
|
7742
|
+
});
|
|
7743
|
+
}
|
|
7744
|
+
function runSubprocess(options) {
|
|
7745
|
+
const { command, args, shell, label, message, signal } = options;
|
|
7746
|
+
return new Promise((resolve4, reject) => {
|
|
7747
|
+
const child = child_process.spawn(command, args, {
|
|
7748
|
+
shell,
|
|
7749
|
+
stdio: ["pipe", "inherit", "inherit"]
|
|
7750
|
+
});
|
|
7751
|
+
let abortListener;
|
|
7752
|
+
if (signal) {
|
|
7753
|
+
if (signal.aborted) {
|
|
6329
7754
|
child.kill();
|
|
6330
7755
|
} else {
|
|
6331
7756
|
abortListener = () => {
|
|
@@ -6745,7 +8170,7 @@ function renderDeprecationNotices() {
|
|
|
6745
8170
|
function buildBoxLines(message) {
|
|
6746
8171
|
const innerWidth = BOX_WIDTH - 4;
|
|
6747
8172
|
const pad = (line) => `\u2502 ${line.padEnd(innerWidth)} \u2502`;
|
|
6748
|
-
const wrapped =
|
|
8173
|
+
const wrapped = wrapAnsi4__default.default(message, innerWidth, { hard: true }).split("\n");
|
|
6749
8174
|
return [
|
|
6750
8175
|
`\u256D${"\u2500".repeat(BOX_WIDTH - 2)}\u256E`,
|
|
6751
8176
|
pad(BOX_TITLE),
|
|
@@ -6758,7 +8183,7 @@ function buildBoxLines(message) {
|
|
|
6758
8183
|
// package.json with { type: 'json' }
|
|
6759
8184
|
var package_default2 = {
|
|
6760
8185
|
name: "@zapier/zapier-sdk-cli",
|
|
6761
|
-
version: "0.
|
|
8186
|
+
version: "0.69.0"};
|
|
6762
8187
|
|
|
6763
8188
|
// src/sdk.ts
|
|
6764
8189
|
var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
|
|
@@ -6798,6 +8223,7 @@ var cliSdkPlugin = zapierSdk.definePlugin({
|
|
|
6798
8223
|
mcpPlugin,
|
|
6799
8224
|
getLoginConfigPathPlugin,
|
|
6800
8225
|
initPlugin,
|
|
8226
|
+
setupPlugin,
|
|
6801
8227
|
bundleCodePlugin,
|
|
6802
8228
|
feedbackPlugin,
|
|
6803
8229
|
curlPlugin,
|
|
@@ -6866,6 +8292,7 @@ function createZapierCliSdk2(options = {}) {
|
|
|
6866
8292
|
mcpPlugin,
|
|
6867
8293
|
getLoginConfigPathPlugin,
|
|
6868
8294
|
initPlugin,
|
|
8295
|
+
setupPlugin,
|
|
6869
8296
|
bundleCodePlugin,
|
|
6870
8297
|
feedbackPlugin,
|
|
6871
8298
|
curlPlugin,
|
|
@@ -6950,163 +8377,6 @@ function readEnvSpecs() {
|
|
|
6950
8377
|
if (!raw) return [];
|
|
6951
8378
|
return raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
6952
8379
|
}
|
|
6953
|
-
var ONE_DAY_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
6954
|
-
var CACHE_RESET_INTERVAL_MILLISECONDS = (() => {
|
|
6955
|
-
const {
|
|
6956
|
-
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS,
|
|
6957
|
-
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS
|
|
6958
|
-
} = process.env;
|
|
6959
|
-
let intervalMs;
|
|
6960
|
-
if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS !== void 0) {
|
|
6961
|
-
const seconds = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS);
|
|
6962
|
-
intervalMs = isNaN(seconds) ? NaN : seconds * 1e3;
|
|
6963
|
-
} else if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS !== void 0) {
|
|
6964
|
-
intervalMs = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
|
|
6965
|
-
} else {
|
|
6966
|
-
intervalMs = ONE_DAY_MILLISECONDS;
|
|
6967
|
-
}
|
|
6968
|
-
if (isNaN(intervalMs) || intervalMs < 0) {
|
|
6969
|
-
return -1;
|
|
6970
|
-
}
|
|
6971
|
-
return intervalMs;
|
|
6972
|
-
})();
|
|
6973
|
-
function getVersionCache() {
|
|
6974
|
-
try {
|
|
6975
|
-
const cache = getConfig().get("version_cache");
|
|
6976
|
-
const now = Date.now();
|
|
6977
|
-
if (!cache || !cache.last_reset_timestamp || now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MILLISECONDS) {
|
|
6978
|
-
const newCache = {
|
|
6979
|
-
last_reset_timestamp: now,
|
|
6980
|
-
packages: {}
|
|
6981
|
-
};
|
|
6982
|
-
getConfig().set("version_cache", newCache);
|
|
6983
|
-
return newCache;
|
|
6984
|
-
}
|
|
6985
|
-
return cache;
|
|
6986
|
-
} catch (error) {
|
|
6987
|
-
log_default.debug(`Failed to read version cache: ${error}`);
|
|
6988
|
-
return {
|
|
6989
|
-
last_reset_timestamp: Date.now(),
|
|
6990
|
-
packages: {}
|
|
6991
|
-
};
|
|
6992
|
-
}
|
|
6993
|
-
}
|
|
6994
|
-
function setCachedPackageInfo(packageName, version, info) {
|
|
6995
|
-
try {
|
|
6996
|
-
const cache = getVersionCache();
|
|
6997
|
-
if (!cache.packages[packageName]) {
|
|
6998
|
-
cache.packages[packageName] = {};
|
|
6999
|
-
}
|
|
7000
|
-
cache.packages[packageName][version] = info;
|
|
7001
|
-
getConfig().set("version_cache", cache);
|
|
7002
|
-
} catch (error) {
|
|
7003
|
-
log_default.debug(`Failed to cache package info: ${error}`);
|
|
7004
|
-
}
|
|
7005
|
-
}
|
|
7006
|
-
function getCachedPackageInfo(packageName, version) {
|
|
7007
|
-
try {
|
|
7008
|
-
const cache = getVersionCache();
|
|
7009
|
-
return cache.packages[packageName]?.[version];
|
|
7010
|
-
} catch (error) {
|
|
7011
|
-
log_default.debug(`Failed to get cached package info: ${error}`);
|
|
7012
|
-
return void 0;
|
|
7013
|
-
}
|
|
7014
|
-
}
|
|
7015
|
-
async function fetchCachedPackageInfo(packageName, version) {
|
|
7016
|
-
const cacheKey = version || "latest";
|
|
7017
|
-
let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
|
|
7018
|
-
if (cachedInfo) {
|
|
7019
|
-
return cachedInfo;
|
|
7020
|
-
}
|
|
7021
|
-
const packageInfo = await packageJsonLib__default.default(packageName, {
|
|
7022
|
-
version,
|
|
7023
|
-
fullMetadata: true
|
|
7024
|
-
});
|
|
7025
|
-
const info = {
|
|
7026
|
-
version: packageInfo.version,
|
|
7027
|
-
deprecated: packageInfo.deprecated,
|
|
7028
|
-
fetched_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
7029
|
-
};
|
|
7030
|
-
setCachedPackageInfo(packageName, cacheKey, info);
|
|
7031
|
-
return info;
|
|
7032
|
-
}
|
|
7033
|
-
async function checkForUpdates({
|
|
7034
|
-
packageName,
|
|
7035
|
-
currentVersion
|
|
7036
|
-
}) {
|
|
7037
|
-
try {
|
|
7038
|
-
const latestPackageInfo = await fetchCachedPackageInfo(packageName);
|
|
7039
|
-
const latestVersion = latestPackageInfo.version;
|
|
7040
|
-
const hasUpdate = semver__default.default.gt(latestVersion, currentVersion);
|
|
7041
|
-
let currentPackageInfo;
|
|
7042
|
-
try {
|
|
7043
|
-
currentPackageInfo = await fetchCachedPackageInfo(
|
|
7044
|
-
packageName,
|
|
7045
|
-
currentVersion
|
|
7046
|
-
);
|
|
7047
|
-
} catch (error) {
|
|
7048
|
-
if (!(error instanceof packageJsonLib.VersionNotFoundError)) {
|
|
7049
|
-
log_default.debug(`Failed to check deprecation for current version: ${error}`);
|
|
7050
|
-
}
|
|
7051
|
-
currentPackageInfo = latestPackageInfo;
|
|
7052
|
-
}
|
|
7053
|
-
const isDeprecated = Boolean(currentPackageInfo.deprecated);
|
|
7054
|
-
const deprecationMessage = isDeprecated ? String(currentPackageInfo.deprecated) : void 0;
|
|
7055
|
-
return {
|
|
7056
|
-
hasUpdate,
|
|
7057
|
-
latestVersion,
|
|
7058
|
-
currentVersion,
|
|
7059
|
-
isDeprecated,
|
|
7060
|
-
deprecationMessage
|
|
7061
|
-
};
|
|
7062
|
-
} catch (error) {
|
|
7063
|
-
log_default.debug(`Failed to check for updates: ${error}`);
|
|
7064
|
-
return {
|
|
7065
|
-
hasUpdate: false,
|
|
7066
|
-
currentVersion,
|
|
7067
|
-
isDeprecated: false
|
|
7068
|
-
};
|
|
7069
|
-
}
|
|
7070
|
-
}
|
|
7071
|
-
function displayUpdateNotification(versionInfo, packageName) {
|
|
7072
|
-
if (versionInfo.isDeprecated) {
|
|
7073
|
-
console.error();
|
|
7074
|
-
console.error(
|
|
7075
|
-
chalk8__default.default.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8__default.default.red(
|
|
7076
|
-
` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
|
|
7077
|
-
)
|
|
7078
|
-
);
|
|
7079
|
-
if (versionInfo.deprecationMessage) {
|
|
7080
|
-
console.error(chalk8__default.default.red(` ${versionInfo.deprecationMessage}`));
|
|
7081
|
-
}
|
|
7082
|
-
console.error(chalk8__default.default.red(` Please update to the latest version.`));
|
|
7083
|
-
console.error();
|
|
7084
|
-
}
|
|
7085
|
-
if (versionInfo.hasUpdate) {
|
|
7086
|
-
console.error();
|
|
7087
|
-
console.error(
|
|
7088
|
-
chalk8__default.default.yellow.bold("\u{1F4E6} Update available!") + chalk8__default.default.yellow(
|
|
7089
|
-
` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
|
|
7090
|
-
)
|
|
7091
|
-
);
|
|
7092
|
-
console.error(
|
|
7093
|
-
chalk8__default.default.yellow(
|
|
7094
|
-
` Run ${chalk8__default.default.bold(getUpdateCommand(packageName))} to update.`
|
|
7095
|
-
)
|
|
7096
|
-
);
|
|
7097
|
-
console.error();
|
|
7098
|
-
}
|
|
7099
|
-
}
|
|
7100
|
-
async function checkAndNotifyUpdates({
|
|
7101
|
-
packageName,
|
|
7102
|
-
currentVersion
|
|
7103
|
-
}) {
|
|
7104
|
-
if (CACHE_RESET_INTERVAL_MILLISECONDS < 0) {
|
|
7105
|
-
return;
|
|
7106
|
-
}
|
|
7107
|
-
const versionInfo = await checkForUpdates({ packageName, currentVersion });
|
|
7108
|
-
displayUpdateNotification(versionInfo, packageName);
|
|
7109
|
-
}
|
|
7110
8380
|
var EMOJI_PRESENTATION_PATTERN = /\p{Emoji_Presentation}/u;
|
|
7111
8381
|
var WIDE_CODE_POINT_RANGES = [
|
|
7112
8382
|
[4352, 4447],
|
|
@@ -7210,7 +8480,7 @@ function buildFrameLines(state, frameIndex) {
|
|
|
7210
8480
|
const hasMessages = recentMessages.length > 0;
|
|
7211
8481
|
recentMessages.forEach((message, index) => {
|
|
7212
8482
|
const dimmed = Boolean(state.verdict) || index < recentMessages.length - 1;
|
|
7213
|
-
const segments =
|
|
8483
|
+
const segments = wrapAnsi4__default.default(message, bodyTextWidth, { hard: true }).split(
|
|
7214
8484
|
"\n"
|
|
7215
8485
|
);
|
|
7216
8486
|
segments.forEach((segment, segmentIndex) => {
|
|
@@ -7221,7 +8491,7 @@ function buildFrameLines(state, frameIndex) {
|
|
|
7221
8491
|
if (state.streamError) {
|
|
7222
8492
|
if (hasMessages || !state.verdict) content.push("");
|
|
7223
8493
|
content.push(chalk8__default.default.bold.red("Approval stream error"));
|
|
7224
|
-
for (const segment of
|
|
8494
|
+
for (const segment of wrapAnsi4__default.default(state.streamError, bodyTextWidth, {
|
|
7225
8495
|
hard: true
|
|
7226
8496
|
}).split("\n")) {
|
|
7227
8497
|
content.push(` ${segment}`);
|
|
@@ -7233,7 +8503,7 @@ function buildFrameLines(state, frameIndex) {
|
|
|
7233
8503
|
chalk8__default.default.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
|
|
7234
8504
|
);
|
|
7235
8505
|
if (state.verdict.reason) {
|
|
7236
|
-
for (const segment of
|
|
8506
|
+
for (const segment of wrapAnsi4__default.default(state.verdict.reason, bodyTextWidth, {
|
|
7237
8507
|
hard: true
|
|
7238
8508
|
}).split("\n")) {
|
|
7239
8509
|
content.push(` ${segment}`);
|