@zapier/zapier-sdk-cli 0.68.0 → 0.70.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 +28 -0
- package/README.md +26 -7
- package/dist/cli.cjs +1719 -293
- package/dist/cli.mjs +1721 -297
- 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 +1804 -33
- package/dist/index.d.mts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.mjs +1800 -35
- 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.mjs
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Command, CommanderError, Option } from 'commander';
|
|
3
|
-
import { getConnectionPlugin, defineMethod, apiPluginRef, resolveCredentialsPluginRef, eventEmissionPluginRef, sdkOptionsPluginRef, declareOptionalProperty, OutputPropertySchema, ZapierBundleError, isZapierBundleError, DEFAULT_CONFIG_PATH, declareMethod, ZapierValidationError, isZapierValidationError, ZapierUnknownError, manifestPluginRef, defineResolver, isPermanentHttpError, isZapierAuthenticationError, ZapierApiError, defineMethodOverride, zapierCoreOptions, injectCliLogin, definePlugin, omitExports, zapierSdkPlugin, BaseSdkOptionsSchema, disposeSdk, invalidateCachedToken, batch, toSnakeCase, ZapierError, isZapierReleaseTriggerMessageSignal, createSdk as createSdk$1, CORE_OPTIONS_ID as CORE_OPTIONS_ID$1, SDK_OPTIONS_ID as SDK_OPTIONS_ID$1, addPlugin as addPlugin$1, getOrCreateApiClient, isCredentialsObject, ZapierAbortDrainSignal, ZapierReleaseTriggerMessageSignal, buildApplicationLifecycleEvent, AuthMechanism, DEPRECATION_NOTICE_EVENT, runWithCallerContext,
|
|
2
|
+
import { Command, CommanderError, Option, InvalidArgumentError } from 'commander';
|
|
3
|
+
import { getConnectionPlugin, defineMethod, apiPluginRef, resolveCredentialsPluginRef, eventEmissionPluginRef, sdkOptionsPluginRef, declareOptionalProperty, OutputPropertySchema, ZapierBundleError, isZapierBundleError, DEFAULT_CONFIG_PATH, declareMethod, ZapierValidationError, isZapierValidationError, ZapierUnknownError, manifestPluginRef, defineResolver, isPermanentHttpError, isZapierAuthenticationError, ZapierApiError, defineMethodOverride, zapierCoreOptions, injectCliLogin, definePlugin, omitExports, zapierSdkPlugin, BaseSdkOptionsSchema, disposeSdk, invalidateCachedToken, batch, toSnakeCase, ZapierError, isZapierReleaseTriggerMessageSignal, createSdk as createSdk$1, CORE_OPTIONS_ID as CORE_OPTIONS_ID$1, SDK_OPTIONS_ID as SDK_OPTIONS_ID$1, addPlugin as addPlugin$1, getOrCreateApiClient, isCredentialsObject, getRegistryPlugin, createController, ZapierAbortDrainSignal, ZapierReleaseTriggerMessageSignal, buildApplicationLifecycleEvent, AuthMechanism, DEPRECATION_NOTICE_EVENT, runWithCallerContext, isCoreCancelledSignal, getNegatable, isPositional, resolvePlugin, isZapierError, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, isZapierConflictError, getReleaseId, getCurrentTimestamp, generateEventId, isZapierApprovalError, ZapierAuthenticationError } from '@zapier/zapier-sdk';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
6
|
import chalk8 from 'chalk';
|
|
7
7
|
import { makeTheme, createPrompt, useState, usePrefix, useMemo, useEffect, useKeypress, isEnterKey, isTabKey, isUpKey, isDownKey, usePagination, Separator } from '@inquirer/core';
|
|
8
8
|
import ora from 'ora';
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import { promises, createWriteStream, existsSync, readdirSync, readFileSync, rmSync, mkdirSync, writeFileSync, copyFileSync } from 'fs';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import { resolve, join, dirname, basename, relative, extname } from 'path';
|
|
13
|
+
import isInstalledGlobally from 'is-installed-globally';
|
|
9
14
|
import util, { stripVTControlCharacters } from 'util';
|
|
10
|
-
import
|
|
15
|
+
import wrapAnsi4 from 'wrap-ansi';
|
|
11
16
|
import * as jwt from 'jsonwebtoken';
|
|
12
17
|
import { deletePassword, getKeyring, setPassword, getPassword } from 'cross-keychain';
|
|
13
18
|
import Conf from 'conf';
|
|
14
|
-
import * as fs from 'fs';
|
|
15
|
-
import { promises, createWriteStream, existsSync, readdirSync, rmSync, mkdirSync, writeFileSync, copyFileSync, readFileSync } from 'fs';
|
|
16
19
|
import crypto, { createHash } from 'crypto';
|
|
17
|
-
import * as path from 'path';
|
|
18
|
-
import { resolve, join, dirname, basename, relative, extname } from 'path';
|
|
19
20
|
import * as lockfile from 'proper-lockfile';
|
|
20
21
|
import { hostname } from 'os';
|
|
21
22
|
import express from 'express';
|
|
@@ -26,13 +27,14 @@ import { startMcpServer } from '@zapier/zapier-sdk-mcp';
|
|
|
26
27
|
import { buildSync } from 'esbuild';
|
|
27
28
|
import { mkdir, writeFile, access } from 'fs/promises';
|
|
28
29
|
import * as ts from 'typescript';
|
|
29
|
-
import isInstalledGlobally from 'is-installed-globally';
|
|
30
30
|
import { execSync, spawn } from 'child_process';
|
|
31
31
|
import Handlebars from 'handlebars';
|
|
32
32
|
import { fileURLToPath } from 'url';
|
|
33
|
-
import { triggerInboxResolver, DrainTriggerInboxSchema, WatchTriggerInboxSchema, injectCliLogin as injectCliLogin$1, definePlugin as definePlugin$1, omitExports as omitExports$1, zapierExperimentalSdkPlugin, createSdk, CORE_OPTIONS_ID, SDK_OPTIONS_ID, addPlugin } from '@zapier/zapier-sdk/experimental';
|
|
34
33
|
import packageJsonLib, { VersionNotFoundError } from 'package-json';
|
|
35
34
|
import semver from 'semver';
|
|
35
|
+
import crossSpawn from 'cross-spawn';
|
|
36
|
+
import Table from 'cli-table3';
|
|
37
|
+
import { triggerInboxResolver, DrainTriggerInboxSchema, WatchTriggerInboxSchema, injectCliLogin as injectCliLogin$1, definePlugin as definePlugin$1, omitExports as omitExports$1, zapierExperimentalSdkPlugin, createSdk, CORE_OPTIONS_ID, SDK_OPTIONS_ID, addPlugin } from '@zapier/zapier-sdk/experimental';
|
|
36
38
|
import * as readline from 'readline';
|
|
37
39
|
|
|
38
40
|
var __defProp = Object.defineProperty;
|
|
@@ -194,11 +196,21 @@ async function promptText({
|
|
|
194
196
|
password
|
|
195
197
|
}) {
|
|
196
198
|
const { value } = await inquirer.prompt([
|
|
197
|
-
{
|
|
199
|
+
{
|
|
200
|
+
type: password ? "password" : "input",
|
|
201
|
+
name: "value",
|
|
202
|
+
message,
|
|
203
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
204
|
+
}
|
|
198
205
|
]);
|
|
199
206
|
return value;
|
|
200
207
|
}
|
|
201
208
|
var display = (c) => c.hint ? `${c.label} ${chalk8.dim(`(${c.hint})`)}` : c.label;
|
|
209
|
+
var HIGH_CONTRAST_PROMPT_THEME = {
|
|
210
|
+
style: {
|
|
211
|
+
answer: (text) => chalk8.inverse.bold(` ${text} `)
|
|
212
|
+
}
|
|
213
|
+
};
|
|
202
214
|
function buildSelectRows(question, term) {
|
|
203
215
|
const row = (name, action) => ({
|
|
204
216
|
name,
|
|
@@ -265,9 +277,39 @@ function foldPage(acc, question, field) {
|
|
|
265
277
|
checked: []
|
|
266
278
|
};
|
|
267
279
|
}
|
|
268
|
-
async function answerSelect(question, field, box, failed
|
|
280
|
+
async function answerSelect(question, field, box, failed, mode) {
|
|
269
281
|
const acc = failed ? void 0 : box.acc = foldPage(box.acc, question, field);
|
|
270
282
|
const view = acc ? { ...question, choices: acc.choices } : question;
|
|
283
|
+
const isClosedListPrompt = mode === "closed-list" && !failed && !view.multiple;
|
|
284
|
+
const booleanValues = view.choices.map(({ value: value2 }) => value2);
|
|
285
|
+
if (isClosedListPrompt && booleanValues.length === 2 && booleanValues.includes("true") && booleanValues.includes("false")) {
|
|
286
|
+
const { value: value2 } = await inquirer.prompt([
|
|
287
|
+
{
|
|
288
|
+
type: "confirm",
|
|
289
|
+
name: "value",
|
|
290
|
+
message: view.message,
|
|
291
|
+
default: booleanValues[0] === "true",
|
|
292
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
293
|
+
}
|
|
294
|
+
]);
|
|
295
|
+
return { type: "choose", value: String(value2) };
|
|
296
|
+
}
|
|
297
|
+
if (isClosedListPrompt && view.choices.length > 0 && !offers(view, "search") && !offers(view, "next_page") && !offers(view, "retry")) {
|
|
298
|
+
const choices = view.choices.map((choice) => ({
|
|
299
|
+
name: display(choice),
|
|
300
|
+
value: choice.value
|
|
301
|
+
}));
|
|
302
|
+
const { value: value2 } = await inquirer.prompt([
|
|
303
|
+
{
|
|
304
|
+
type: "list",
|
|
305
|
+
name: "value",
|
|
306
|
+
message: view.message,
|
|
307
|
+
choices,
|
|
308
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
309
|
+
}
|
|
310
|
+
]);
|
|
311
|
+
return { type: "choose", value: value2 };
|
|
312
|
+
}
|
|
271
313
|
if (question.multiple && acc) {
|
|
272
314
|
if (acc.newStart > 0 && process.stdout.isTTY) {
|
|
273
315
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
@@ -291,7 +333,13 @@ async function answerSelect(question, field, box, failed = false) {
|
|
|
291
333
|
}))
|
|
292
334
|
];
|
|
293
335
|
const { values } = await inquirer.prompt([
|
|
294
|
-
{
|
|
336
|
+
{
|
|
337
|
+
type: "checkbox",
|
|
338
|
+
name: "values",
|
|
339
|
+
message: question.message,
|
|
340
|
+
choices,
|
|
341
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
342
|
+
}
|
|
295
343
|
]);
|
|
296
344
|
const selected = values;
|
|
297
345
|
const picked = selected.filter((v) => !isActionRow(v));
|
|
@@ -386,7 +434,8 @@ async function answerCollection(question) {
|
|
|
386
434
|
type: "confirm",
|
|
387
435
|
name: "again",
|
|
388
436
|
message: question.message,
|
|
389
|
-
default: false
|
|
437
|
+
default: false,
|
|
438
|
+
theme: HIGH_CONTRAST_PROMPT_THEME
|
|
390
439
|
}
|
|
391
440
|
]);
|
|
392
441
|
return again ? { type: "add" } : { type: "done" };
|
|
@@ -401,22 +450,37 @@ function withEngineSpinner(answer, spinner) {
|
|
|
401
450
|
}
|
|
402
451
|
};
|
|
403
452
|
}
|
|
404
|
-
function createCliAnswer(
|
|
453
|
+
function createCliAnswer({
|
|
454
|
+
mode = "search"
|
|
455
|
+
} = {}) {
|
|
405
456
|
const box = {};
|
|
406
|
-
return ({ result }) => {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
457
|
+
return async ({ result }) => {
|
|
458
|
+
try {
|
|
459
|
+
if (result.error !== void 0) {
|
|
460
|
+
const message = typeof result.error === "string" ? result.error : result.error.message;
|
|
461
|
+
console.log(chalk8.yellow(`! ${message}`));
|
|
462
|
+
}
|
|
463
|
+
const question = result.question;
|
|
464
|
+
const field = question.path.length ? question.path.join(".") : "value";
|
|
465
|
+
switch (question.type) {
|
|
466
|
+
case "select":
|
|
467
|
+
return await answerSelect(
|
|
468
|
+
question,
|
|
469
|
+
field,
|
|
470
|
+
box,
|
|
471
|
+
result.status === "failed",
|
|
472
|
+
mode
|
|
473
|
+
);
|
|
474
|
+
case "input":
|
|
475
|
+
return await answerInput(question);
|
|
476
|
+
case "collection":
|
|
477
|
+
return await answerCollection(question);
|
|
478
|
+
}
|
|
479
|
+
} catch (error) {
|
|
480
|
+
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
481
|
+
return { type: "cancel" };
|
|
482
|
+
}
|
|
483
|
+
throw error;
|
|
420
484
|
}
|
|
421
485
|
};
|
|
422
486
|
}
|
|
@@ -494,7 +558,86 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
494
558
|
|
|
495
559
|
// package.json
|
|
496
560
|
var package_default = {
|
|
497
|
-
version: "0.
|
|
561
|
+
version: "0.70.0"};
|
|
562
|
+
var PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
|
|
563
|
+
var LOCKFILES = [
|
|
564
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
565
|
+
["yarn.lock", "yarn"],
|
|
566
|
+
["bun.lock", "bun"],
|
|
567
|
+
["bun.lockb", "bun"],
|
|
568
|
+
["package-lock.json", "npm"]
|
|
569
|
+
];
|
|
570
|
+
function readDeclaredPackageManager(cwd) {
|
|
571
|
+
try {
|
|
572
|
+
const manifest = JSON.parse(
|
|
573
|
+
readFileSync(join(cwd, "package.json"), "utf8")
|
|
574
|
+
);
|
|
575
|
+
if (typeof manifest !== "object" || manifest === null || !("packageManager" in manifest) || typeof manifest.packageManager !== "string") {
|
|
576
|
+
return void 0;
|
|
577
|
+
}
|
|
578
|
+
const [name] = manifest.packageManager.split("@", 1);
|
|
579
|
+
return PACKAGE_MANAGERS.find((packageManager) => packageManager === name);
|
|
580
|
+
} catch {
|
|
581
|
+
return void 0;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
function detectPackageManager(cwd = process.cwd()) {
|
|
585
|
+
const lockfileManagers = new Set(
|
|
586
|
+
LOCKFILES.filter(([file]) => existsSync(join(cwd, file))).map(
|
|
587
|
+
([, packageManager]) => packageManager
|
|
588
|
+
)
|
|
589
|
+
);
|
|
590
|
+
if (lockfileManagers.size === 1) {
|
|
591
|
+
return { name: [...lockfileManagers][0], source: "lockfile" };
|
|
592
|
+
}
|
|
593
|
+
const declaredPackageManager = readDeclaredPackageManager(cwd);
|
|
594
|
+
if (declaredPackageManager) {
|
|
595
|
+
return { name: declaredPackageManager, source: "package-json" };
|
|
596
|
+
}
|
|
597
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
598
|
+
if (userAgent) {
|
|
599
|
+
if (userAgent.includes("yarn")) {
|
|
600
|
+
return { name: "yarn", source: "runtime" };
|
|
601
|
+
}
|
|
602
|
+
if (userAgent.includes("pnpm")) {
|
|
603
|
+
return { name: "pnpm", source: "runtime" };
|
|
604
|
+
}
|
|
605
|
+
if (userAgent.includes("bun")) {
|
|
606
|
+
return { name: "bun", source: "runtime" };
|
|
607
|
+
}
|
|
608
|
+
if (userAgent.includes("npm")) {
|
|
609
|
+
return { name: "npm", source: "runtime" };
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return { name: "npm", source: "fallback" };
|
|
613
|
+
}
|
|
614
|
+
function getUpdateCommand(packageName) {
|
|
615
|
+
const pm = detectPackageManager();
|
|
616
|
+
const isGlobal = isInstalledGlobally;
|
|
617
|
+
if (isGlobal) {
|
|
618
|
+
switch (pm.name) {
|
|
619
|
+
case "yarn":
|
|
620
|
+
return `yarn global upgrade ${packageName}@latest`;
|
|
621
|
+
case "pnpm":
|
|
622
|
+
return `pnpm update -g ${packageName}@latest`;
|
|
623
|
+
case "bun":
|
|
624
|
+
return `bun update -g ${packageName}@latest`;
|
|
625
|
+
default:
|
|
626
|
+
return `npm install -g ${packageName}@latest`;
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
switch (pm.name) {
|
|
630
|
+
case "yarn":
|
|
631
|
+
return `yarn upgrade ${packageName}@latest`;
|
|
632
|
+
case "pnpm":
|
|
633
|
+
return `pnpm update ${packageName}@latest`;
|
|
634
|
+
case "bun":
|
|
635
|
+
return `bun update ${packageName}@latest`;
|
|
636
|
+
default:
|
|
637
|
+
return `npm install ${packageName}@latest`;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
498
641
|
|
|
499
642
|
// src/telemetry/builders.ts
|
|
500
643
|
function createCliBaseEvent(context = {}) {
|
|
@@ -542,8 +685,7 @@ function buildCliCommandExecutedEvent({
|
|
|
542
685
|
ci_platform: getCiPlatform(),
|
|
543
686
|
...getTtyContext(),
|
|
544
687
|
agent: getAgent(),
|
|
545
|
-
package_manager: data.package_manager ??
|
|
546
|
-
// Default based on project setup
|
|
688
|
+
package_manager: data.package_manager ?? detectPackageManager(process.cwd()).name,
|
|
547
689
|
made_network_requests: data.made_network_requests ?? null,
|
|
548
690
|
files_modified_count: data.files_modified_count ?? null,
|
|
549
691
|
files_created_count: data.files_created_count ?? null,
|
|
@@ -637,7 +779,7 @@ var DETAIL_INDENT = " ";
|
|
|
637
779
|
var DETAIL_MAX_LINES = 5;
|
|
638
780
|
function formatDetailText(text, indent = DETAIL_INDENT) {
|
|
639
781
|
const columns = Math.max((process.stdout.columns || 80) - indent.length, 40);
|
|
640
|
-
const wrapped =
|
|
782
|
+
const wrapped = wrapAnsi4(text, columns, { hard: true, trim: false });
|
|
641
783
|
const lines = wrapped.split("\n");
|
|
642
784
|
if (lines.length <= DETAIL_MAX_LINES) {
|
|
643
785
|
return lines.join("\n" + indent);
|
|
@@ -680,6 +822,9 @@ function formatItemsGeneric(items, startingNumber = 0) {
|
|
|
680
822
|
function toKebabCase(str) {
|
|
681
823
|
return str.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
|
|
682
824
|
}
|
|
825
|
+
function kebabToCamelCase(str) {
|
|
826
|
+
return str.replace(/-([a-z])/g, (match) => match[1].toUpperCase());
|
|
827
|
+
}
|
|
683
828
|
function formatMissingParamsError(error) {
|
|
684
829
|
return [
|
|
685
830
|
"Missing required parameters:",
|
|
@@ -1075,6 +1220,18 @@ function resolveOutputMode({
|
|
|
1075
1220
|
if (hasUserSpecifiedMaxItems) return "collect";
|
|
1076
1221
|
return "paginate";
|
|
1077
1222
|
}
|
|
1223
|
+
function negationKebabName(param) {
|
|
1224
|
+
if (param.negatable === true) return `no-${toKebabCase(param.name)}`;
|
|
1225
|
+
if (typeof param.negatable === "string") return toKebabCase(param.negatable);
|
|
1226
|
+
return void 0;
|
|
1227
|
+
}
|
|
1228
|
+
function antonymAttributeName(param) {
|
|
1229
|
+
const negationKebab = negationKebabName(param);
|
|
1230
|
+
if (negationKebab === void 0 || negationKebab.startsWith("no-")) {
|
|
1231
|
+
return void 0;
|
|
1232
|
+
}
|
|
1233
|
+
return kebabToCamelCase(negationKebab);
|
|
1234
|
+
}
|
|
1078
1235
|
function takesPositionalSlot(param) {
|
|
1079
1236
|
return param.required || !!param.isPositional && !param.isDeprecated && !param.isAlias;
|
|
1080
1237
|
}
|
|
@@ -1187,7 +1344,8 @@ function analyzeZodField(name, schema) {
|
|
|
1187
1344
|
isPositional: isPositional(schema),
|
|
1188
1345
|
elementType,
|
|
1189
1346
|
deprecationMessage,
|
|
1190
|
-
isDeprecated
|
|
1347
|
+
isDeprecated,
|
|
1348
|
+
negatable: getNegatable(schema)
|
|
1191
1349
|
};
|
|
1192
1350
|
}
|
|
1193
1351
|
function positionalProjection(schema, positional) {
|
|
@@ -1572,15 +1730,25 @@ function collect(value, previous = []) {
|
|
|
1572
1730
|
return previous;
|
|
1573
1731
|
}
|
|
1574
1732
|
function addCommand(program2, commandName, config2) {
|
|
1575
|
-
const command = program2.command(commandName, { hidden: config2.hidden ?? false }).description(config2.description);
|
|
1733
|
+
const command = program2.command(commandName, { hidden: config2.hidden ?? false }).description(config2.description).allowExcessArguments(false);
|
|
1576
1734
|
let hasPositionalArray = false;
|
|
1735
|
+
const lastPositionalParamName = [...config2.parameters].reverse().find(takesPositionalSlot)?.name;
|
|
1736
|
+
const booleanFlags2 = [];
|
|
1577
1737
|
config2.parameters.forEach((param) => {
|
|
1578
1738
|
const kebabName = toKebabCase(param.name);
|
|
1579
1739
|
if (param.promptable && param.required) {
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1740
|
+
if (param.type === "array" && !hasPositionalArray && param.name === lastPositionalParamName) {
|
|
1741
|
+
hasPositionalArray = true;
|
|
1742
|
+
command.argument(
|
|
1743
|
+
`[${kebabName}...]`,
|
|
1744
|
+
param.description || `${kebabName} parameter`
|
|
1745
|
+
);
|
|
1746
|
+
} else {
|
|
1747
|
+
command.argument(
|
|
1748
|
+
`[${kebabName}]`,
|
|
1749
|
+
param.description || `${kebabName} parameter`
|
|
1750
|
+
);
|
|
1751
|
+
}
|
|
1584
1752
|
} else if (param.required && param.type === "array" && !hasPositionalArray) {
|
|
1585
1753
|
hasPositionalArray = true;
|
|
1586
1754
|
command.argument(
|
|
@@ -1617,6 +1785,24 @@ function addCommand(program2, commandName, config2) {
|
|
|
1617
1785
|
const opt = new Option(flags.join(", "), param.description);
|
|
1618
1786
|
if (param.isDeprecated) opt.hideHelp();
|
|
1619
1787
|
command.addOption(opt);
|
|
1788
|
+
const negationKebab = negationKebabName(param);
|
|
1789
|
+
if (negationKebab !== void 0) {
|
|
1790
|
+
const negation = new Option(
|
|
1791
|
+
`--${negationKebab}`,
|
|
1792
|
+
`Disable --${kebabName}`
|
|
1793
|
+
);
|
|
1794
|
+
if (!negationKebab.startsWith("no-")) {
|
|
1795
|
+
negation.conflicts(param.name);
|
|
1796
|
+
}
|
|
1797
|
+
if (param.isDeprecated) negation.hideHelp();
|
|
1798
|
+
command.addOption(negation);
|
|
1799
|
+
}
|
|
1800
|
+
booleanFlags2.push({
|
|
1801
|
+
kebabName,
|
|
1802
|
+
attributeName: param.name,
|
|
1803
|
+
negationKebab,
|
|
1804
|
+
shortAlias: alias && alias.length === 1 ? alias : void 0
|
|
1805
|
+
});
|
|
1620
1806
|
} else if (param.type === "array") {
|
|
1621
1807
|
const flagSignature = flags.join(", ") + ` <value>`;
|
|
1622
1808
|
const opt = new Option(flagSignature, param.description || "");
|
|
@@ -1646,24 +1832,128 @@ function addCommand(program2, commandName, config2) {
|
|
|
1646
1832
|
if (config2.supportsJsonOutput === false && opt.name === "json") return;
|
|
1647
1833
|
command.option(opt.flag, opt.description);
|
|
1648
1834
|
});
|
|
1835
|
+
if (booleanFlags2.length > 0) {
|
|
1836
|
+
addBooleanFlagErrorHints({ command, booleanFlags: booleanFlags2 });
|
|
1837
|
+
rejectBooleanFlagValues({ command, booleanFlags: booleanFlags2 });
|
|
1838
|
+
}
|
|
1649
1839
|
command.action(config2.handler);
|
|
1650
1840
|
}
|
|
1841
|
+
function booleanFlagUsageHint(flag) {
|
|
1842
|
+
return flag.negationKebab !== void 0 ? `use --${flag.kebabName} to enable or --${flag.negationKebab} to disable` : `pass --${flag.kebabName} to enable or omit it`;
|
|
1843
|
+
}
|
|
1844
|
+
function addBooleanFlagErrorHints({
|
|
1845
|
+
command,
|
|
1846
|
+
booleanFlags: booleanFlags2
|
|
1847
|
+
}) {
|
|
1848
|
+
const originalError = command.error.bind(command);
|
|
1849
|
+
command.error = (message, errorOptions) => originalError(
|
|
1850
|
+
appendBooleanFlagHint({
|
|
1851
|
+
message,
|
|
1852
|
+
code: errorOptions?.code,
|
|
1853
|
+
command,
|
|
1854
|
+
booleanFlags: booleanFlags2
|
|
1855
|
+
}),
|
|
1856
|
+
errorOptions
|
|
1857
|
+
);
|
|
1858
|
+
}
|
|
1859
|
+
function rejectBooleanFlagValues({
|
|
1860
|
+
command,
|
|
1861
|
+
booleanFlags: booleanFlags2
|
|
1862
|
+
}) {
|
|
1863
|
+
command.hook("preAction", (_thisCommand, actionCommand) => {
|
|
1864
|
+
let root = actionCommand;
|
|
1865
|
+
while (root.parent) root = root.parent;
|
|
1866
|
+
const { rawArgs } = root;
|
|
1867
|
+
const terminatorIndex = rawArgs.indexOf("--");
|
|
1868
|
+
const tokens = terminatorIndex === -1 ? rawArgs : rawArgs.slice(0, terminatorIndex);
|
|
1869
|
+
for (const flag of booleanFlags2) {
|
|
1870
|
+
const spellings = new Set(
|
|
1871
|
+
[
|
|
1872
|
+
`--${flag.kebabName}`,
|
|
1873
|
+
flag.negationKebab === void 0 ? void 0 : `--${flag.negationKebab}`,
|
|
1874
|
+
flag.shortAlias === void 0 ? void 0 : `-${flag.shortAlias}`
|
|
1875
|
+
].filter((spelling) => spelling !== void 0)
|
|
1876
|
+
);
|
|
1877
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
1878
|
+
if (!spellings.has(tokens[i])) continue;
|
|
1879
|
+
const next = tokens[i + 1].trim().toLowerCase();
|
|
1880
|
+
if (!BOOLEAN_TRUE_TOKENS.has(next) && !BOOLEAN_FALSE_TOKENS.has(next)) {
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
actionCommand.error(
|
|
1884
|
+
`error: ${tokens[i]} is a boolean flag and takes no value, but was followed by '${tokens[i + 1]}': ${booleanFlagUsageHint(flag)}.`,
|
|
1885
|
+
{ code: "zapierSdk.booleanFlagValue" }
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
});
|
|
1890
|
+
}
|
|
1891
|
+
function appendBooleanFlagHint({
|
|
1892
|
+
message,
|
|
1893
|
+
code,
|
|
1894
|
+
command,
|
|
1895
|
+
booleanFlags: booleanFlags2
|
|
1896
|
+
}) {
|
|
1897
|
+
if (code === "commander.unknownOption") {
|
|
1898
|
+
const flagWithValue = message.match(/'--([^=']+)=/);
|
|
1899
|
+
if (!flagWithValue) return message;
|
|
1900
|
+
const typedName = flagWithValue[1];
|
|
1901
|
+
const flag = booleanFlags2.find(
|
|
1902
|
+
(candidate) => candidate.kebabName === typedName || candidate.negationKebab === typedName
|
|
1903
|
+
);
|
|
1904
|
+
if (flag === void 0) return message;
|
|
1905
|
+
return `${message}
|
|
1906
|
+
(--${typedName} is a boolean flag and takes no value: ${booleanFlagUsageHint(flag)}.)`;
|
|
1907
|
+
}
|
|
1908
|
+
if (code === "commander.excessArguments") {
|
|
1909
|
+
const excessOperands = command.args.slice(
|
|
1910
|
+
command.registeredArguments.length
|
|
1911
|
+
);
|
|
1912
|
+
const strayBooleanToken = excessOperands.find((token) => {
|
|
1913
|
+
const normalized = token.trim().toLowerCase();
|
|
1914
|
+
return BOOLEAN_TRUE_TOKENS.has(normalized) || BOOLEAN_FALSE_TOKENS.has(normalized);
|
|
1915
|
+
});
|
|
1916
|
+
if (strayBooleanToken === void 0) return message;
|
|
1917
|
+
const usedBooleanFlag = booleanFlags2.find(
|
|
1918
|
+
(flag) => [flag.attributeName, flag.negationKebab].filter((name) => name !== void 0).some(
|
|
1919
|
+
(name) => command.getOptionValueSource(kebabToCamelCase(name)) === "cli"
|
|
1920
|
+
)
|
|
1921
|
+
);
|
|
1922
|
+
if (usedBooleanFlag === void 0) return message;
|
|
1923
|
+
return `${message}
|
|
1924
|
+
(Boolean flags take no value, so '${strayBooleanToken}' was read as an extra argument: ${booleanFlagUsageHint(usedBooleanFlag)}.)`;
|
|
1925
|
+
}
|
|
1926
|
+
return message;
|
|
1927
|
+
}
|
|
1651
1928
|
function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
1652
1929
|
const sdkParams = {};
|
|
1653
1930
|
let argIndex = 0;
|
|
1654
1931
|
parameters.forEach((param) => {
|
|
1655
1932
|
if (takesPositionalSlot(param) && argIndex < positionalArgs.length) {
|
|
1933
|
+
const positionalValue = positionalArgs[argIndex];
|
|
1934
|
+
argIndex++;
|
|
1935
|
+
if (Array.isArray(positionalValue) && positionalValue.length === 0) {
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1656
1938
|
sdkParams[param.name] = convertValue(
|
|
1657
|
-
|
|
1939
|
+
positionalValue,
|
|
1658
1940
|
param.type,
|
|
1659
1941
|
param.elementType
|
|
1660
1942
|
);
|
|
1661
|
-
argIndex++;
|
|
1662
1943
|
}
|
|
1663
1944
|
});
|
|
1664
1945
|
Object.entries(options).forEach(([key, value]) => {
|
|
1665
1946
|
const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
1666
1947
|
const param = parameters.find((p) => p.name === camelKey);
|
|
1948
|
+
if (param === void 0 && value === true) {
|
|
1949
|
+
const antonymTarget = parameters.find(
|
|
1950
|
+
(p) => antonymAttributeName(p) === camelKey
|
|
1951
|
+
);
|
|
1952
|
+
if (antonymTarget && sdkParams[antonymTarget.name] === void 0) {
|
|
1953
|
+
sdkParams[antonymTarget.name] = false;
|
|
1954
|
+
}
|
|
1955
|
+
return;
|
|
1956
|
+
}
|
|
1667
1957
|
if (param && value !== void 0) {
|
|
1668
1958
|
if (sdkParams[camelKey] !== void 0) {
|
|
1669
1959
|
return;
|
|
@@ -1676,6 +1966,16 @@ function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
|
1676
1966
|
});
|
|
1677
1967
|
return sdkParams;
|
|
1678
1968
|
}
|
|
1969
|
+
var BOOLEAN_TRUE_TOKENS = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
|
|
1970
|
+
var BOOLEAN_FALSE_TOKENS = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
|
|
1971
|
+
function parseCliBoolean(value) {
|
|
1972
|
+
const normalized = value.trim().toLowerCase();
|
|
1973
|
+
if (BOOLEAN_TRUE_TOKENS.has(normalized)) return true;
|
|
1974
|
+
if (BOOLEAN_FALSE_TOKENS.has(normalized)) return false;
|
|
1975
|
+
throw new InvalidArgumentError(
|
|
1976
|
+
`Expected a boolean (true or false), received "${value}".`
|
|
1977
|
+
);
|
|
1978
|
+
}
|
|
1679
1979
|
function convertValue(value, type, elementType) {
|
|
1680
1980
|
if (value === void 0) {
|
|
1681
1981
|
return void 0;
|
|
@@ -1684,7 +1984,7 @@ function convertValue(value, type, elementType) {
|
|
|
1684
1984
|
case "number":
|
|
1685
1985
|
return Number(value);
|
|
1686
1986
|
case "boolean":
|
|
1687
|
-
return Boolean(value);
|
|
1987
|
+
return typeof value === "string" ? parseCliBoolean(value) : Boolean(value);
|
|
1688
1988
|
case "array": {
|
|
1689
1989
|
const arr = Array.isArray(value) ? value : [value];
|
|
1690
1990
|
if (elementType !== "object") return arr;
|
|
@@ -5715,54 +6015,6 @@ var InitSchema = z.object({
|
|
|
5715
6015
|
}).describe(
|
|
5716
6016
|
"Create a new Zapier SDK project in a new directory with starter files"
|
|
5717
6017
|
);
|
|
5718
|
-
function detectPackageManager(cwd = process.cwd()) {
|
|
5719
|
-
const ua = process.env.npm_config_user_agent;
|
|
5720
|
-
if (ua) {
|
|
5721
|
-
if (ua.includes("yarn")) return { name: "yarn", source: "runtime" };
|
|
5722
|
-
if (ua.includes("pnpm")) return { name: "pnpm", source: "runtime" };
|
|
5723
|
-
if (ua.includes("bun")) return { name: "bun", source: "runtime" };
|
|
5724
|
-
if (ua.includes("npm")) return { name: "npm", source: "runtime" };
|
|
5725
|
-
}
|
|
5726
|
-
const files = [
|
|
5727
|
-
["pnpm-lock.yaml", "pnpm"],
|
|
5728
|
-
["yarn.lock", "yarn"],
|
|
5729
|
-
["bun.lockb", "bun"],
|
|
5730
|
-
["package-lock.json", "npm"]
|
|
5731
|
-
];
|
|
5732
|
-
for (const [file, name] of files) {
|
|
5733
|
-
if (existsSync(join(cwd, file))) {
|
|
5734
|
-
return { name, source: "lockfile" };
|
|
5735
|
-
}
|
|
5736
|
-
}
|
|
5737
|
-
return { name: "unknown", source: "fallback" };
|
|
5738
|
-
}
|
|
5739
|
-
function getUpdateCommand(packageName) {
|
|
5740
|
-
const pm = detectPackageManager();
|
|
5741
|
-
const isGlobal = isInstalledGlobally;
|
|
5742
|
-
if (isGlobal) {
|
|
5743
|
-
switch (pm.name) {
|
|
5744
|
-
case "yarn":
|
|
5745
|
-
return `yarn global upgrade ${packageName}@latest`;
|
|
5746
|
-
case "pnpm":
|
|
5747
|
-
return `pnpm update -g ${packageName}@latest`;
|
|
5748
|
-
case "bun":
|
|
5749
|
-
return `bun update -g ${packageName}@latest`;
|
|
5750
|
-
default:
|
|
5751
|
-
return `npm install -g ${packageName}@latest`;
|
|
5752
|
-
}
|
|
5753
|
-
} else {
|
|
5754
|
-
switch (pm.name) {
|
|
5755
|
-
case "yarn":
|
|
5756
|
-
return `yarn upgrade ${packageName}@latest`;
|
|
5757
|
-
case "pnpm":
|
|
5758
|
-
return `pnpm update ${packageName}@latest`;
|
|
5759
|
-
case "bun":
|
|
5760
|
-
return `bun update ${packageName}@latest`;
|
|
5761
|
-
default:
|
|
5762
|
-
return `npm install ${packageName}@latest`;
|
|
5763
|
-
}
|
|
5764
|
-
}
|
|
5765
|
-
}
|
|
5766
6018
|
function getDirentParentPath(entry) {
|
|
5767
6019
|
const e = entry;
|
|
5768
6020
|
const parent = e.parentPath ?? e.path;
|
|
@@ -6159,17 +6411,16 @@ var initPlugin = defineMethod({
|
|
|
6159
6411
|
const cwd = process.cwd();
|
|
6160
6412
|
const { projectName, projectDir } = validateInitOptions({ rawName, cwd });
|
|
6161
6413
|
const displayHooks = createConsoleDisplayHooks();
|
|
6162
|
-
const
|
|
6163
|
-
if (
|
|
6414
|
+
const packageManager = detectPackageManager(cwd);
|
|
6415
|
+
if (packageManager.source === "fallback") {
|
|
6164
6416
|
displayHooks.onWarn(
|
|
6165
6417
|
"Could not detect package manager, defaulting to npm."
|
|
6166
6418
|
);
|
|
6167
6419
|
}
|
|
6168
|
-
const packageManager = packageManagerInfo.name === "unknown" ? "npm" : packageManagerInfo.name;
|
|
6169
6420
|
const steps = getInitSteps({
|
|
6170
6421
|
projectDir,
|
|
6171
6422
|
projectName,
|
|
6172
|
-
packageManager,
|
|
6423
|
+
packageManager: packageManager.name,
|
|
6173
6424
|
displayHooks
|
|
6174
6425
|
});
|
|
6175
6426
|
const completedSetupStepIds = [];
|
|
@@ -6197,54 +6448,1382 @@ var initPlugin = defineMethod({
|
|
|
6197
6448
|
projectName,
|
|
6198
6449
|
steps,
|
|
6199
6450
|
completedSetupStepIds,
|
|
6200
|
-
packageManager
|
|
6451
|
+
packageManager: packageManager.name
|
|
6201
6452
|
});
|
|
6202
6453
|
}
|
|
6203
6454
|
});
|
|
6204
|
-
var
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6455
|
+
var ONE_DAY_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
6456
|
+
var CACHE_RESET_INTERVAL_MILLISECONDS = (() => {
|
|
6457
|
+
const {
|
|
6458
|
+
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS,
|
|
6459
|
+
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS
|
|
6460
|
+
} = process.env;
|
|
6461
|
+
let intervalMs;
|
|
6462
|
+
if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS !== void 0) {
|
|
6463
|
+
const seconds = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS);
|
|
6464
|
+
intervalMs = isNaN(seconds) ? NaN : seconds * 1e3;
|
|
6465
|
+
} else if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS !== void 0) {
|
|
6466
|
+
intervalMs = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
|
|
6467
|
+
} else {
|
|
6468
|
+
intervalMs = ONE_DAY_MILLISECONDS;
|
|
6208
6469
|
}
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
return
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
)
|
|
6219
|
-
|
|
6220
|
-
|
|
6470
|
+
if (isNaN(intervalMs) || intervalMs < 0) {
|
|
6471
|
+
return -1;
|
|
6472
|
+
}
|
|
6473
|
+
return intervalMs;
|
|
6474
|
+
})();
|
|
6475
|
+
function getVersionCache() {
|
|
6476
|
+
try {
|
|
6477
|
+
const cache = getConfig().get("version_cache");
|
|
6478
|
+
const now = Date.now();
|
|
6479
|
+
if (!cache || !cache.last_reset_timestamp || now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MILLISECONDS) {
|
|
6480
|
+
const newCache = {
|
|
6481
|
+
last_reset_timestamp: now,
|
|
6482
|
+
packages: {}
|
|
6483
|
+
};
|
|
6484
|
+
getConfig().set("version_cache", newCache);
|
|
6485
|
+
return newCache;
|
|
6221
6486
|
}
|
|
6222
|
-
|
|
6223
|
-
|
|
6487
|
+
return cache;
|
|
6488
|
+
} catch (error) {
|
|
6489
|
+
log_default.debug(`Failed to read version cache: ${error}`);
|
|
6490
|
+
return {
|
|
6491
|
+
last_reset_timestamp: Date.now(),
|
|
6492
|
+
packages: {}
|
|
6493
|
+
};
|
|
6494
|
+
}
|
|
6495
|
+
}
|
|
6496
|
+
function setCachedPackageInfo(packageName, version, info) {
|
|
6497
|
+
try {
|
|
6498
|
+
const cache = getVersionCache();
|
|
6499
|
+
if (!cache.packages[packageName]) {
|
|
6500
|
+
cache.packages[packageName] = {};
|
|
6224
6501
|
}
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6502
|
+
cache.packages[packageName][version] = info;
|
|
6503
|
+
getConfig().set("version_cache", cache);
|
|
6504
|
+
} catch (error) {
|
|
6505
|
+
log_default.debug(`Failed to cache package info: ${error}`);
|
|
6506
|
+
}
|
|
6507
|
+
}
|
|
6508
|
+
function getCachedPackageInfo(packageName, version) {
|
|
6509
|
+
try {
|
|
6510
|
+
const cache = getVersionCache();
|
|
6511
|
+
return cache.packages[packageName]?.[version];
|
|
6512
|
+
} catch (error) {
|
|
6513
|
+
log_default.debug(`Failed to get cached package info: ${error}`);
|
|
6514
|
+
return void 0;
|
|
6515
|
+
}
|
|
6516
|
+
}
|
|
6517
|
+
async function fetchCachedPackageInfo(packageName, version) {
|
|
6518
|
+
const cacheKey = version || "latest";
|
|
6519
|
+
let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
|
|
6520
|
+
if (cachedInfo) {
|
|
6521
|
+
return cachedInfo;
|
|
6522
|
+
}
|
|
6523
|
+
const packageInfo = await packageJsonLib(packageName, {
|
|
6524
|
+
version,
|
|
6525
|
+
fullMetadata: true
|
|
6526
|
+
});
|
|
6527
|
+
const info = {
|
|
6528
|
+
version: packageInfo.version,
|
|
6529
|
+
deprecated: packageInfo.deprecated,
|
|
6530
|
+
fetched_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6531
|
+
};
|
|
6532
|
+
setCachedPackageInfo(packageName, cacheKey, info);
|
|
6533
|
+
return info;
|
|
6534
|
+
}
|
|
6535
|
+
async function checkForUpdates({
|
|
6536
|
+
packageName,
|
|
6537
|
+
currentVersion
|
|
6538
|
+
}) {
|
|
6539
|
+
try {
|
|
6540
|
+
const latestPackageInfo = await fetchCachedPackageInfo(packageName);
|
|
6541
|
+
const latestVersion = latestPackageInfo.version;
|
|
6542
|
+
const hasUpdate = semver.gt(latestVersion, currentVersion);
|
|
6543
|
+
let currentPackageInfo;
|
|
6544
|
+
try {
|
|
6545
|
+
currentPackageInfo = await fetchCachedPackageInfo(
|
|
6546
|
+
packageName,
|
|
6547
|
+
currentVersion
|
|
6548
|
+
);
|
|
6549
|
+
} catch (error) {
|
|
6550
|
+
if (!(error instanceof VersionNotFoundError)) {
|
|
6551
|
+
log_default.debug(`Failed to check deprecation for current version: ${error}`);
|
|
6552
|
+
}
|
|
6553
|
+
currentPackageInfo = latestPackageInfo;
|
|
6554
|
+
}
|
|
6555
|
+
const isDeprecated = Boolean(currentPackageInfo.deprecated);
|
|
6556
|
+
const deprecationMessage = isDeprecated ? String(currentPackageInfo.deprecated) : void 0;
|
|
6557
|
+
return {
|
|
6558
|
+
hasUpdate,
|
|
6559
|
+
latestVersion,
|
|
6560
|
+
currentVersion,
|
|
6561
|
+
isDeprecated,
|
|
6562
|
+
deprecationMessage
|
|
6563
|
+
};
|
|
6564
|
+
} catch (error) {
|
|
6565
|
+
log_default.debug(`Failed to check for updates: ${error}`);
|
|
6566
|
+
return {
|
|
6567
|
+
hasUpdate: false,
|
|
6568
|
+
currentVersion,
|
|
6569
|
+
isDeprecated: false
|
|
6570
|
+
};
|
|
6571
|
+
}
|
|
6572
|
+
}
|
|
6573
|
+
function displayUpdateNotification(versionInfo, packageName) {
|
|
6574
|
+
if (versionInfo.isDeprecated) {
|
|
6575
|
+
console.error();
|
|
6576
|
+
console.error(
|
|
6577
|
+
chalk8.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.red(
|
|
6578
|
+
` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
|
|
6579
|
+
)
|
|
6580
|
+
);
|
|
6581
|
+
if (versionInfo.deprecationMessage) {
|
|
6582
|
+
console.error(chalk8.red(` ${versionInfo.deprecationMessage}`));
|
|
6583
|
+
}
|
|
6584
|
+
console.error(chalk8.red(` Please update to the latest version.`));
|
|
6585
|
+
console.error();
|
|
6586
|
+
}
|
|
6587
|
+
if (versionInfo.hasUpdate) {
|
|
6588
|
+
console.error();
|
|
6589
|
+
console.error(
|
|
6590
|
+
chalk8.yellow.bold("\u{1F4E6} Update available!") + chalk8.yellow(
|
|
6591
|
+
` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
|
|
6592
|
+
)
|
|
6593
|
+
);
|
|
6594
|
+
console.error(
|
|
6595
|
+
chalk8.yellow(
|
|
6596
|
+
` Run ${chalk8.bold(getUpdateCommand(packageName))} to update.`
|
|
6597
|
+
)
|
|
6598
|
+
);
|
|
6599
|
+
console.error();
|
|
6600
|
+
}
|
|
6601
|
+
}
|
|
6602
|
+
async function checkAndNotifyUpdates({
|
|
6603
|
+
packageName,
|
|
6604
|
+
currentVersion
|
|
6605
|
+
}) {
|
|
6606
|
+
if (CACHE_RESET_INTERVAL_MILLISECONDS < 0) {
|
|
6607
|
+
return;
|
|
6608
|
+
}
|
|
6609
|
+
const versionInfo = await checkForUpdates({ packageName, currentVersion });
|
|
6610
|
+
displayUpdateNotification(versionInfo, packageName);
|
|
6611
|
+
}
|
|
6612
|
+
var BRAILLE_BLANK = "\u2800";
|
|
6613
|
+
var LIGHTNING_INTERVAL_MILLISECONDS = 140;
|
|
6614
|
+
var boltRows = [
|
|
6615
|
+
"\u2800\u2800\u2880\u28FE\u2800\u2800\u2800\u2800",
|
|
6616
|
+
"\u2800\u2800\u28E0\u28FF\u28FF\u2800\u2800\u2800",
|
|
6617
|
+
"\u2800\u28FC\u28FF\u28FF\u28FF\u28C0\u28C0\u2840",
|
|
6618
|
+
"\u2808\u2809\u2809\u28FF\u28FF\u28FF\u285F\u2800",
|
|
6619
|
+
"\u2800\u2800\u2800\u28FF\u28FF\u280B\u2800\u2800",
|
|
6620
|
+
"\u2800\u2800\u2800\u287F\u2801\u2800\u2800\u2800"
|
|
6621
|
+
];
|
|
6622
|
+
var boltFillOrder = boltRows.flatMap(
|
|
6623
|
+
(row, rowIndex) => [...row].flatMap(
|
|
6624
|
+
(cell, columnIndex) => cell === BRAILLE_BLANK ? [] : rowIndex * row.length + columnIndex
|
|
6625
|
+
)
|
|
6626
|
+
);
|
|
6627
|
+
var fillStages = [
|
|
6628
|
+
...Array.from({ length: boltFillOrder.length + 1 }, (_, index) => index),
|
|
6629
|
+
boltFillOrder.length,
|
|
6630
|
+
0
|
|
6631
|
+
];
|
|
6632
|
+
var boltFillRanks = new Map(
|
|
6633
|
+
boltFillOrder.map((cellIndex, fillIndex) => [cellIndex, fillIndex])
|
|
6634
|
+
);
|
|
6635
|
+
var STATUS_ROW_INDEX = Math.floor(boltRows.length / 2);
|
|
6636
|
+
function formatPhase({ label, detail }) {
|
|
6637
|
+
return detail ? `${chalk8.bold(label)} ${chalk8.dim(detail)}` : chalk8.bold(label);
|
|
6638
|
+
}
|
|
6639
|
+
function formatLoaderFrame({
|
|
6640
|
+
phase,
|
|
6641
|
+
fillStage
|
|
6642
|
+
}) {
|
|
6643
|
+
return boltRows.map((row, rowIndex) => {
|
|
6644
|
+
const bolt = [...row].map((cell, columnIndex) => {
|
|
6645
|
+
if (cell === BRAILLE_BLANK) return cell;
|
|
6646
|
+
const cellIndex = rowIndex * row.length + columnIndex;
|
|
6647
|
+
const fillRank = boltFillRanks.get(cellIndex);
|
|
6648
|
+
const isFilled = fillRank !== void 0 && fillRank < fillStage;
|
|
6649
|
+
return isFilled ? chalk8.bold.yellow(cell) : chalk8.dim.yellow(cell);
|
|
6650
|
+
}).join("");
|
|
6651
|
+
const status = rowIndex === STATUS_ROW_INDEX ? ` ${formatPhase(phase)}` : "";
|
|
6652
|
+
return `${bolt}${status}`;
|
|
6653
|
+
}).join("\n");
|
|
6654
|
+
}
|
|
6655
|
+
async function runWithSetupLoader({
|
|
6656
|
+
promise,
|
|
6657
|
+
...phase
|
|
6658
|
+
}) {
|
|
6659
|
+
const startedAt = Date.now();
|
|
6660
|
+
let fillFrameIndex = 0;
|
|
6661
|
+
const loader = ora({
|
|
6662
|
+
isEnabled: process.stderr.isTTY === true,
|
|
6663
|
+
spinner: { interval: 80, frames: [""] },
|
|
6664
|
+
text: formatLoaderFrame({
|
|
6665
|
+
phase,
|
|
6666
|
+
fillStage: fillStages[fillFrameIndex]
|
|
6667
|
+
})
|
|
6668
|
+
}).start();
|
|
6669
|
+
const animationTimer = setInterval(() => {
|
|
6670
|
+
fillFrameIndex = (fillFrameIndex + 1) % fillStages.length;
|
|
6671
|
+
loader.text = formatLoaderFrame({
|
|
6672
|
+
phase,
|
|
6673
|
+
fillStage: fillStages[fillFrameIndex]
|
|
6674
|
+
});
|
|
6675
|
+
}, LIGHTNING_INTERVAL_MILLISECONDS);
|
|
6676
|
+
animationTimer.unref?.();
|
|
6677
|
+
try {
|
|
6678
|
+
const result = await promise;
|
|
6679
|
+
clearInterval(animationTimer);
|
|
6680
|
+
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
6681
|
+
loader.succeed(`${formatPhase(phase)} ${chalk8.dim(`${elapsedSeconds}s`)}`);
|
|
6682
|
+
return result;
|
|
6683
|
+
} catch (error) {
|
|
6684
|
+
clearInterval(animationTimer);
|
|
6685
|
+
const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
|
|
6686
|
+
loader.fail(`${formatPhase(phase)} ${chalk8.dim(`${elapsedSeconds}s`)}`);
|
|
6687
|
+
throw error;
|
|
6688
|
+
}
|
|
6689
|
+
}
|
|
6690
|
+
function isRecord(value) {
|
|
6691
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6692
|
+
}
|
|
6693
|
+
function readPackageJson({
|
|
6694
|
+
directory
|
|
6695
|
+
}) {
|
|
6696
|
+
try {
|
|
6697
|
+
const manifest = JSON.parse(
|
|
6698
|
+
readFileSync(join(directory, "package.json"), "utf8")
|
|
6699
|
+
);
|
|
6700
|
+
return isRecord(manifest) ? manifest : void 0;
|
|
6701
|
+
} catch {
|
|
6702
|
+
return void 0;
|
|
6703
|
+
}
|
|
6704
|
+
}
|
|
6705
|
+
var SetupOptionSchema = z.object({
|
|
6706
|
+
label: z.string(),
|
|
6707
|
+
value: z.string()
|
|
6708
|
+
});
|
|
6709
|
+
var SetupOptionsSchema = z.array(SetupOptionSchema).min(1);
|
|
6710
|
+
var SetupDecisionSchema = z.object({
|
|
6711
|
+
message: z.string(),
|
|
6712
|
+
options: SetupOptionsSchema,
|
|
6713
|
+
answer: z.string()
|
|
6714
|
+
});
|
|
6715
|
+
var SetupInputSchema = z.object({
|
|
6716
|
+
message: z.string(),
|
|
6717
|
+
answer: z.string()
|
|
6718
|
+
});
|
|
6719
|
+
var setupDecisionResolver = defineResolver({
|
|
6720
|
+
requireParameters: ["message", "options"],
|
|
6721
|
+
listItems: ({ input }) => ({ data: input.options }),
|
|
6722
|
+
prompt: ({ items, input }) => ({
|
|
6723
|
+
type: "list",
|
|
6724
|
+
message: input.message,
|
|
6725
|
+
choices: items
|
|
6726
|
+
}),
|
|
6727
|
+
validate: ({ input, value }) => {
|
|
6728
|
+
if (typeof value !== "string") return "Choose an available option.";
|
|
6729
|
+
return input.options.some((option) => option.value === value) || "Choose one of the available options.";
|
|
6730
|
+
}
|
|
6731
|
+
});
|
|
6732
|
+
var setupInputResolver = defineResolver({
|
|
6733
|
+
type: "static",
|
|
6734
|
+
inputType: "text",
|
|
6735
|
+
requireParameters: ["message"]
|
|
6736
|
+
});
|
|
6737
|
+
var resolveSetupDecisionPlugin = defineMethod({
|
|
6738
|
+
name: "resolveSetupDecision",
|
|
6739
|
+
description: "Resolve one setup wizard decision.",
|
|
6740
|
+
inputSchema: SetupDecisionSchema,
|
|
6741
|
+
resolvers: { answer: setupDecisionResolver },
|
|
6742
|
+
run: ({ input }) => input
|
|
6743
|
+
});
|
|
6744
|
+
var resolveSetupInputPlugin = defineMethod({
|
|
6745
|
+
name: "resolveSetupInput",
|
|
6746
|
+
description: "Resolve one setup wizard text input.",
|
|
6747
|
+
inputSchema: SetupInputSchema,
|
|
6748
|
+
resolvers: { answer: setupInputResolver },
|
|
6749
|
+
run: ({ input }) => input
|
|
6750
|
+
});
|
|
6751
|
+
function createSetupController() {
|
|
6752
|
+
const setupResolutionSdk = createSdk$1(
|
|
6753
|
+
definePlugin({
|
|
6754
|
+
name: "setup-resolution",
|
|
6755
|
+
exports: [
|
|
6756
|
+
resolveSetupDecisionPlugin,
|
|
6757
|
+
resolveSetupInputPlugin,
|
|
6758
|
+
getRegistryPlugin
|
|
6759
|
+
]
|
|
6760
|
+
})
|
|
6761
|
+
);
|
|
6762
|
+
return createController(setupResolutionSdk);
|
|
6763
|
+
}
|
|
6764
|
+
async function resolveWithCancellation({
|
|
6765
|
+
run
|
|
6766
|
+
}) {
|
|
6767
|
+
try {
|
|
6768
|
+
return await run();
|
|
6769
|
+
} catch (error) {
|
|
6770
|
+
if (isCoreCancelledSignal(error)) {
|
|
6771
|
+
throw new ZapierCliUserCancellationError();
|
|
6772
|
+
}
|
|
6773
|
+
throw error;
|
|
6774
|
+
}
|
|
6775
|
+
}
|
|
6776
|
+
async function resolveSetupDecision({
|
|
6777
|
+
answer,
|
|
6778
|
+
controller,
|
|
6779
|
+
message,
|
|
6780
|
+
options
|
|
6781
|
+
}) {
|
|
6782
|
+
const parsedOptions = SetupOptionsSchema.parse(options);
|
|
6783
|
+
const resolved = await resolveWithCancellation({
|
|
6784
|
+
run: () => controller.resolve({
|
|
6785
|
+
method: "resolveSetupDecision",
|
|
6786
|
+
input: { message, options: parsedOptions },
|
|
6787
|
+
answer,
|
|
6788
|
+
interactive: true
|
|
6789
|
+
})
|
|
6790
|
+
});
|
|
6791
|
+
return SetupDecisionSchema.parse(resolved).answer;
|
|
6792
|
+
}
|
|
6793
|
+
async function resolveSetupConfirm({
|
|
6794
|
+
answer,
|
|
6795
|
+
controller,
|
|
6796
|
+
defaultValue,
|
|
6797
|
+
message
|
|
6798
|
+
}) {
|
|
6799
|
+
const values = defaultValue ? [true, false] : [false, true];
|
|
6800
|
+
const resolved = await resolveSetupDecision({
|
|
6801
|
+
answer,
|
|
6802
|
+
controller,
|
|
6803
|
+
message,
|
|
6804
|
+
options: values.map((value) => ({
|
|
6805
|
+
label: value ? "Yes" : "No",
|
|
6806
|
+
value: String(value)
|
|
6807
|
+
}))
|
|
6808
|
+
});
|
|
6809
|
+
return resolved === "true";
|
|
6810
|
+
}
|
|
6811
|
+
async function resolveSetupInput({
|
|
6812
|
+
answer,
|
|
6813
|
+
controller,
|
|
6814
|
+
message
|
|
6815
|
+
}) {
|
|
6816
|
+
const resolved = await resolveWithCancellation({
|
|
6817
|
+
run: () => controller.resolve({
|
|
6818
|
+
method: "resolveSetupInput",
|
|
6819
|
+
input: { message },
|
|
6820
|
+
answer: ({ result, state }) => answer({
|
|
6821
|
+
state,
|
|
6822
|
+
result: {
|
|
6823
|
+
...result,
|
|
6824
|
+
question: { ...result.question, message }
|
|
6825
|
+
}
|
|
6826
|
+
}),
|
|
6827
|
+
interactive: true
|
|
6828
|
+
})
|
|
6829
|
+
});
|
|
6830
|
+
return SetupInputSchema.parse(resolved).answer.trim();
|
|
6831
|
+
}
|
|
6832
|
+
async function resolveSetupSelect({
|
|
6833
|
+
answer,
|
|
6834
|
+
controller,
|
|
6835
|
+
choices,
|
|
6836
|
+
message
|
|
6837
|
+
}) {
|
|
6838
|
+
const resolved = await resolveSetupDecision({
|
|
6839
|
+
answer,
|
|
6840
|
+
controller,
|
|
6841
|
+
message,
|
|
6842
|
+
options: choices
|
|
6843
|
+
});
|
|
6844
|
+
const selected = choices.find(({ value }) => value === resolved);
|
|
6845
|
+
if (!selected) {
|
|
6846
|
+
throw new Error("Resolved setup selection is not an available choice.");
|
|
6847
|
+
}
|
|
6848
|
+
return selected.value;
|
|
6849
|
+
}
|
|
6850
|
+
|
|
6851
|
+
// src/plugins/setup/dependencies.ts
|
|
6852
|
+
var REQUIRED_PACKAGES = [
|
|
6853
|
+
{ name: "@zapier/zapier-sdk", dev: false, checkForUpdates: true },
|
|
6854
|
+
{ name: "@zapier/zapier-sdk-cli", dev: true, checkForUpdates: true },
|
|
6855
|
+
{
|
|
6856
|
+
name: "@types/node",
|
|
6857
|
+
dev: true,
|
|
6858
|
+
checkForUpdates: false,
|
|
6859
|
+
typescriptOnly: true
|
|
6860
|
+
},
|
|
6861
|
+
{
|
|
6862
|
+
name: "typescript",
|
|
6863
|
+
dev: true,
|
|
6864
|
+
checkForUpdates: false,
|
|
6865
|
+
typescriptOnly: true
|
|
6866
|
+
},
|
|
6867
|
+
{ name: "tsx", dev: true, checkForUpdates: false, typescriptOnly: true }
|
|
6868
|
+
];
|
|
6869
|
+
function getInstallCommand({
|
|
6870
|
+
packageManager,
|
|
6871
|
+
packages,
|
|
6872
|
+
dev = false
|
|
6873
|
+
}) {
|
|
6874
|
+
const verb = packageManager === "npm" ? "install" : "add";
|
|
6875
|
+
const devFlag = packageManager === "bun" ? "-d" : "-D";
|
|
6876
|
+
return {
|
|
6877
|
+
command: packageManager,
|
|
6878
|
+
args: [verb, ...dev ? [devFlag] : [], ...packages]
|
|
6879
|
+
};
|
|
6880
|
+
}
|
|
6881
|
+
async function executeInstall(context, command) {
|
|
6882
|
+
try {
|
|
6883
|
+
await context.runCommand({ ...command, cwd: context.cwd });
|
|
6884
|
+
} catch (error) {
|
|
6885
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6886
|
+
if (message.includes("EPERM") && message.includes(".npm/_cacache")) {
|
|
6887
|
+
console.error(
|
|
6888
|
+
"This EPERM usually means the command sandbox blocked npm cache writes; it does not usually mean your file permissions are broken."
|
|
6889
|
+
);
|
|
6890
|
+
}
|
|
6891
|
+
throw error;
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
function getDeclaredPackageNames(cwd) {
|
|
6895
|
+
const manifest = readPackageJson({ directory: cwd });
|
|
6896
|
+
if (!manifest) return /* @__PURE__ */ new Set();
|
|
6897
|
+
const names = /* @__PURE__ */ new Set();
|
|
6898
|
+
for (const section of ["dependencies", "devDependencies"]) {
|
|
6899
|
+
const dependencies = manifest[section];
|
|
6900
|
+
if (!isRecord(dependencies)) continue;
|
|
6901
|
+
for (const name of Object.keys(dependencies)) names.add(name);
|
|
6902
|
+
}
|
|
6903
|
+
return names;
|
|
6904
|
+
}
|
|
6905
|
+
function getInstalledPackageVersion({
|
|
6906
|
+
cwd,
|
|
6907
|
+
packageName
|
|
6908
|
+
}) {
|
|
6909
|
+
let directory = cwd;
|
|
6910
|
+
while (true) {
|
|
6911
|
+
const manifest = readPackageJson({
|
|
6912
|
+
directory: join(directory, "node_modules", ...packageName.split("/"))
|
|
6913
|
+
});
|
|
6914
|
+
if (manifest?.name === packageName && typeof manifest.version === "string") {
|
|
6915
|
+
return manifest.version;
|
|
6916
|
+
}
|
|
6917
|
+
const parent = dirname(directory);
|
|
6918
|
+
if (parent === directory) return void 0;
|
|
6919
|
+
directory = parent;
|
|
6920
|
+
}
|
|
6921
|
+
}
|
|
6922
|
+
async function installPackages({
|
|
6923
|
+
context,
|
|
6924
|
+
packages
|
|
6925
|
+
}) {
|
|
6926
|
+
const runtimePackages = packages.filter(({ dependency }) => !dependency.dev).map(({ dependency }) => dependency.name);
|
|
6927
|
+
if (runtimePackages.length > 0) {
|
|
6928
|
+
await executeInstall(
|
|
6929
|
+
context,
|
|
6930
|
+
getInstallCommand({
|
|
6931
|
+
packageManager: context.packageManager,
|
|
6932
|
+
packages: runtimePackages
|
|
6933
|
+
})
|
|
6934
|
+
);
|
|
6935
|
+
}
|
|
6936
|
+
const developmentPackages = packages.filter(({ dependency }) => dependency.dev).map(({ dependency }) => dependency.name);
|
|
6937
|
+
if (developmentPackages.length > 0) {
|
|
6938
|
+
await executeInstall(
|
|
6939
|
+
context,
|
|
6940
|
+
getInstallCommand({
|
|
6941
|
+
packageManager: context.packageManager,
|
|
6942
|
+
packages: developmentPackages,
|
|
6943
|
+
dev: true
|
|
6944
|
+
})
|
|
6945
|
+
);
|
|
6946
|
+
}
|
|
6947
|
+
}
|
|
6948
|
+
async function offerMissingPackageInstall({
|
|
6949
|
+
context,
|
|
6950
|
+
packages
|
|
6951
|
+
}) {
|
|
6952
|
+
if (packages.length === 0) return;
|
|
6953
|
+
const shouldInstall = await resolveSetupConfirm({
|
|
6954
|
+
answer: context.createAnswer(),
|
|
6955
|
+
controller: context.setupController,
|
|
6956
|
+
message: `These packages are required to continue. Install them now: ${packages.map(({ dependency }) => dependency.name).join(", ")}?`,
|
|
6957
|
+
defaultValue: true
|
|
6958
|
+
});
|
|
6959
|
+
if (!shouldInstall) {
|
|
6960
|
+
console.log(
|
|
6961
|
+
"The Zapier SDK packages are required to continue. Setup cancelled without installing dependencies."
|
|
6962
|
+
);
|
|
6963
|
+
throw new ZapierCliUserCancellationError(
|
|
6964
|
+
"Required Zapier SDK packages were not installed"
|
|
6965
|
+
);
|
|
6966
|
+
}
|
|
6967
|
+
await installPackages({ context, packages });
|
|
6968
|
+
}
|
|
6969
|
+
async function offerPackageUpdate({
|
|
6970
|
+
context,
|
|
6971
|
+
packageState
|
|
6972
|
+
}) {
|
|
6973
|
+
const { currentVersion, dependency } = packageState;
|
|
6974
|
+
if (!currentVersion || !dependency.checkForUpdates) return;
|
|
6975
|
+
const update = await runWithSetupLoader({
|
|
6976
|
+
promise: context.checkForUpdates({
|
|
6977
|
+
packageName: dependency.name,
|
|
6978
|
+
currentVersion
|
|
6979
|
+
}),
|
|
6980
|
+
label: "Checking for updates",
|
|
6981
|
+
detail: dependency.name
|
|
6982
|
+
});
|
|
6983
|
+
if (!update.hasUpdate || !update.latestVersion) return;
|
|
6984
|
+
const shouldUpdate = await resolveSetupConfirm({
|
|
6985
|
+
answer: context.createAnswer(),
|
|
6986
|
+
controller: context.setupController,
|
|
6987
|
+
message: `Update ${dependency.name} from ${currentVersion} to ${update.latestVersion}?`,
|
|
6988
|
+
defaultValue: true
|
|
6989
|
+
});
|
|
6990
|
+
if (!shouldUpdate) return;
|
|
6991
|
+
await executeInstall(
|
|
6992
|
+
context,
|
|
6993
|
+
getInstallCommand({
|
|
6994
|
+
packageManager: context.packageManager,
|
|
6995
|
+
packages: [`${dependency.name}@${update.latestVersion}`],
|
|
6996
|
+
dev: dependency.dev
|
|
6997
|
+
})
|
|
6998
|
+
);
|
|
6999
|
+
}
|
|
7000
|
+
async function prepareDependencies(context) {
|
|
7001
|
+
const declaredPackageNames = getDeclaredPackageNames(context.cwd);
|
|
7002
|
+
const requiredPackages = REQUIRED_PACKAGES.filter(
|
|
7003
|
+
({ typescriptOnly }) => !typescriptOnly || context.projectLanguage === "typescript"
|
|
7004
|
+
);
|
|
7005
|
+
const packages = requiredPackages.map((dependency) => ({
|
|
7006
|
+
dependency,
|
|
7007
|
+
currentVersion: declaredPackageNames.has(dependency.name) ? getInstalledPackageVersion({
|
|
7008
|
+
cwd: context.cwd,
|
|
7009
|
+
packageName: dependency.name
|
|
7010
|
+
}) : void 0
|
|
7011
|
+
}));
|
|
7012
|
+
await offerMissingPackageInstall({
|
|
7013
|
+
context,
|
|
7014
|
+
packages: packages.filter(
|
|
7015
|
+
({ dependency }) => !declaredPackageNames.has(dependency.name)
|
|
7016
|
+
)
|
|
7017
|
+
});
|
|
7018
|
+
for (const packageState of packages) {
|
|
7019
|
+
await offerPackageUpdate({ context, packageState });
|
|
7020
|
+
}
|
|
7021
|
+
}
|
|
7022
|
+
|
|
7023
|
+
// src/plugins/setup/package-commands.ts
|
|
7024
|
+
function createLocalPackageCommand({
|
|
7025
|
+
packageManager,
|
|
7026
|
+
binary,
|
|
7027
|
+
args = []
|
|
7028
|
+
}) {
|
|
7029
|
+
const runner = {
|
|
7030
|
+
npm: { command: "npx", args: ["--no-install"] },
|
|
7031
|
+
pnpm: { command: "pnpm", args: ["exec"] },
|
|
7032
|
+
yarn: { command: "yarn", args: ["exec"] },
|
|
7033
|
+
bun: { command: "bunx", args: ["--no-install"] }
|
|
7034
|
+
};
|
|
7035
|
+
return {
|
|
7036
|
+
command: runner[packageManager].command,
|
|
7037
|
+
args: [...runner[packageManager].args, binary, ...args]
|
|
7038
|
+
};
|
|
7039
|
+
}
|
|
7040
|
+
function createPackageRunnerCommand({
|
|
7041
|
+
packageManager,
|
|
7042
|
+
packageName,
|
|
7043
|
+
args = []
|
|
7044
|
+
}) {
|
|
7045
|
+
const runner = {
|
|
7046
|
+
npm: { command: "npx", args: ["--yes"] },
|
|
7047
|
+
pnpm: { command: "pnpm", args: ["dlx"] },
|
|
7048
|
+
yarn: { command: "yarn", args: ["dlx"] },
|
|
7049
|
+
bun: { command: "bunx", args: [] }
|
|
7050
|
+
};
|
|
7051
|
+
return {
|
|
7052
|
+
command: runner[packageManager].command,
|
|
7053
|
+
args: [...runner[packageManager].args, packageName, ...args]
|
|
7054
|
+
};
|
|
7055
|
+
}
|
|
7056
|
+
function formatPackageCommand({
|
|
7057
|
+
command,
|
|
7058
|
+
args
|
|
7059
|
+
}) {
|
|
7060
|
+
return [command, ...args].join(" ");
|
|
7061
|
+
}
|
|
7062
|
+
|
|
7063
|
+
// src/plugins/setup/project.ts
|
|
7064
|
+
var COMMAND_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
7065
|
+
var PROJECT_INIT_COMMANDS = {
|
|
7066
|
+
npm: { command: "npm", args: ["init", "-y"] },
|
|
7067
|
+
pnpm: { command: "pnpm", args: ["init"] },
|
|
7068
|
+
yarn: { command: "yarn", args: ["init", "-y"] },
|
|
7069
|
+
bun: { command: "bun", args: ["init", "-y"] }
|
|
7070
|
+
};
|
|
7071
|
+
var CapturedCommandError = class extends Error {
|
|
7072
|
+
constructor(error, stdout, stderr) {
|
|
7073
|
+
super(error.message);
|
|
7074
|
+
this.stdout = stdout;
|
|
7075
|
+
this.stderr = stderr;
|
|
7076
|
+
}
|
|
7077
|
+
};
|
|
7078
|
+
function commandError({
|
|
7079
|
+
command,
|
|
7080
|
+
code,
|
|
7081
|
+
signal
|
|
7082
|
+
}) {
|
|
7083
|
+
return new Error(
|
|
7084
|
+
signal ? `${command} was terminated by ${signal}` : `${command} exited with code ${code ?? "unknown"}`
|
|
7085
|
+
);
|
|
7086
|
+
}
|
|
7087
|
+
function executeCapturedCommand({
|
|
7088
|
+
command,
|
|
7089
|
+
args,
|
|
7090
|
+
cwd,
|
|
7091
|
+
input
|
|
7092
|
+
}) {
|
|
7093
|
+
return new Promise((resolve4, reject) => {
|
|
7094
|
+
const child = crossSpawn(command, args, {
|
|
7095
|
+
cwd,
|
|
7096
|
+
shell: false,
|
|
7097
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
7098
|
+
});
|
|
7099
|
+
let stdout = "";
|
|
7100
|
+
let stderr = "";
|
|
7101
|
+
const append = ({
|
|
7102
|
+
chunk,
|
|
7103
|
+
stream
|
|
7104
|
+
}) => {
|
|
7105
|
+
if (stream === "stdout") stdout += chunk.toString();
|
|
7106
|
+
else stderr += chunk.toString();
|
|
7107
|
+
if (Buffer.byteLength(stdout) + Buffer.byteLength(stderr) > COMMAND_MAX_BUFFER_BYTES) {
|
|
7108
|
+
child.kill();
|
|
7109
|
+
reject(new Error("Command output exceeded the capture limit."));
|
|
7110
|
+
}
|
|
7111
|
+
};
|
|
7112
|
+
child.stdout?.on(
|
|
7113
|
+
"data",
|
|
7114
|
+
(chunk) => append({ chunk, stream: "stdout" })
|
|
7115
|
+
);
|
|
7116
|
+
child.stderr?.on(
|
|
7117
|
+
"data",
|
|
7118
|
+
(chunk) => append({ chunk, stream: "stderr" })
|
|
7119
|
+
);
|
|
7120
|
+
child.once("error", reject);
|
|
7121
|
+
child.once("close", (code, signal) => {
|
|
7122
|
+
if (code === 0) {
|
|
7123
|
+
resolve4(stdout.trim());
|
|
7124
|
+
return;
|
|
7125
|
+
}
|
|
7126
|
+
reject(
|
|
7127
|
+
new CapturedCommandError(
|
|
7128
|
+
commandError({ command, code, signal }),
|
|
7129
|
+
stdout,
|
|
7130
|
+
stderr
|
|
7131
|
+
)
|
|
7132
|
+
);
|
|
7133
|
+
});
|
|
7134
|
+
child.stdin?.end(input);
|
|
7135
|
+
});
|
|
7136
|
+
}
|
|
7137
|
+
function executeStreamingCommand({
|
|
7138
|
+
command,
|
|
7139
|
+
args,
|
|
7140
|
+
cwd,
|
|
7141
|
+
input
|
|
7142
|
+
}) {
|
|
7143
|
+
return new Promise((resolve4, reject) => {
|
|
7144
|
+
const child = crossSpawn(command, args, {
|
|
7145
|
+
cwd,
|
|
7146
|
+
shell: false,
|
|
7147
|
+
stdio: [input === void 0 ? "inherit" : "pipe", "inherit", "inherit"]
|
|
7148
|
+
});
|
|
7149
|
+
child.once("error", reject);
|
|
7150
|
+
child.once("close", (code, signal) => {
|
|
7151
|
+
if (code === 0) {
|
|
7152
|
+
resolve4("");
|
|
7153
|
+
return;
|
|
7154
|
+
}
|
|
7155
|
+
reject(commandError({ command, code, signal }));
|
|
7156
|
+
});
|
|
7157
|
+
if (input !== void 0) child.stdin?.end(input);
|
|
7158
|
+
});
|
|
7159
|
+
}
|
|
7160
|
+
async function runCommand({
|
|
7161
|
+
command,
|
|
7162
|
+
args = [],
|
|
7163
|
+
cwd,
|
|
7164
|
+
capture = true,
|
|
7165
|
+
input
|
|
7166
|
+
}) {
|
|
7167
|
+
const commandLabel = `$ ${command} ${args.join(" ")}`.trim();
|
|
7168
|
+
const execute = capture ? executeCapturedCommand({ command, args, cwd, input }) : executeStreamingCommand({ command, args, cwd, input });
|
|
7169
|
+
try {
|
|
7170
|
+
if (capture) {
|
|
7171
|
+
return await runWithSetupLoader({
|
|
7172
|
+
promise: execute,
|
|
7173
|
+
label: "Running command",
|
|
7174
|
+
detail: commandLabel
|
|
7175
|
+
});
|
|
7176
|
+
}
|
|
7177
|
+
console.log(chalk8.dim(commandLabel));
|
|
7178
|
+
return await execute;
|
|
7179
|
+
} catch (error) {
|
|
7180
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7181
|
+
if (error instanceof CapturedCommandError) {
|
|
7182
|
+
if (error.stdout) process.stdout.write(error.stdout);
|
|
7183
|
+
if (error.stderr) process.stderr.write(error.stderr);
|
|
7184
|
+
if (!error.stdout && !error.stderr) console.error(message);
|
|
7185
|
+
} else {
|
|
7186
|
+
console.error(message);
|
|
7187
|
+
}
|
|
7188
|
+
throw new ZapierCliExitError(message);
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
async function chooseDirectory(context) {
|
|
7192
|
+
const useCurrentDirectory = await resolveSetupConfirm({
|
|
7193
|
+
answer: context.createAnswer(),
|
|
7194
|
+
controller: context.setupController,
|
|
7195
|
+
message: `Set up the Zapier SDK in ${context.cwd}?`,
|
|
7196
|
+
defaultValue: true
|
|
7197
|
+
});
|
|
7198
|
+
if (useCurrentDirectory) return;
|
|
7199
|
+
const setupCommand = formatPackageCommand(
|
|
7200
|
+
createLocalPackageCommand({
|
|
7201
|
+
packageManager: context.packageManager,
|
|
7202
|
+
binary: "zapier-sdk",
|
|
7203
|
+
args: ["setup"]
|
|
7204
|
+
})
|
|
7205
|
+
);
|
|
7206
|
+
console.log(
|
|
7207
|
+
`Setup cancelled. Navigate to the intended directory and run \`${setupCommand}\` again.`
|
|
7208
|
+
);
|
|
7209
|
+
throw new ZapierCliUserCancellationError("Setup cancelled by user");
|
|
7210
|
+
}
|
|
7211
|
+
async function ensureSupportedNode(context) {
|
|
7212
|
+
let version;
|
|
7213
|
+
try {
|
|
7214
|
+
version = await context.runCommand({
|
|
7215
|
+
command: "node",
|
|
7216
|
+
args: ["-v"],
|
|
7217
|
+
cwd: context.cwd,
|
|
7218
|
+
capture: true
|
|
7219
|
+
});
|
|
7220
|
+
} catch {
|
|
7221
|
+
console.error(
|
|
7222
|
+
"Node.js 20 or higher is required. Install it from https://nodejs.org, then run setup again."
|
|
7223
|
+
);
|
|
7224
|
+
throw new ZapierCliExitError(
|
|
7225
|
+
"Setup could not continue without Node.js 20 or higher."
|
|
7226
|
+
);
|
|
7227
|
+
}
|
|
7228
|
+
const major = Number(version.replace(/^v/, "").split(".")[0]);
|
|
7229
|
+
if (!Number.isFinite(major) || major < 20) {
|
|
7230
|
+
console.error(
|
|
7231
|
+
`Node.js 20 or higher is required; found ${version}. Upgrade Node.js, then run setup again.`
|
|
7232
|
+
);
|
|
7233
|
+
throw new ZapierCliExitError(
|
|
7234
|
+
"Setup could not continue without Node.js 20 or higher."
|
|
7235
|
+
);
|
|
7236
|
+
}
|
|
7237
|
+
console.log(`Node.js ${version} is ready.`);
|
|
7238
|
+
}
|
|
7239
|
+
function detectProjectLanguage({
|
|
7240
|
+
cwd,
|
|
7241
|
+
hasExistingProject
|
|
7242
|
+
}) {
|
|
7243
|
+
if (!hasExistingProject || existsSync(join(cwd, "tsconfig.json"))) {
|
|
7244
|
+
return "typescript";
|
|
7245
|
+
}
|
|
7246
|
+
const manifest = readPackageJson({ directory: cwd });
|
|
7247
|
+
const hasTypeScript = [
|
|
7248
|
+
manifest?.dependencies,
|
|
7249
|
+
manifest?.devDependencies
|
|
7250
|
+
].some(
|
|
7251
|
+
(dependencies) => isRecord(dependencies) && "typescript" in dependencies
|
|
7252
|
+
);
|
|
7253
|
+
return hasTypeScript ? "typescript" : "javascript";
|
|
7254
|
+
}
|
|
7255
|
+
async function prepareProject(context) {
|
|
7256
|
+
context.packageManager = detectPackageManager(context.cwd).name;
|
|
7257
|
+
console.log(`Using ${context.packageManager} for dependency installs.`);
|
|
7258
|
+
const hasExistingProject = existsSync(join(context.cwd, "package.json"));
|
|
7259
|
+
context.projectLanguage = detectProjectLanguage({
|
|
7260
|
+
cwd: context.cwd,
|
|
7261
|
+
hasExistingProject
|
|
7262
|
+
});
|
|
7263
|
+
if (hasExistingProject) {
|
|
7264
|
+
console.log("Found package.json; using this project as-is.");
|
|
7265
|
+
} else {
|
|
7266
|
+
await context.runCommand({
|
|
7267
|
+
...PROJECT_INIT_COMMANDS[context.packageManager],
|
|
7268
|
+
cwd: context.cwd
|
|
7269
|
+
});
|
|
7270
|
+
}
|
|
7271
|
+
await prepareDependencies(context);
|
|
7272
|
+
}
|
|
7273
|
+
|
|
7274
|
+
// src/plugins/setup/context.ts
|
|
7275
|
+
function createWizardContext({
|
|
7276
|
+
imports
|
|
7277
|
+
}) {
|
|
7278
|
+
return {
|
|
7279
|
+
cwd: process.cwd(),
|
|
7280
|
+
imports,
|
|
7281
|
+
createAnswer: () => createCliAnswer({ mode: "closed-list" }),
|
|
7282
|
+
setupController: createSetupController(),
|
|
7283
|
+
checkForUpdates,
|
|
7284
|
+
openUrl: async (url) => {
|
|
7285
|
+
await open(url);
|
|
7286
|
+
},
|
|
7287
|
+
runCommand,
|
|
7288
|
+
packageManager: detectPackageManager(process.cwd()).name,
|
|
7289
|
+
projectLanguage: "typescript"
|
|
7290
|
+
};
|
|
7291
|
+
}
|
|
7292
|
+
var SetupSchema = z.object({}).describe("Set up the Zapier SDK in an existing or new project");
|
|
7293
|
+
function printAuthCommand({
|
|
7294
|
+
context,
|
|
7295
|
+
flow,
|
|
7296
|
+
headless
|
|
7297
|
+
}) {
|
|
7298
|
+
const command = createLocalPackageCommand({
|
|
7299
|
+
packageManager: context.packageManager,
|
|
7300
|
+
binary: "zapier-sdk",
|
|
7301
|
+
args: [flow, ...headless ? ["--headless"] : []]
|
|
7302
|
+
});
|
|
7303
|
+
console.log(`$ ${formatPackageCommand(command)}`);
|
|
7304
|
+
if (headless) {
|
|
7305
|
+
console.log(
|
|
7306
|
+
"Open the printed URL in another browser, then paste the final OAuth callback URL when prompted."
|
|
7307
|
+
);
|
|
7308
|
+
}
|
|
7309
|
+
}
|
|
7310
|
+
function isCredentialWriteError(error) {
|
|
7311
|
+
const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : "";
|
|
7312
|
+
if (/^(eacces|eperm)$/i.test(code)) return true;
|
|
7313
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7314
|
+
return /permission|sandbox|eacces|eperm/i.test(message);
|
|
7315
|
+
}
|
|
7316
|
+
async function authenticate(context) {
|
|
7317
|
+
const activeProfile = await runWithSetupLoader({
|
|
7318
|
+
promise: context.imports.getProfile({}).then(({ data }) => data).catch((error) => {
|
|
7319
|
+
if (isZapierAuthenticationError(error)) return void 0;
|
|
7320
|
+
throw error;
|
|
7321
|
+
}),
|
|
7322
|
+
label: "Checking Zapier authentication"
|
|
7323
|
+
});
|
|
7324
|
+
if (activeProfile) {
|
|
7325
|
+
const shouldLogout = await resolveSetupConfirm({
|
|
7326
|
+
answer: context.createAnswer(),
|
|
7327
|
+
controller: context.setupController,
|
|
7328
|
+
message: `You are already logged in as "${activeProfile.email}".
|
|
7329
|
+
Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
|
|
7330
|
+
Log out and use a different account?`,
|
|
7331
|
+
defaultValue: false
|
|
7332
|
+
});
|
|
7333
|
+
if (!shouldLogout) {
|
|
7334
|
+
context.accountEmail = activeProfile.email;
|
|
7335
|
+
console.log(`Continuing as ${activeProfile.email}.`);
|
|
7336
|
+
return;
|
|
7337
|
+
}
|
|
7338
|
+
const logoutCommand = createLocalPackageCommand({
|
|
7339
|
+
packageManager: context.packageManager,
|
|
7340
|
+
binary: "zapier-sdk",
|
|
7341
|
+
args: ["logout"]
|
|
7342
|
+
});
|
|
7343
|
+
console.log(`$ ${formatPackageCommand(logoutCommand)}`);
|
|
7344
|
+
await context.imports.logout({});
|
|
7345
|
+
}
|
|
7346
|
+
const flow = await resolveSetupSelect({
|
|
7347
|
+
answer: context.createAnswer(),
|
|
7348
|
+
controller: context.setupController,
|
|
7349
|
+
message: "Zapier account:",
|
|
7350
|
+
choices: [
|
|
7351
|
+
{ label: "Log in to an existing account", value: "login" },
|
|
7352
|
+
{ label: "Create a new Zapier account", value: "signup" }
|
|
7353
|
+
]
|
|
7354
|
+
});
|
|
7355
|
+
const environment = await resolveSetupSelect({
|
|
7356
|
+
answer: context.createAnswer(),
|
|
7357
|
+
controller: context.setupController,
|
|
7358
|
+
message: "Environment:",
|
|
7359
|
+
choices: [
|
|
7360
|
+
{ label: "Local machine with a browser", value: "local" },
|
|
7361
|
+
{ label: "Remote or headless", value: "headless" }
|
|
7362
|
+
]
|
|
7363
|
+
});
|
|
7364
|
+
const headless = environment === "headless";
|
|
7365
|
+
const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
|
|
7366
|
+
printAuthCommand({ context, flow, headless });
|
|
7367
|
+
try {
|
|
7368
|
+
await runAuth({ headless });
|
|
7369
|
+
} catch (error) {
|
|
7370
|
+
if (isCredentialWriteError(error)) {
|
|
7371
|
+
console.error(
|
|
7372
|
+
"Authentication could not write credentials. A permissions or sandbox restriction may be blocking disk access."
|
|
7373
|
+
);
|
|
7374
|
+
}
|
|
7375
|
+
throw error;
|
|
7376
|
+
}
|
|
7377
|
+
const { data: profile } = await runWithSetupLoader({
|
|
7378
|
+
promise: context.imports.getProfile({}),
|
|
7379
|
+
label: "Confirming Zapier account"
|
|
7380
|
+
});
|
|
7381
|
+
context.accountEmail = profile.email;
|
|
7382
|
+
console.log(`Authenticated as ${profile.email}.`);
|
|
7383
|
+
}
|
|
7384
|
+
var agentLabels = {
|
|
7385
|
+
claude: "Claude Code",
|
|
7386
|
+
codex: "Codex",
|
|
7387
|
+
cursor: "Cursor",
|
|
7388
|
+
"vscode-copilot": "VS Code Copilot"
|
|
7389
|
+
};
|
|
7390
|
+
function buildAgentPrompt({ context }) {
|
|
7391
|
+
const listConnectionsCommand = formatPackageCommand(
|
|
7392
|
+
createLocalPackageCommand({
|
|
7393
|
+
packageManager: context.packageManager,
|
|
7394
|
+
binary: "zapier-sdk",
|
|
7395
|
+
args: ["list-connections", "--owner", "me", "--json"]
|
|
7396
|
+
})
|
|
7397
|
+
);
|
|
7398
|
+
const listActionsCommand = formatPackageCommand(
|
|
7399
|
+
createLocalPackageCommand({
|
|
7400
|
+
packageManager: context.packageManager,
|
|
7401
|
+
binary: "zapier-sdk",
|
|
7402
|
+
args: ["list-actions", "APP_KEY"]
|
|
7403
|
+
})
|
|
7404
|
+
);
|
|
7405
|
+
return `Start by running this command to discover my active connected apps outside of your sandbox:
|
|
7406
|
+
|
|
7407
|
+
${listConnectionsCommand}
|
|
7408
|
+
|
|
7409
|
+
Using the connected apps returned by that command:
|
|
7410
|
+
|
|
7411
|
+
- Pick 1-3 apps and show commands I can use to explore their actions, such as: ${listActionsCommand}
|
|
7412
|
+
- Do not run those list-actions commands.
|
|
7413
|
+
- Suggest 3 specific ideas based on my connected apps. Each idea should read from one app, optionally process data, and write to another.
|
|
7414
|
+
- Do not suggest event-driven workflows.
|
|
7415
|
+
- Keep each idea to one sentence. Example: "pull in-progress Jira issues and DM yourself a summary on Slack".
|
|
7416
|
+
|
|
7417
|
+
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.`;
|
|
7418
|
+
}
|
|
7419
|
+
function printAgentPrompt({
|
|
7420
|
+
context,
|
|
7421
|
+
message
|
|
7422
|
+
}) {
|
|
7423
|
+
console.log();
|
|
7424
|
+
console.log(chalk8.bgYellow.black.bold(message));
|
|
7425
|
+
console.log();
|
|
7426
|
+
console.log(buildAgentPrompt({ context }));
|
|
7427
|
+
}
|
|
7428
|
+
async function openAgentHandoff(context) {
|
|
7429
|
+
const agent = await resolveSetupSelect({
|
|
7430
|
+
answer: context.createAnswer(),
|
|
7431
|
+
controller: context.setupController,
|
|
7432
|
+
message: "Want to open your agent and have it give you suggestions to start?",
|
|
7433
|
+
choices: [
|
|
7434
|
+
{ label: "No", value: "none" },
|
|
7435
|
+
{ label: "Claude Code", value: "claude" },
|
|
7436
|
+
{ label: "Cursor", value: "cursor" },
|
|
7437
|
+
{ label: "Codex", value: "codex" },
|
|
7438
|
+
{ label: "VS Code Copilot", value: "vscode-copilot" },
|
|
7439
|
+
{ label: "Other", value: "other" }
|
|
7440
|
+
]
|
|
7441
|
+
});
|
|
7442
|
+
if (agent === "none") return;
|
|
7443
|
+
if (agent === "other") {
|
|
7444
|
+
printAgentPrompt({
|
|
7445
|
+
context,
|
|
7446
|
+
message: "Paste this prompt into your AI agent:"
|
|
7447
|
+
});
|
|
7448
|
+
return;
|
|
7449
|
+
}
|
|
7450
|
+
const prompt = buildAgentPrompt({ context });
|
|
7451
|
+
const encodedPrompt = encodeURIComponent(prompt);
|
|
7452
|
+
const encodedPath = encodeURIComponent(context.cwd);
|
|
7453
|
+
try {
|
|
7454
|
+
switch (agent) {
|
|
7455
|
+
case "claude":
|
|
7456
|
+
await context.openUrl(
|
|
7457
|
+
`claude://code/new?q=${encodedPrompt}&folder=${encodedPath}`
|
|
7458
|
+
);
|
|
7459
|
+
break;
|
|
7460
|
+
case "codex":
|
|
7461
|
+
await context.openUrl(
|
|
7462
|
+
`codex://threads/new?prompt=${encodedPrompt}&path=${encodedPath}`
|
|
7463
|
+
);
|
|
7464
|
+
break;
|
|
7465
|
+
case "cursor":
|
|
7466
|
+
await context.runCommand({
|
|
7467
|
+
command: "cursor",
|
|
7468
|
+
args: ["."],
|
|
7469
|
+
cwd: context.cwd,
|
|
7470
|
+
capture: true
|
|
7471
|
+
});
|
|
7472
|
+
console.log(`Cursor opened in ${context.cwd}.`);
|
|
7473
|
+
break;
|
|
7474
|
+
case "vscode-copilot":
|
|
7475
|
+
await context.runCommand({
|
|
7476
|
+
command: "code",
|
|
7477
|
+
args: ["chat", "--mode", "agent", "-"],
|
|
7478
|
+
cwd: context.cwd,
|
|
7479
|
+
input: prompt
|
|
7480
|
+
});
|
|
7481
|
+
break;
|
|
7482
|
+
default: {
|
|
7483
|
+
const unsupportedAgent = agent;
|
|
7484
|
+
throw new Error(`Unsupported agent: ${unsupportedAgent}`);
|
|
7485
|
+
}
|
|
7486
|
+
}
|
|
7487
|
+
} catch {
|
|
7488
|
+
console.warn(
|
|
7489
|
+
`Could not open ${agentLabels[agent]}. Open it manually to continue.`
|
|
7490
|
+
);
|
|
7491
|
+
}
|
|
7492
|
+
printAgentPrompt({
|
|
7493
|
+
context,
|
|
7494
|
+
message: "If it didn't load correctly, paste this prompt into your agent:"
|
|
7495
|
+
});
|
|
7496
|
+
}
|
|
7497
|
+
var CONNECTIONS_URL = "https://zapier.com/app/assets/connections";
|
|
7498
|
+
var CONNECTION_DISPLAY_LIMIT = 10;
|
|
7499
|
+
async function ensureConnectionsAvailable(context) {
|
|
7500
|
+
const page = await runWithSetupLoader({
|
|
7501
|
+
promise: context.imports.listConnections({
|
|
7502
|
+
owner: "me",
|
|
7503
|
+
maxItems: CONNECTION_DISPLAY_LIMIT
|
|
7504
|
+
}),
|
|
7505
|
+
label: "Loading app connections"
|
|
7506
|
+
});
|
|
7507
|
+
if (page.data.length === 0) {
|
|
7508
|
+
console.log(
|
|
7509
|
+
`No active connections found. Connect or reconnect an app at ${CONNECTIONS_URL}, then come back and run setup again.`
|
|
7510
|
+
);
|
|
7511
|
+
throw new ZapierCliExitError(
|
|
7512
|
+
"Setup stopped before completion because no active connections are available."
|
|
7513
|
+
);
|
|
7514
|
+
}
|
|
7515
|
+
const table = new Table({
|
|
7516
|
+
head: ["App", "Connection"],
|
|
7517
|
+
style: { compact: true }
|
|
7518
|
+
});
|
|
7519
|
+
table.push(
|
|
7520
|
+
...page.data.map((connection) => [
|
|
7521
|
+
connection.slug || connection.app_key,
|
|
7522
|
+
connection.title
|
|
7523
|
+
])
|
|
7524
|
+
);
|
|
7525
|
+
console.log(
|
|
7526
|
+
`Active Zapier connections (showing up to ${CONNECTION_DISPLAY_LIMIT}):`
|
|
7527
|
+
);
|
|
7528
|
+
console.log(table.toString());
|
|
7529
|
+
}
|
|
7530
|
+
var CONNECTION_PLACEHOLDER = "__ZAPIER_SDK_SLACK_CONNECTION__";
|
|
7531
|
+
var EMAIL_PLACEHOLDER = "__ZAPIER_SDK_ACCOUNT_EMAIL__";
|
|
7532
|
+
var APP_PLACEHOLDER = "__ZAPIER_SDK_SLACK_APP__";
|
|
7533
|
+
var SLACK_SLUG = "slack";
|
|
7534
|
+
function getSlackTestPath(context) {
|
|
7535
|
+
const extension = context.projectLanguage === "typescript" ? "ts" : "mjs";
|
|
7536
|
+
return join("src", "sdk-demo", `zapier-slack-test.${extension}`);
|
|
7537
|
+
}
|
|
7538
|
+
function getSlackTestTemplatePath(context) {
|
|
7539
|
+
const extension = context.projectLanguage === "typescript" ? "ts" : "mjs";
|
|
7540
|
+
return join(TEMPLATES_DIR, "setup", `zapier-slack-test.${extension}`);
|
|
7541
|
+
}
|
|
7542
|
+
async function findSlackConnection(context) {
|
|
7543
|
+
const page = await runWithSetupLoader({
|
|
7544
|
+
promise: context.imports.listConnections({
|
|
7545
|
+
owner: "me",
|
|
7546
|
+
app: SLACK_SLUG,
|
|
7547
|
+
maxItems: 1
|
|
7548
|
+
}),
|
|
7549
|
+
label: "Looking for a Slack connection"
|
|
7550
|
+
});
|
|
7551
|
+
return page.data.find(({ slug }) => slug === SLACK_SLUG);
|
|
7552
|
+
}
|
|
7553
|
+
function toTemplateString(value) {
|
|
7554
|
+
return JSON.stringify(value).slice(1, -1);
|
|
7555
|
+
}
|
|
7556
|
+
function renderSlackTest({
|
|
7557
|
+
context,
|
|
7558
|
+
app,
|
|
7559
|
+
connection,
|
|
7560
|
+
email
|
|
7561
|
+
}) {
|
|
7562
|
+
return readFileSync(getSlackTestTemplatePath(context), "utf8").replace(APP_PLACEHOLDER, () => toTemplateString(app)).replace(CONNECTION_PLACEHOLDER, () => toTemplateString(connection)).replace(EMAIL_PLACEHOLDER, () => toTemplateString(email));
|
|
7563
|
+
}
|
|
7564
|
+
function writeSlackTest({
|
|
7565
|
+
context,
|
|
7566
|
+
app,
|
|
7567
|
+
connection,
|
|
7568
|
+
email
|
|
7569
|
+
}) {
|
|
7570
|
+
const slackTestPath = getSlackTestPath(context);
|
|
7571
|
+
const path2 = join(context.cwd, slackTestPath);
|
|
7572
|
+
if (!existsSync(dirname(path2))) mkdirSync(dirname(path2), { recursive: true });
|
|
7573
|
+
writeFileSync(path2, renderSlackTest({ context, app, connection, email }));
|
|
7574
|
+
console.log(`Created ${slackTestPath}.`);
|
|
7575
|
+
}
|
|
7576
|
+
async function executeSlackTest(context) {
|
|
7577
|
+
const slackTestPath = getSlackTestPath(context);
|
|
7578
|
+
if (context.projectLanguage === "javascript") {
|
|
7579
|
+
await context.runCommand({
|
|
7580
|
+
command: "node",
|
|
7581
|
+
args: [slackTestPath],
|
|
7582
|
+
cwd: context.cwd,
|
|
7583
|
+
capture: false
|
|
7584
|
+
});
|
|
7585
|
+
return;
|
|
7586
|
+
}
|
|
7587
|
+
const command = context.packageManager === "bun" ? { command: "bun", args: [] } : createLocalPackageCommand({
|
|
7588
|
+
packageManager: context.packageManager,
|
|
7589
|
+
binary: "tsx"
|
|
7590
|
+
});
|
|
7591
|
+
const args = [...command.args, slackTestPath];
|
|
7592
|
+
await context.runCommand({
|
|
7593
|
+
command: command.command,
|
|
7594
|
+
args,
|
|
7595
|
+
cwd: context.cwd,
|
|
7596
|
+
capture: false
|
|
7597
|
+
});
|
|
7598
|
+
}
|
|
7599
|
+
async function trySlackTest(context) {
|
|
7600
|
+
try {
|
|
7601
|
+
await executeSlackTest(context);
|
|
7602
|
+
return true;
|
|
7603
|
+
} catch (error) {
|
|
7604
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7605
|
+
console.warn(`Slack demo failed: ${message}. Setup will continue.`);
|
|
7606
|
+
return false;
|
|
7607
|
+
}
|
|
7608
|
+
}
|
|
7609
|
+
async function offerSlackTest(context) {
|
|
7610
|
+
if (!context.accountEmail) {
|
|
7611
|
+
console.log("No account email found; skipping the Slack demo.");
|
|
7612
|
+
return;
|
|
7613
|
+
}
|
|
7614
|
+
const slackConnection = await findSlackConnection(context);
|
|
7615
|
+
if (!slackConnection) {
|
|
7616
|
+
console.log("No active Slack connection found; skipping the Slack demo.");
|
|
7617
|
+
return;
|
|
7618
|
+
}
|
|
7619
|
+
const slackTestPath = getSlackTestPath(context);
|
|
7620
|
+
const shouldRun = await resolveSetupConfirm({
|
|
7621
|
+
answer: context.createAnswer(),
|
|
7622
|
+
controller: context.setupController,
|
|
7623
|
+
message: `Run the Slack self-DM test using ${context.accountEmail}?`,
|
|
7624
|
+
defaultValue: true
|
|
7625
|
+
});
|
|
7626
|
+
if (!shouldRun) return;
|
|
7627
|
+
const path2 = join(context.cwd, slackTestPath);
|
|
7628
|
+
if (existsSync(path2)) {
|
|
7629
|
+
const shouldOverwrite = await resolveSetupConfirm({
|
|
7630
|
+
answer: context.createAnswer(),
|
|
7631
|
+
controller: context.setupController,
|
|
7632
|
+
message: `${slackTestPath} already exists. Is it okay to overwrite it?`,
|
|
7633
|
+
defaultValue: false
|
|
7634
|
+
});
|
|
7635
|
+
if (!shouldOverwrite) {
|
|
7636
|
+
console.log("Keeping the existing Slack test file.");
|
|
7637
|
+
const shouldRunExisting = await resolveSetupConfirm({
|
|
7638
|
+
answer: context.createAnswer(),
|
|
7639
|
+
controller: context.setupController,
|
|
7640
|
+
message: `Run the existing ${slackTestPath}?`,
|
|
7641
|
+
defaultValue: false
|
|
7642
|
+
});
|
|
7643
|
+
if (shouldRunExisting) await trySlackTest(context);
|
|
7644
|
+
return;
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7647
|
+
let email = context.accountEmail;
|
|
7648
|
+
writeSlackTest({
|
|
7649
|
+
context,
|
|
7650
|
+
app: SLACK_SLUG,
|
|
7651
|
+
connection: slackConnection.id,
|
|
7652
|
+
email
|
|
7653
|
+
});
|
|
7654
|
+
if (await trySlackTest(context)) return;
|
|
7655
|
+
email = await resolveSetupInput({
|
|
7656
|
+
answer: context.createAnswer(),
|
|
7657
|
+
controller: context.setupController,
|
|
7658
|
+
message: "Slack email for one retry after the failed test:"
|
|
7659
|
+
});
|
|
7660
|
+
if (!email) {
|
|
7661
|
+
console.log("Skipping the Slack test.");
|
|
7662
|
+
return;
|
|
7663
|
+
}
|
|
7664
|
+
writeSlackTest({
|
|
7665
|
+
context,
|
|
7666
|
+
app: SLACK_SLUG,
|
|
7667
|
+
connection: slackConnection.id,
|
|
7668
|
+
email
|
|
7669
|
+
});
|
|
7670
|
+
await trySlackTest(context);
|
|
7671
|
+
}
|
|
7672
|
+
|
|
7673
|
+
// src/plugins/setup/skill.ts
|
|
7674
|
+
async function installOptionalSkill(context) {
|
|
7675
|
+
const shouldInstall = await resolveSetupConfirm({
|
|
7676
|
+
answer: context.createAnswer(),
|
|
7677
|
+
controller: context.setupController,
|
|
7678
|
+
message: "Install the optional Zapier SDK skill for extra agent context? This is not required for SDK setup.",
|
|
7679
|
+
defaultValue: true
|
|
7680
|
+
});
|
|
7681
|
+
if (!shouldInstall) {
|
|
7682
|
+
console.log("Skipping the optional Zapier SDK skill.");
|
|
7683
|
+
return;
|
|
7684
|
+
}
|
|
7685
|
+
const command = createPackageRunnerCommand({
|
|
7686
|
+
packageManager: context.packageManager,
|
|
7687
|
+
packageName: "skills",
|
|
7688
|
+
args: ["add", "zapier/sdk", "-y"]
|
|
7689
|
+
});
|
|
7690
|
+
try {
|
|
7691
|
+
await context.runCommand({
|
|
7692
|
+
...command,
|
|
7693
|
+
cwd: context.cwd,
|
|
7694
|
+
capture: true
|
|
7695
|
+
});
|
|
7696
|
+
} catch {
|
|
7697
|
+
console.warn(
|
|
7698
|
+
`Could not install the optional Zapier SDK skill. To install it manually, run: ${formatPackageCommand(command)}`
|
|
7699
|
+
);
|
|
7700
|
+
}
|
|
7701
|
+
}
|
|
7702
|
+
|
|
7703
|
+
// src/plugins/setup/wizard.ts
|
|
7704
|
+
var PHASE_COUNT = 6;
|
|
7705
|
+
var MINIMUM_MESSAGE_WIDTH = 20;
|
|
7706
|
+
var MAXIMUM_MESSAGE_WIDTH = 88;
|
|
7707
|
+
function showPhase({ number, title }) {
|
|
7708
|
+
console.log();
|
|
7709
|
+
console.log(chalk8.bgCyan.black.bold(` ${number}/${PHASE_COUNT} ${title} `));
|
|
7710
|
+
}
|
|
7711
|
+
function printWrapped(text) {
|
|
7712
|
+
const width = Math.max(
|
|
7713
|
+
MINIMUM_MESSAGE_WIDTH,
|
|
7714
|
+
Math.min(
|
|
7715
|
+
process.stdout.columns ?? MAXIMUM_MESSAGE_WIDTH,
|
|
7716
|
+
MAXIMUM_MESSAGE_WIDTH
|
|
7717
|
+
)
|
|
7718
|
+
);
|
|
7719
|
+
console.log(wrapAnsi4(text, width));
|
|
7720
|
+
}
|
|
7721
|
+
function showReadyMessage() {
|
|
7722
|
+
console.log();
|
|
7723
|
+
console.log(chalk8.bgGreen.black.bold(" \u2713 Zapier SDK setup complete "));
|
|
7724
|
+
console.log();
|
|
7725
|
+
printWrapped(
|
|
7726
|
+
"Use active Zapier connections to access 9,000+ app connectors without managing each app's OAuth, token refresh, or retries."
|
|
7727
|
+
);
|
|
7728
|
+
console.log();
|
|
7729
|
+
printWrapped(
|
|
7730
|
+
"To learn more about the Zapier SDK, visit https://docs.zapier.com/sdk"
|
|
7731
|
+
);
|
|
7732
|
+
console.log();
|
|
7733
|
+
}
|
|
7734
|
+
async function runWizard(context) {
|
|
7735
|
+
console.log(chalk8.bold("Zapier SDK setup"));
|
|
7736
|
+
showPhase({ number: 1, title: "Project directory" });
|
|
7737
|
+
await chooseDirectory(context);
|
|
7738
|
+
showPhase({ number: 2, title: "Node.js" });
|
|
7739
|
+
await ensureSupportedNode(context);
|
|
7740
|
+
showPhase({ number: 3, title: "Dependencies" });
|
|
7741
|
+
await prepareProject(context);
|
|
7742
|
+
await installOptionalSkill(context);
|
|
7743
|
+
showPhase({ number: 4, title: "Zapier account" });
|
|
7744
|
+
await authenticate(context);
|
|
7745
|
+
showPhase({ number: 5, title: "App connections" });
|
|
7746
|
+
await ensureConnectionsAvailable(context);
|
|
7747
|
+
showPhase({ number: 6, title: "Slack demo" });
|
|
7748
|
+
await offerSlackTest(context);
|
|
7749
|
+
showReadyMessage();
|
|
7750
|
+
console.log(chalk8.bgCyan.black.bold(" Next steps "));
|
|
7751
|
+
await openAgentHandoff(context);
|
|
7752
|
+
}
|
|
7753
|
+
|
|
7754
|
+
// src/plugins/setup/index.ts
|
|
7755
|
+
var getProfileRef = declareMethod({ id: "getProfile" });
|
|
7756
|
+
var listConnectionsRef2 = declareMethod({ id: "listConnections" });
|
|
7757
|
+
var loginRef = declareMethod({ id: "login" });
|
|
7758
|
+
var logoutRef = declareMethod({ id: "logout" });
|
|
7759
|
+
var signupRef = declareMethod({ id: "signup" });
|
|
7760
|
+
var setupImports = [
|
|
7761
|
+
getProfileRef,
|
|
7762
|
+
listConnectionsRef2,
|
|
7763
|
+
loginRef,
|
|
7764
|
+
logoutRef,
|
|
7765
|
+
signupRef
|
|
7766
|
+
];
|
|
7767
|
+
var setupPlugin = defineMethod({
|
|
7768
|
+
name: "setup",
|
|
7769
|
+
imports: setupImports,
|
|
7770
|
+
categories: ["utility"],
|
|
7771
|
+
supportsJsonOutput: false,
|
|
7772
|
+
inputSchema: SetupSchema,
|
|
7773
|
+
output: "raw",
|
|
7774
|
+
run: async ({ imports }) => {
|
|
7775
|
+
if (process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
|
|
7776
|
+
throw new ZapierCliExitError(
|
|
7777
|
+
"`zapier-sdk setup` requires an interactive terminal."
|
|
7778
|
+
);
|
|
7779
|
+
}
|
|
7780
|
+
await runWizard(createWizardContext({ imports }));
|
|
7781
|
+
}
|
|
7782
|
+
});
|
|
7783
|
+
var CliSkipLeaseExpireError = class extends Error {
|
|
7784
|
+
constructor() {
|
|
7785
|
+
super("user skipped (let lease expire)");
|
|
7786
|
+
this.name = "CliSkipLeaseExpireError";
|
|
7787
|
+
}
|
|
7788
|
+
};
|
|
7789
|
+
function createInteractiveCallback() {
|
|
7790
|
+
let messageNumber = 0;
|
|
7791
|
+
return async (message) => {
|
|
7792
|
+
messageNumber++;
|
|
7793
|
+
const attrs = message.message_attributes;
|
|
7794
|
+
console.log(
|
|
7795
|
+
`
|
|
7796
|
+
${chalk8.bold(`Message #${messageNumber}`)} ${chalk8.dim(message.id)} ${chalk8.dim(`(lease #${attrs.lease_count})`)}`
|
|
7797
|
+
);
|
|
7798
|
+
if (attrs.error_message) {
|
|
7799
|
+
console.log(chalk8.yellow(` upstream error: ${attrs.error_message}`));
|
|
7800
|
+
}
|
|
7801
|
+
if (attrs.possible_duplicate_data) {
|
|
7802
|
+
console.log(chalk8.yellow(" possible duplicate data"));
|
|
7803
|
+
}
|
|
7804
|
+
while (true) {
|
|
7805
|
+
let action;
|
|
7806
|
+
try {
|
|
7807
|
+
const answer = await inquirer.prompt([
|
|
7808
|
+
{
|
|
7809
|
+
type: "list",
|
|
7810
|
+
name: "action",
|
|
7811
|
+
message: "Action?",
|
|
7812
|
+
choices: [
|
|
7813
|
+
{ name: "Ack (remove from inbox)", value: "ack" },
|
|
7814
|
+
{
|
|
7815
|
+
name: "Skip (release after draining)",
|
|
7816
|
+
value: "skip-release"
|
|
7817
|
+
},
|
|
7818
|
+
{ name: "Skip (let lease expire)", value: "skip-expire" },
|
|
7819
|
+
{ name: "View payload", value: "view" },
|
|
7820
|
+
{ name: "Quit", value: "quit" }
|
|
7821
|
+
]
|
|
7822
|
+
}
|
|
7823
|
+
]);
|
|
7824
|
+
action = answer.action;
|
|
7825
|
+
} catch (error) {
|
|
7826
|
+
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
6248
7827
|
throw new ZapierAbortDrainSignal("user pressed Ctrl-C");
|
|
6249
7828
|
}
|
|
6250
7829
|
throw error;
|
|
@@ -6705,7 +8284,7 @@ function renderDeprecationNotices() {
|
|
|
6705
8284
|
function buildBoxLines(message) {
|
|
6706
8285
|
const innerWidth = BOX_WIDTH - 4;
|
|
6707
8286
|
const pad = (line) => `\u2502 ${line.padEnd(innerWidth)} \u2502`;
|
|
6708
|
-
const wrapped =
|
|
8287
|
+
const wrapped = wrapAnsi4(message, innerWidth, { hard: true }).split("\n");
|
|
6709
8288
|
return [
|
|
6710
8289
|
`\u256D${"\u2500".repeat(BOX_WIDTH - 2)}\u256E`,
|
|
6711
8290
|
pad(BOX_TITLE),
|
|
@@ -6718,7 +8297,7 @@ function buildBoxLines(message) {
|
|
|
6718
8297
|
// package.json with { type: 'json' }
|
|
6719
8298
|
var package_default2 = {
|
|
6720
8299
|
name: "@zapier/zapier-sdk-cli",
|
|
6721
|
-
version: "0.
|
|
8300
|
+
version: "0.70.0"};
|
|
6722
8301
|
|
|
6723
8302
|
// src/sdk.ts
|
|
6724
8303
|
var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
|
|
@@ -6758,6 +8337,7 @@ var cliSdkPlugin = definePlugin({
|
|
|
6758
8337
|
mcpPlugin,
|
|
6759
8338
|
getLoginConfigPathPlugin,
|
|
6760
8339
|
initPlugin,
|
|
8340
|
+
setupPlugin,
|
|
6761
8341
|
bundleCodePlugin,
|
|
6762
8342
|
feedbackPlugin,
|
|
6763
8343
|
curlPlugin,
|
|
@@ -6826,6 +8406,7 @@ function createZapierCliSdk2(options = {}) {
|
|
|
6826
8406
|
mcpPlugin,
|
|
6827
8407
|
getLoginConfigPathPlugin,
|
|
6828
8408
|
initPlugin,
|
|
8409
|
+
setupPlugin,
|
|
6829
8410
|
bundleCodePlugin,
|
|
6830
8411
|
feedbackPlugin,
|
|
6831
8412
|
curlPlugin,
|
|
@@ -6910,163 +8491,6 @@ function readEnvSpecs() {
|
|
|
6910
8491
|
if (!raw) return [];
|
|
6911
8492
|
return raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
6912
8493
|
}
|
|
6913
|
-
var ONE_DAY_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
6914
|
-
var CACHE_RESET_INTERVAL_MILLISECONDS = (() => {
|
|
6915
|
-
const {
|
|
6916
|
-
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS,
|
|
6917
|
-
ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS
|
|
6918
|
-
} = process.env;
|
|
6919
|
-
let intervalMs;
|
|
6920
|
-
if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS !== void 0) {
|
|
6921
|
-
const seconds = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_SECONDS);
|
|
6922
|
-
intervalMs = isNaN(seconds) ? NaN : seconds * 1e3;
|
|
6923
|
-
} else if (ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS !== void 0) {
|
|
6924
|
-
intervalMs = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
|
|
6925
|
-
} else {
|
|
6926
|
-
intervalMs = ONE_DAY_MILLISECONDS;
|
|
6927
|
-
}
|
|
6928
|
-
if (isNaN(intervalMs) || intervalMs < 0) {
|
|
6929
|
-
return -1;
|
|
6930
|
-
}
|
|
6931
|
-
return intervalMs;
|
|
6932
|
-
})();
|
|
6933
|
-
function getVersionCache() {
|
|
6934
|
-
try {
|
|
6935
|
-
const cache = getConfig().get("version_cache");
|
|
6936
|
-
const now = Date.now();
|
|
6937
|
-
if (!cache || !cache.last_reset_timestamp || now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MILLISECONDS) {
|
|
6938
|
-
const newCache = {
|
|
6939
|
-
last_reset_timestamp: now,
|
|
6940
|
-
packages: {}
|
|
6941
|
-
};
|
|
6942
|
-
getConfig().set("version_cache", newCache);
|
|
6943
|
-
return newCache;
|
|
6944
|
-
}
|
|
6945
|
-
return cache;
|
|
6946
|
-
} catch (error) {
|
|
6947
|
-
log_default.debug(`Failed to read version cache: ${error}`);
|
|
6948
|
-
return {
|
|
6949
|
-
last_reset_timestamp: Date.now(),
|
|
6950
|
-
packages: {}
|
|
6951
|
-
};
|
|
6952
|
-
}
|
|
6953
|
-
}
|
|
6954
|
-
function setCachedPackageInfo(packageName, version, info) {
|
|
6955
|
-
try {
|
|
6956
|
-
const cache = getVersionCache();
|
|
6957
|
-
if (!cache.packages[packageName]) {
|
|
6958
|
-
cache.packages[packageName] = {};
|
|
6959
|
-
}
|
|
6960
|
-
cache.packages[packageName][version] = info;
|
|
6961
|
-
getConfig().set("version_cache", cache);
|
|
6962
|
-
} catch (error) {
|
|
6963
|
-
log_default.debug(`Failed to cache package info: ${error}`);
|
|
6964
|
-
}
|
|
6965
|
-
}
|
|
6966
|
-
function getCachedPackageInfo(packageName, version) {
|
|
6967
|
-
try {
|
|
6968
|
-
const cache = getVersionCache();
|
|
6969
|
-
return cache.packages[packageName]?.[version];
|
|
6970
|
-
} catch (error) {
|
|
6971
|
-
log_default.debug(`Failed to get cached package info: ${error}`);
|
|
6972
|
-
return void 0;
|
|
6973
|
-
}
|
|
6974
|
-
}
|
|
6975
|
-
async function fetchCachedPackageInfo(packageName, version) {
|
|
6976
|
-
const cacheKey = version || "latest";
|
|
6977
|
-
let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
|
|
6978
|
-
if (cachedInfo) {
|
|
6979
|
-
return cachedInfo;
|
|
6980
|
-
}
|
|
6981
|
-
const packageInfo = await packageJsonLib(packageName, {
|
|
6982
|
-
version,
|
|
6983
|
-
fullMetadata: true
|
|
6984
|
-
});
|
|
6985
|
-
const info = {
|
|
6986
|
-
version: packageInfo.version,
|
|
6987
|
-
deprecated: packageInfo.deprecated,
|
|
6988
|
-
fetched_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6989
|
-
};
|
|
6990
|
-
setCachedPackageInfo(packageName, cacheKey, info);
|
|
6991
|
-
return info;
|
|
6992
|
-
}
|
|
6993
|
-
async function checkForUpdates({
|
|
6994
|
-
packageName,
|
|
6995
|
-
currentVersion
|
|
6996
|
-
}) {
|
|
6997
|
-
try {
|
|
6998
|
-
const latestPackageInfo = await fetchCachedPackageInfo(packageName);
|
|
6999
|
-
const latestVersion = latestPackageInfo.version;
|
|
7000
|
-
const hasUpdate = semver.gt(latestVersion, currentVersion);
|
|
7001
|
-
let currentPackageInfo;
|
|
7002
|
-
try {
|
|
7003
|
-
currentPackageInfo = await fetchCachedPackageInfo(
|
|
7004
|
-
packageName,
|
|
7005
|
-
currentVersion
|
|
7006
|
-
);
|
|
7007
|
-
} catch (error) {
|
|
7008
|
-
if (!(error instanceof VersionNotFoundError)) {
|
|
7009
|
-
log_default.debug(`Failed to check deprecation for current version: ${error}`);
|
|
7010
|
-
}
|
|
7011
|
-
currentPackageInfo = latestPackageInfo;
|
|
7012
|
-
}
|
|
7013
|
-
const isDeprecated = Boolean(currentPackageInfo.deprecated);
|
|
7014
|
-
const deprecationMessage = isDeprecated ? String(currentPackageInfo.deprecated) : void 0;
|
|
7015
|
-
return {
|
|
7016
|
-
hasUpdate,
|
|
7017
|
-
latestVersion,
|
|
7018
|
-
currentVersion,
|
|
7019
|
-
isDeprecated,
|
|
7020
|
-
deprecationMessage
|
|
7021
|
-
};
|
|
7022
|
-
} catch (error) {
|
|
7023
|
-
log_default.debug(`Failed to check for updates: ${error}`);
|
|
7024
|
-
return {
|
|
7025
|
-
hasUpdate: false,
|
|
7026
|
-
currentVersion,
|
|
7027
|
-
isDeprecated: false
|
|
7028
|
-
};
|
|
7029
|
-
}
|
|
7030
|
-
}
|
|
7031
|
-
function displayUpdateNotification(versionInfo, packageName) {
|
|
7032
|
-
if (versionInfo.isDeprecated) {
|
|
7033
|
-
console.error();
|
|
7034
|
-
console.error(
|
|
7035
|
-
chalk8.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.red(
|
|
7036
|
-
` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
|
|
7037
|
-
)
|
|
7038
|
-
);
|
|
7039
|
-
if (versionInfo.deprecationMessage) {
|
|
7040
|
-
console.error(chalk8.red(` ${versionInfo.deprecationMessage}`));
|
|
7041
|
-
}
|
|
7042
|
-
console.error(chalk8.red(` Please update to the latest version.`));
|
|
7043
|
-
console.error();
|
|
7044
|
-
}
|
|
7045
|
-
if (versionInfo.hasUpdate) {
|
|
7046
|
-
console.error();
|
|
7047
|
-
console.error(
|
|
7048
|
-
chalk8.yellow.bold("\u{1F4E6} Update available!") + chalk8.yellow(
|
|
7049
|
-
` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
|
|
7050
|
-
)
|
|
7051
|
-
);
|
|
7052
|
-
console.error(
|
|
7053
|
-
chalk8.yellow(
|
|
7054
|
-
` Run ${chalk8.bold(getUpdateCommand(packageName))} to update.`
|
|
7055
|
-
)
|
|
7056
|
-
);
|
|
7057
|
-
console.error();
|
|
7058
|
-
}
|
|
7059
|
-
}
|
|
7060
|
-
async function checkAndNotifyUpdates({
|
|
7061
|
-
packageName,
|
|
7062
|
-
currentVersion
|
|
7063
|
-
}) {
|
|
7064
|
-
if (CACHE_RESET_INTERVAL_MILLISECONDS < 0) {
|
|
7065
|
-
return;
|
|
7066
|
-
}
|
|
7067
|
-
const versionInfo = await checkForUpdates({ packageName, currentVersion });
|
|
7068
|
-
displayUpdateNotification(versionInfo, packageName);
|
|
7069
|
-
}
|
|
7070
8494
|
var EMOJI_PRESENTATION_PATTERN = /\p{Emoji_Presentation}/u;
|
|
7071
8495
|
var WIDE_CODE_POINT_RANGES = [
|
|
7072
8496
|
[4352, 4447],
|
|
@@ -7170,7 +8594,7 @@ function buildFrameLines(state, frameIndex) {
|
|
|
7170
8594
|
const hasMessages = recentMessages.length > 0;
|
|
7171
8595
|
recentMessages.forEach((message, index) => {
|
|
7172
8596
|
const dimmed = Boolean(state.verdict) || index < recentMessages.length - 1;
|
|
7173
|
-
const segments =
|
|
8597
|
+
const segments = wrapAnsi4(message, bodyTextWidth, { hard: true }).split(
|
|
7174
8598
|
"\n"
|
|
7175
8599
|
);
|
|
7176
8600
|
segments.forEach((segment, segmentIndex) => {
|
|
@@ -7181,7 +8605,7 @@ function buildFrameLines(state, frameIndex) {
|
|
|
7181
8605
|
if (state.streamError) {
|
|
7182
8606
|
if (hasMessages || !state.verdict) content.push("");
|
|
7183
8607
|
content.push(chalk8.bold.red("Approval stream error"));
|
|
7184
|
-
for (const segment of
|
|
8608
|
+
for (const segment of wrapAnsi4(state.streamError, bodyTextWidth, {
|
|
7185
8609
|
hard: true
|
|
7186
8610
|
}).split("\n")) {
|
|
7187
8611
|
content.push(` ${segment}`);
|
|
@@ -7193,7 +8617,7 @@ function buildFrameLines(state, frameIndex) {
|
|
|
7193
8617
|
chalk8.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
|
|
7194
8618
|
);
|
|
7195
8619
|
if (state.verdict.reason) {
|
|
7196
|
-
for (const segment of
|
|
8620
|
+
for (const segment of wrapAnsi4(state.verdict.reason, bodyTextWidth, {
|
|
7197
8621
|
hard: true
|
|
7198
8622
|
}).split("\n")) {
|
|
7199
8623
|
content.push(` ${segment}`);
|