@zapier/zapier-sdk-cli 0.55.6 → 0.55.7
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 +17 -0
- package/README.md +101 -21
- package/dist/cli.cjs +253 -5
- package/dist/cli.mjs +253 -6
- package/dist/experimental.cjs +1 -1
- package/dist/experimental.mjs +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/package.json +5 -2
- package/dist/src/cli.js +6 -1
- package/dist/src/utils/approval-errors.d.ts +1 -0
- package/dist/src/utils/approval-errors.js +9 -0
- package/dist/src/utils/approval-progress.d.ts +12 -0
- package/dist/src/utils/approval-progress.js +179 -0
- package/dist/src/utils/cli-generator.js +4 -1
- package/dist/src/utils/cli-renderer.d.ts +1 -0
- package/dist/src/utils/cli-renderer.js +9 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -4
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command, CommanderError, Option } from 'commander';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { definePlugin, createPluginMethod, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, ZapierReleaseTriggerMessageSignal, injectCliLogin, BaseSdkOptionsSchema, getOrCreateApiClient, isPermanentHttpError, invalidateCachedToken, batch, toSnakeCase, ZapierAbortDrainSignal, createZapierSdkStack as createZapierSdkStack$1, addPlugin as addPlugin$1, ZapierError, isCredentialsObject, buildApplicationLifecycleEvent, ZapierAuthenticationError, isPositional, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } from '@zapier/zapier-sdk';
|
|
4
|
+
import { definePlugin, createPluginMethod, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, ZapierReleaseTriggerMessageSignal, injectCliLogin, BaseSdkOptionsSchema, getOrCreateApiClient, isPermanentHttpError, invalidateCachedToken, batch, toSnakeCase, ZapierAbortDrainSignal, createZapierSdkStack as createZapierSdkStack$1, addPlugin as addPlugin$1, ZapierError, isCredentialsObject, buildApplicationLifecycleEvent, ZapierAuthenticationError, isPositional, runWithTelemetryContext, buildCapabilityMessage, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId, ZapierApprovalError } from '@zapier/zapier-sdk';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
6
|
import search from '@inquirer/search';
|
|
7
7
|
import chalk from 'chalk';
|
|
@@ -33,6 +33,8 @@ import { fileURLToPath } from 'url';
|
|
|
33
33
|
import { injectCliLogin as injectCliLogin$1, createZapierSdkStack, addPlugin } from '@zapier/zapier-sdk/experimental';
|
|
34
34
|
import packageJsonLib, { VersionNotFoundError } from 'package-json';
|
|
35
35
|
import semver from 'semver';
|
|
36
|
+
import React from 'react';
|
|
37
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
36
38
|
|
|
37
39
|
var __defProp = Object.defineProperty;
|
|
38
40
|
var __export = (target, all) => {
|
|
@@ -1531,7 +1533,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
1531
1533
|
|
|
1532
1534
|
// package.json
|
|
1533
1535
|
var package_default = {
|
|
1534
|
-
version: "0.55.
|
|
1536
|
+
version: "0.55.7"};
|
|
1535
1537
|
|
|
1536
1538
|
// src/telemetry/builders.ts
|
|
1537
1539
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1587,6 +1589,11 @@ function buildCliCommandExecutedEvent({
|
|
|
1587
1589
|
subprocess_count: data.subprocess_count ?? null
|
|
1588
1590
|
};
|
|
1589
1591
|
}
|
|
1592
|
+
function getApprovalReason(error) {
|
|
1593
|
+
if (!(error instanceof ZapierApprovalError)) return void 0;
|
|
1594
|
+
const { reason } = error;
|
|
1595
|
+
return typeof reason === "string" && reason.trim().length > 0 ? reason.trim() : void 0;
|
|
1596
|
+
}
|
|
1590
1597
|
function formatJsonOutput(data) {
|
|
1591
1598
|
if (data === void 0) {
|
|
1592
1599
|
return;
|
|
@@ -1727,7 +1734,14 @@ function buildJsonErrors(error) {
|
|
|
1727
1734
|
}
|
|
1728
1735
|
const code = error instanceof ZapierError ? error.code : "UNKNOWN_ERROR";
|
|
1729
1736
|
const message = error instanceof Error ? error.message : String(error);
|
|
1730
|
-
|
|
1737
|
+
const reason = getApprovalReason(error);
|
|
1738
|
+
return [
|
|
1739
|
+
{
|
|
1740
|
+
code,
|
|
1741
|
+
message,
|
|
1742
|
+
...reason ? { reason } : {}
|
|
1743
|
+
}
|
|
1744
|
+
];
|
|
1731
1745
|
}
|
|
1732
1746
|
async function unwrapHttpResponse(response) {
|
|
1733
1747
|
const text = await response.text().catch(() => "[unable to read body]");
|
|
@@ -2368,7 +2382,10 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
2368
2382
|
const commandObj = args[args.length - 1];
|
|
2369
2383
|
const options = commandObj.opts();
|
|
2370
2384
|
const interactiveMode = !options.json;
|
|
2371
|
-
const renderer = interactiveMode ? createInteractiveRenderer({
|
|
2385
|
+
const renderer = interactiveMode ? createInteractiveRenderer({
|
|
2386
|
+
sdk,
|
|
2387
|
+
params: resolvedParams
|
|
2388
|
+
}) : createJsonRenderer();
|
|
2372
2389
|
try {
|
|
2373
2390
|
emitDeprecationWarning({
|
|
2374
2391
|
cliCommandName,
|
|
@@ -7195,7 +7212,7 @@ var watchTriggerInboxCliPlugin = definePlugin(
|
|
|
7195
7212
|
// package.json with { type: 'json' }
|
|
7196
7213
|
var package_default2 = {
|
|
7197
7214
|
name: "@zapier/zapier-sdk-cli",
|
|
7198
|
-
version: "0.55.
|
|
7215
|
+
version: "0.55.7"};
|
|
7199
7216
|
|
|
7200
7217
|
// src/sdk.ts
|
|
7201
7218
|
injectCliLogin(login_exports);
|
|
@@ -7439,6 +7456,232 @@ async function checkAndNotifyUpdates({
|
|
|
7439
7456
|
const versionInfo = await checkForUpdates({ packageName, currentVersion });
|
|
7440
7457
|
displayUpdateNotification(versionInfo, packageName);
|
|
7441
7458
|
}
|
|
7459
|
+
var FALLBACK_PANEL_WIDTH = 72;
|
|
7460
|
+
var MIN_PANEL_WIDTH = 36;
|
|
7461
|
+
var MAX_PANEL_WIDTH = 88;
|
|
7462
|
+
var SPINNER_INTERVAL_MS = 80;
|
|
7463
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
7464
|
+
var inkImportPromise;
|
|
7465
|
+
function loadInk() {
|
|
7466
|
+
inkImportPromise ?? (inkImportPromise = import('ink'));
|
|
7467
|
+
return inkImportPromise;
|
|
7468
|
+
}
|
|
7469
|
+
function createInitialState() {
|
|
7470
|
+
return {
|
|
7471
|
+
messages: [],
|
|
7472
|
+
active: false
|
|
7473
|
+
};
|
|
7474
|
+
}
|
|
7475
|
+
function getPanelWidth() {
|
|
7476
|
+
const terminalColumns = process.stderr.columns;
|
|
7477
|
+
if (!terminalColumns) return FALLBACK_PANEL_WIDTH;
|
|
7478
|
+
return Math.min(
|
|
7479
|
+
Math.max(terminalColumns - 4, MIN_PANEL_WIDTH),
|
|
7480
|
+
MAX_PANEL_WIDTH
|
|
7481
|
+
);
|
|
7482
|
+
}
|
|
7483
|
+
function getPayloadString(event, key) {
|
|
7484
|
+
const value = event.payload?.[key];
|
|
7485
|
+
if (typeof value !== "string") return void 0;
|
|
7486
|
+
const trimmed = value.trim();
|
|
7487
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
7488
|
+
}
|
|
7489
|
+
function getApprovedVerdict(decision, reason) {
|
|
7490
|
+
if (decision !== "approved") return void 0;
|
|
7491
|
+
return {
|
|
7492
|
+
icon: "\u2713",
|
|
7493
|
+
label: "Approved",
|
|
7494
|
+
color: "green",
|
|
7495
|
+
reason
|
|
7496
|
+
};
|
|
7497
|
+
}
|
|
7498
|
+
function Spinner({ text }) {
|
|
7499
|
+
const [frameIndex, setFrameIndex] = React.useState(0);
|
|
7500
|
+
const InkText = text;
|
|
7501
|
+
React.useEffect(() => {
|
|
7502
|
+
const timer = setInterval(() => {
|
|
7503
|
+
setFrameIndex((index) => (index + 1) % SPINNER_FRAMES.length);
|
|
7504
|
+
}, SPINNER_INTERVAL_MS);
|
|
7505
|
+
return () => clearInterval(timer);
|
|
7506
|
+
}, []);
|
|
7507
|
+
return /* @__PURE__ */ jsx(InkText, { color: "yellow", children: `${SPINNER_FRAMES[frameIndex]} Checking approval...` });
|
|
7508
|
+
}
|
|
7509
|
+
function ApprovalProgressView({
|
|
7510
|
+
state,
|
|
7511
|
+
box,
|
|
7512
|
+
text
|
|
7513
|
+
}) {
|
|
7514
|
+
if (!state.active) return null;
|
|
7515
|
+
const InkBox = box;
|
|
7516
|
+
const InkText = text;
|
|
7517
|
+
const recentMessages = state.messages.slice(-5);
|
|
7518
|
+
const hasMessages = recentMessages.length > 0;
|
|
7519
|
+
return /* @__PURE__ */ jsxs(
|
|
7520
|
+
InkBox,
|
|
7521
|
+
{
|
|
7522
|
+
borderColor: "cyan",
|
|
7523
|
+
borderStyle: "round",
|
|
7524
|
+
flexDirection: "column",
|
|
7525
|
+
paddingX: 1,
|
|
7526
|
+
width: getPanelWidth(),
|
|
7527
|
+
children: [
|
|
7528
|
+
/* @__PURE__ */ jsx(InkText, { bold: true, color: "cyan", children: "Approval review" }),
|
|
7529
|
+
/* @__PURE__ */ jsxs(InkBox, { flexDirection: "column", marginTop: 1, children: [
|
|
7530
|
+
!state.verdict && /* @__PURE__ */ jsx(Spinner, { text }),
|
|
7531
|
+
recentMessages.map((message, index) => /* @__PURE__ */ jsxs(InkBox, { flexDirection: "row", children: [
|
|
7532
|
+
/* @__PURE__ */ jsx(InkText, { color: "cyan", children: "> " }),
|
|
7533
|
+
/* @__PURE__ */ jsx(
|
|
7534
|
+
InkText,
|
|
7535
|
+
{
|
|
7536
|
+
dimColor: Boolean(state.verdict) || index < recentMessages.length - 1,
|
|
7537
|
+
wrap: "wrap",
|
|
7538
|
+
children: message
|
|
7539
|
+
}
|
|
7540
|
+
)
|
|
7541
|
+
] }, `${index}-${message}`)),
|
|
7542
|
+
state.streamError && /* @__PURE__ */ jsxs(
|
|
7543
|
+
InkBox,
|
|
7544
|
+
{
|
|
7545
|
+
flexDirection: "column",
|
|
7546
|
+
marginTop: hasMessages || !state.verdict ? 1 : 0,
|
|
7547
|
+
children: [
|
|
7548
|
+
/* @__PURE__ */ jsx(InkText, { bold: true, color: "red", children: "Approval stream error" }),
|
|
7549
|
+
/* @__PURE__ */ jsx(InkText, { wrap: "wrap", children: ` ${state.streamError}` })
|
|
7550
|
+
]
|
|
7551
|
+
}
|
|
7552
|
+
),
|
|
7553
|
+
state.verdict && /* @__PURE__ */ jsxs(
|
|
7554
|
+
InkBox,
|
|
7555
|
+
{
|
|
7556
|
+
flexDirection: "column",
|
|
7557
|
+
marginTop: hasMessages || state.streamError ? 1 : 0,
|
|
7558
|
+
children: [
|
|
7559
|
+
/* @__PURE__ */ jsx(InkText, { bold: true, color: state.verdict.color, children: `${state.verdict.icon} ${state.verdict.label}` }),
|
|
7560
|
+
state.verdict.reason && /* @__PURE__ */ jsx(InkText, { wrap: "wrap", children: ` ${state.verdict.reason}` })
|
|
7561
|
+
]
|
|
7562
|
+
}
|
|
7563
|
+
)
|
|
7564
|
+
] })
|
|
7565
|
+
]
|
|
7566
|
+
}
|
|
7567
|
+
);
|
|
7568
|
+
}
|
|
7569
|
+
function createApprovalProgressRenderer({
|
|
7570
|
+
enabled,
|
|
7571
|
+
onEvent
|
|
7572
|
+
}) {
|
|
7573
|
+
let instance;
|
|
7574
|
+
let currentState = createInitialState();
|
|
7575
|
+
let renderQueue = Promise.resolve();
|
|
7576
|
+
let renderGeneration = 0;
|
|
7577
|
+
let renderEnabled = enabled;
|
|
7578
|
+
let renderErrorReported = false;
|
|
7579
|
+
function update(nextState, { complete = false } = {}) {
|
|
7580
|
+
const generation = renderGeneration;
|
|
7581
|
+
currentState = complete ? createInitialState() : nextState;
|
|
7582
|
+
renderQueue = renderQueue.then(async () => {
|
|
7583
|
+
if (generation !== renderGeneration) return;
|
|
7584
|
+
const { Box, Text, render } = await loadInk();
|
|
7585
|
+
if (generation !== renderGeneration) return;
|
|
7586
|
+
const element = /* @__PURE__ */ jsx(ApprovalProgressView, { state: nextState, box: Box, text: Text });
|
|
7587
|
+
if (!instance) {
|
|
7588
|
+
instance = render(element, {
|
|
7589
|
+
stdout: process.stderr,
|
|
7590
|
+
stderr: process.stderr
|
|
7591
|
+
});
|
|
7592
|
+
} else {
|
|
7593
|
+
instance.rerender(element);
|
|
7594
|
+
}
|
|
7595
|
+
if (complete) {
|
|
7596
|
+
instance.unmount();
|
|
7597
|
+
instance = void 0;
|
|
7598
|
+
}
|
|
7599
|
+
}).catch((error) => {
|
|
7600
|
+
if (generation !== renderGeneration) return;
|
|
7601
|
+
renderEnabled = false;
|
|
7602
|
+
currentState = createInitialState();
|
|
7603
|
+
if (renderErrorReported) return;
|
|
7604
|
+
renderErrorReported = true;
|
|
7605
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7606
|
+
process.stderr.write(`Approval progress unavailable: ${message}
|
|
7607
|
+
`);
|
|
7608
|
+
});
|
|
7609
|
+
}
|
|
7610
|
+
function dismiss() {
|
|
7611
|
+
renderGeneration++;
|
|
7612
|
+
currentState = createInitialState();
|
|
7613
|
+
instance?.unmount();
|
|
7614
|
+
instance = void 0;
|
|
7615
|
+
}
|
|
7616
|
+
return {
|
|
7617
|
+
onEvent(event) {
|
|
7618
|
+
onEvent?.(event);
|
|
7619
|
+
if (!renderEnabled) return;
|
|
7620
|
+
if (event.type === "approval:required") {
|
|
7621
|
+
if (event.payload?.mode !== "auto") return;
|
|
7622
|
+
update({
|
|
7623
|
+
approvalId: getPayloadString(event, "approvalId"),
|
|
7624
|
+
messages: [],
|
|
7625
|
+
active: true
|
|
7626
|
+
});
|
|
7627
|
+
return;
|
|
7628
|
+
}
|
|
7629
|
+
if (event.type === "approval:review_message") {
|
|
7630
|
+
if (!currentState.active) return;
|
|
7631
|
+
const message = getPayloadString(event, "message");
|
|
7632
|
+
if (!message) return;
|
|
7633
|
+
update({
|
|
7634
|
+
...currentState,
|
|
7635
|
+
messages: [...currentState.messages, message]
|
|
7636
|
+
});
|
|
7637
|
+
return;
|
|
7638
|
+
}
|
|
7639
|
+
if (event.type === "approval:review_decision") {
|
|
7640
|
+
if (!currentState.active) return;
|
|
7641
|
+
const verdict = getApprovedVerdict(
|
|
7642
|
+
event.payload?.decision,
|
|
7643
|
+
getPayloadString(event, "reason")
|
|
7644
|
+
);
|
|
7645
|
+
if (!verdict) return;
|
|
7646
|
+
update(
|
|
7647
|
+
{
|
|
7648
|
+
...currentState,
|
|
7649
|
+
verdict
|
|
7650
|
+
},
|
|
7651
|
+
{ complete: true }
|
|
7652
|
+
);
|
|
7653
|
+
return;
|
|
7654
|
+
}
|
|
7655
|
+
if (event.type === "approval:review_stream_error") {
|
|
7656
|
+
if (!currentState.active) return;
|
|
7657
|
+
update({
|
|
7658
|
+
...currentState,
|
|
7659
|
+
streamError: getPayloadString(event, "message") ?? "Approval review stream failed"
|
|
7660
|
+
});
|
|
7661
|
+
return;
|
|
7662
|
+
}
|
|
7663
|
+
if (!currentState.active) return;
|
|
7664
|
+
if (event.type === "approval:approved") {
|
|
7665
|
+
update(
|
|
7666
|
+
{
|
|
7667
|
+
...currentState,
|
|
7668
|
+
verdict: getApprovedVerdict(
|
|
7669
|
+
"approved",
|
|
7670
|
+
getPayloadString(event, "reason")
|
|
7671
|
+
)
|
|
7672
|
+
},
|
|
7673
|
+
{ complete: true }
|
|
7674
|
+
);
|
|
7675
|
+
return;
|
|
7676
|
+
}
|
|
7677
|
+
if (event.type === "approval:denied" || event.type === "approval:failed" || event.type === "approval:timeout" || event.type === "approval:error") {
|
|
7678
|
+
dismiss();
|
|
7679
|
+
}
|
|
7680
|
+
}
|
|
7681
|
+
};
|
|
7682
|
+
}
|
|
7683
|
+
|
|
7684
|
+
// src/cli.ts
|
|
7442
7685
|
var EXIT_GRACE_PERIOD_MS = 500;
|
|
7443
7686
|
var program = new Command();
|
|
7444
7687
|
var versionOption = getReservedCliOption("version" /* Version */);
|
|
@@ -7474,7 +7717,7 @@ for (const [key, fieldSchema] of Object.entries(
|
|
|
7474
7717
|
}
|
|
7475
7718
|
if (inner instanceof z.ZodBoolean && key !== "debug") {
|
|
7476
7719
|
const kebab = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
7477
|
-
const description = fieldSchema.
|
|
7720
|
+
const description = fieldSchema.description ?? inner.description ?? "";
|
|
7478
7721
|
booleanFlags.push({ camelName: key, kebabFlag: `--${kebab}` });
|
|
7479
7722
|
program.option(`--${kebab}`, description);
|
|
7480
7723
|
}
|
|
@@ -7544,6 +7787,9 @@ for (const { camelName, kebabFlag } of booleanFlags) {
|
|
|
7544
7787
|
}
|
|
7545
7788
|
var useExperimental = process.argv.includes("--experimental") || process.env.ZAPIER_EXPERIMENTAL === "1" || process.env.ZAPIER_EXPERIMENTAL === "true";
|
|
7546
7789
|
var createZapierCliSdk3 = useExperimental ? createZapierCliSdk2 : createZapierCliSdk;
|
|
7790
|
+
var approvalProgress = createApprovalProgressRenderer({
|
|
7791
|
+
enabled: process.stderr.isTTY === true
|
|
7792
|
+
});
|
|
7547
7793
|
program.exitOverride();
|
|
7548
7794
|
(async () => {
|
|
7549
7795
|
let exitCode = 0;
|
|
@@ -7556,6 +7802,7 @@ program.exitOverride();
|
|
|
7556
7802
|
maxNetworkRetries,
|
|
7557
7803
|
maxNetworkRetryDelayMs,
|
|
7558
7804
|
maxConcurrentRequests,
|
|
7805
|
+
onEvent: approvalProgress.onEvent,
|
|
7559
7806
|
...flagOverrides,
|
|
7560
7807
|
extensions
|
|
7561
7808
|
});
|
package/dist/experimental.cjs
CHANGED
|
@@ -4590,7 +4590,7 @@ var watchTriggerInboxCliPlugin = zapierSdk.definePlugin(
|
|
|
4590
4590
|
// package.json with { type: 'json' }
|
|
4591
4591
|
var package_default = {
|
|
4592
4592
|
name: "@zapier/zapier-sdk-cli",
|
|
4593
|
-
version: "0.55.
|
|
4593
|
+
version: "0.55.7"};
|
|
4594
4594
|
|
|
4595
4595
|
// src/experimental.ts
|
|
4596
4596
|
experimental.injectCliLogin(login_exports);
|
package/dist/experimental.mjs
CHANGED
|
@@ -4554,7 +4554,7 @@ var watchTriggerInboxCliPlugin = definePlugin(
|
|
|
4554
4554
|
// package.json with { type: 'json' }
|
|
4555
4555
|
var package_default = {
|
|
4556
4556
|
name: "@zapier/zapier-sdk-cli",
|
|
4557
|
-
version: "0.55.
|
|
4557
|
+
version: "0.55.7"};
|
|
4558
4558
|
|
|
4559
4559
|
// src/experimental.ts
|
|
4560
4560
|
injectCliLogin(login_exports);
|
package/dist/index.cjs
CHANGED
|
@@ -4589,7 +4589,7 @@ zapierSdk.definePlugin(
|
|
|
4589
4589
|
// package.json with { type: 'json' }
|
|
4590
4590
|
var package_default = {
|
|
4591
4591
|
name: "@zapier/zapier-sdk-cli",
|
|
4592
|
-
version: "0.55.
|
|
4592
|
+
version: "0.55.7"};
|
|
4593
4593
|
|
|
4594
4594
|
// src/sdk.ts
|
|
4595
4595
|
zapierSdk.injectCliLogin(login_exports);
|
|
@@ -4617,7 +4617,7 @@ function createZapierCliSdk(options = {}) {
|
|
|
4617
4617
|
|
|
4618
4618
|
// package.json
|
|
4619
4619
|
var package_default2 = {
|
|
4620
|
-
version: "0.55.
|
|
4620
|
+
version: "0.55.7"};
|
|
4621
4621
|
|
|
4622
4622
|
// src/telemetry/builders.ts
|
|
4623
4623
|
function createCliBaseEvent(context = {}) {
|
package/dist/index.mjs
CHANGED
|
@@ -4553,7 +4553,7 @@ definePlugin(
|
|
|
4553
4553
|
// package.json with { type: 'json' }
|
|
4554
4554
|
var package_default = {
|
|
4555
4555
|
name: "@zapier/zapier-sdk-cli",
|
|
4556
|
-
version: "0.55.
|
|
4556
|
+
version: "0.55.7"};
|
|
4557
4557
|
|
|
4558
4558
|
// src/sdk.ts
|
|
4559
4559
|
injectCliLogin(login_exports);
|
|
@@ -4581,7 +4581,7 @@ function createZapierCliSdk(options = {}) {
|
|
|
4581
4581
|
|
|
4582
4582
|
// package.json
|
|
4583
4583
|
var package_default2 = {
|
|
4584
|
-
version: "0.55.
|
|
4584
|
+
version: "0.55.7"};
|
|
4585
4585
|
|
|
4586
4586
|
// src/telemetry/builders.ts
|
|
4587
4587
|
function createCliBaseEvent(context = {}) {
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zapier/zapier-sdk-cli",
|
|
3
|
-
"version": "0.55.
|
|
3
|
+
"version": "0.55.7",
|
|
4
4
|
"description": "Command line interface for Zapier SDK",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"access": "public"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@zapier/policy-schema": "0.11.0",
|
|
84
83
|
"@inquirer/search": "^3.2.2",
|
|
84
|
+
"@zapier/policy-schema": "0.11.0",
|
|
85
85
|
"@zapier/zapier-sdk": "workspace:*",
|
|
86
86
|
"@zapier/zapier-sdk-mcp": "workspace:*",
|
|
87
87
|
"chalk": "^5.3.0",
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
"esbuild": "^0.25.5",
|
|
93
93
|
"express": "^5.1.0",
|
|
94
94
|
"handlebars": "^4.7.8",
|
|
95
|
+
"ink": "7.0.5",
|
|
95
96
|
"inquirer": "^12.6.3",
|
|
96
97
|
"is-installed-globally": "^1.0.0",
|
|
97
98
|
"jsonwebtoken": "^9.0.2",
|
|
@@ -100,6 +101,7 @@
|
|
|
100
101
|
"package-json": "^10.0.1",
|
|
101
102
|
"pkce-challenge": "^5.0.0",
|
|
102
103
|
"proper-lockfile": "^4.1.2",
|
|
104
|
+
"react": "19.2.6",
|
|
103
105
|
"semver": "^7.7.3",
|
|
104
106
|
"typescript": "^5.8.3",
|
|
105
107
|
"wrap-ansi": "^10.0.0",
|
|
@@ -111,6 +113,7 @@
|
|
|
111
113
|
"@types/jsonwebtoken": "^9.0.10",
|
|
112
114
|
"@types/node": "^24.0.1",
|
|
113
115
|
"@types/proper-lockfile": "^4.1.4",
|
|
116
|
+
"@types/react": "19.2.15",
|
|
114
117
|
"@types/semver": "^7.7.1",
|
|
115
118
|
"tsup": "^8.5.0",
|
|
116
119
|
"vitest": "^4.1.4"
|
package/dist/src/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ import { checkAndNotifyUpdates } from "./utils/version-checker";
|
|
|
10
10
|
import { BaseSdkOptionsSchema } from "@zapier/zapier-sdk";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { ReservedCliParameter, getReservedCliOption, } from "./utils/cli-options";
|
|
13
|
+
import { createApprovalProgressRenderer } from "./utils/approval-progress";
|
|
13
14
|
const EXIT_GRACE_PERIOD_MS = 500;
|
|
14
15
|
const program = new Command();
|
|
15
16
|
const versionOption = getReservedCliOption(ReservedCliParameter.Version);
|
|
@@ -44,7 +45,7 @@ BaseSdkOptionsSchema.shape)) {
|
|
|
44
45
|
}
|
|
45
46
|
if (inner instanceof z.ZodBoolean && key !== "debug") {
|
|
46
47
|
const kebab = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
47
|
-
const description = fieldSchema.
|
|
48
|
+
const description = fieldSchema.description ?? inner.description ?? "";
|
|
48
49
|
booleanFlags.push({ camelName: key, kebabFlag: `--${kebab}` });
|
|
49
50
|
program.option(`--${kebab}`, description);
|
|
50
51
|
}
|
|
@@ -155,6 +156,9 @@ const useExperimental = process.argv.includes("--experimental") ||
|
|
|
155
156
|
const createZapierCliSdk = useExperimental
|
|
156
157
|
? createExperimentalCliSdk
|
|
157
158
|
: createStableCliSdk;
|
|
159
|
+
const approvalProgress = createApprovalProgressRenderer({
|
|
160
|
+
enabled: process.stderr.isTTY === true,
|
|
161
|
+
});
|
|
158
162
|
// Override Commander's default exit behavior to handle our custom errors
|
|
159
163
|
program.exitOverride();
|
|
160
164
|
(async () => {
|
|
@@ -172,6 +176,7 @@ program.exitOverride();
|
|
|
172
176
|
maxNetworkRetries,
|
|
173
177
|
maxNetworkRetryDelayMs,
|
|
174
178
|
maxConcurrentRequests,
|
|
179
|
+
onEvent: approvalProgress.onEvent,
|
|
175
180
|
...flagOverrides,
|
|
176
181
|
extensions,
|
|
177
182
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getApprovalReason(error: unknown): string | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ZapierApprovalError } from "@zapier/zapier-sdk";
|
|
2
|
+
export function getApprovalReason(error) {
|
|
3
|
+
if (!(error instanceof ZapierApprovalError))
|
|
4
|
+
return undefined;
|
|
5
|
+
const { reason } = error;
|
|
6
|
+
return typeof reason === "string" && reason.trim().length > 0
|
|
7
|
+
? reason.trim()
|
|
8
|
+
: undefined;
|
|
9
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ApprovalProgressEvent {
|
|
2
|
+
type: string;
|
|
3
|
+
payload?: Record<string, unknown>;
|
|
4
|
+
timestamp?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ApprovalProgressRenderer {
|
|
7
|
+
onEvent(event: ApprovalProgressEvent): void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createApprovalProgressRenderer({ enabled, onEvent, }: {
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
onEvent?: (event: ApprovalProgressEvent) => void;
|
|
12
|
+
}): ApprovalProgressRenderer;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
const FALLBACK_PANEL_WIDTH = 72;
|
|
4
|
+
const MIN_PANEL_WIDTH = 36;
|
|
5
|
+
const MAX_PANEL_WIDTH = 88;
|
|
6
|
+
const MAX_VISIBLE_MESSAGES = 5;
|
|
7
|
+
const SPINNER_INTERVAL_MS = 80;
|
|
8
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
9
|
+
let inkImportPromise;
|
|
10
|
+
function loadInk() {
|
|
11
|
+
inkImportPromise ?? (inkImportPromise = import("ink"));
|
|
12
|
+
return inkImportPromise;
|
|
13
|
+
}
|
|
14
|
+
function createInitialState() {
|
|
15
|
+
return {
|
|
16
|
+
messages: [],
|
|
17
|
+
active: false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function getPanelWidth() {
|
|
21
|
+
const terminalColumns = process.stderr.columns;
|
|
22
|
+
if (!terminalColumns)
|
|
23
|
+
return FALLBACK_PANEL_WIDTH;
|
|
24
|
+
return Math.min(Math.max(terminalColumns - 4, MIN_PANEL_WIDTH), MAX_PANEL_WIDTH);
|
|
25
|
+
}
|
|
26
|
+
function getPayloadString(event, key) {
|
|
27
|
+
const value = event.payload?.[key];
|
|
28
|
+
if (typeof value !== "string")
|
|
29
|
+
return undefined;
|
|
30
|
+
const trimmed = value.trim();
|
|
31
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
32
|
+
}
|
|
33
|
+
function getApprovedVerdict(decision, reason) {
|
|
34
|
+
if (decision !== "approved")
|
|
35
|
+
return undefined;
|
|
36
|
+
return {
|
|
37
|
+
icon: "✓",
|
|
38
|
+
label: "Approved",
|
|
39
|
+
color: "green",
|
|
40
|
+
reason,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function Spinner({ text }) {
|
|
44
|
+
const [frameIndex, setFrameIndex] = React.useState(0);
|
|
45
|
+
const InkText = text;
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
const timer = setInterval(() => {
|
|
48
|
+
setFrameIndex((index) => (index + 1) % SPINNER_FRAMES.length);
|
|
49
|
+
}, SPINNER_INTERVAL_MS);
|
|
50
|
+
return () => clearInterval(timer);
|
|
51
|
+
}, []);
|
|
52
|
+
return (_jsx(InkText, { color: "yellow", children: `${SPINNER_FRAMES[frameIndex]} Checking approval...` }));
|
|
53
|
+
}
|
|
54
|
+
function ApprovalProgressView({ state, box, text, }) {
|
|
55
|
+
if (!state.active)
|
|
56
|
+
return null;
|
|
57
|
+
const InkBox = box;
|
|
58
|
+
const InkText = text;
|
|
59
|
+
const recentMessages = state.messages.slice(-MAX_VISIBLE_MESSAGES);
|
|
60
|
+
const hasMessages = recentMessages.length > 0;
|
|
61
|
+
return (_jsxs(InkBox, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", paddingX: 1, width: getPanelWidth(), children: [_jsx(InkText, { bold: true, color: "cyan", children: "Approval review" }), _jsxs(InkBox, { flexDirection: "column", marginTop: 1, children: [!state.verdict && _jsx(Spinner, { text: text }), recentMessages.map((message, index) => (_jsxs(InkBox, { flexDirection: "row", children: [_jsx(InkText, { color: "cyan", children: "> " }), _jsx(InkText, { dimColor: Boolean(state.verdict) || index < recentMessages.length - 1, wrap: "wrap", children: message })] }, `${index}-${message}`))), state.streamError && (_jsxs(InkBox, { flexDirection: "column", marginTop: hasMessages || !state.verdict ? 1 : 0, children: [_jsx(InkText, { bold: true, color: "red", children: "Approval stream error" }), _jsx(InkText, { wrap: "wrap", children: ` ${state.streamError}` })] })), state.verdict && (_jsxs(InkBox, { flexDirection: "column", marginTop: hasMessages || state.streamError ? 1 : 0, children: [_jsx(InkText, { bold: true, color: state.verdict.color, children: `${state.verdict.icon} ${state.verdict.label}` }), state.verdict.reason && (_jsx(InkText, { wrap: "wrap", children: ` ${state.verdict.reason}` }))] }))] })] }));
|
|
62
|
+
}
|
|
63
|
+
export function createApprovalProgressRenderer({ enabled, onEvent, }) {
|
|
64
|
+
let instance;
|
|
65
|
+
let currentState = createInitialState();
|
|
66
|
+
let renderQueue = Promise.resolve();
|
|
67
|
+
let renderGeneration = 0;
|
|
68
|
+
let renderEnabled = enabled;
|
|
69
|
+
let renderErrorReported = false;
|
|
70
|
+
function update(nextState, { complete = false } = {}) {
|
|
71
|
+
const generation = renderGeneration;
|
|
72
|
+
currentState = complete ? createInitialState() : nextState;
|
|
73
|
+
renderQueue = renderQueue
|
|
74
|
+
.then(async () => {
|
|
75
|
+
if (generation !== renderGeneration)
|
|
76
|
+
return;
|
|
77
|
+
const { Box, Text, render } = await loadInk();
|
|
78
|
+
if (generation !== renderGeneration)
|
|
79
|
+
return;
|
|
80
|
+
const element = (_jsx(ApprovalProgressView, { state: nextState, box: Box, text: Text }));
|
|
81
|
+
if (!instance) {
|
|
82
|
+
instance = render(element, {
|
|
83
|
+
stdout: process.stderr,
|
|
84
|
+
stderr: process.stderr,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
instance.rerender(element);
|
|
89
|
+
}
|
|
90
|
+
if (complete) {
|
|
91
|
+
instance.unmount();
|
|
92
|
+
instance = undefined;
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
.catch((error) => {
|
|
96
|
+
if (generation !== renderGeneration)
|
|
97
|
+
return;
|
|
98
|
+
renderEnabled = false;
|
|
99
|
+
currentState = createInitialState();
|
|
100
|
+
if (renderErrorReported)
|
|
101
|
+
return;
|
|
102
|
+
renderErrorReported = true;
|
|
103
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
104
|
+
process.stderr.write(`Approval progress unavailable: ${message}\n`);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function dismiss() {
|
|
108
|
+
renderGeneration++;
|
|
109
|
+
currentState = createInitialState();
|
|
110
|
+
instance?.unmount();
|
|
111
|
+
instance = undefined;
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
onEvent(event) {
|
|
115
|
+
onEvent?.(event);
|
|
116
|
+
if (!renderEnabled)
|
|
117
|
+
return;
|
|
118
|
+
if (event.type === "approval:required") {
|
|
119
|
+
if (event.payload?.mode !== "auto")
|
|
120
|
+
return;
|
|
121
|
+
update({
|
|
122
|
+
approvalId: getPayloadString(event, "approvalId"),
|
|
123
|
+
messages: [],
|
|
124
|
+
active: true,
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (event.type === "approval:review_message") {
|
|
129
|
+
if (!currentState.active)
|
|
130
|
+
return;
|
|
131
|
+
const message = getPayloadString(event, "message");
|
|
132
|
+
if (!message)
|
|
133
|
+
return;
|
|
134
|
+
update({
|
|
135
|
+
...currentState,
|
|
136
|
+
messages: [...currentState.messages, message],
|
|
137
|
+
});
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (event.type === "approval:review_decision") {
|
|
141
|
+
if (!currentState.active)
|
|
142
|
+
return;
|
|
143
|
+
const verdict = getApprovedVerdict(event.payload?.decision, getPayloadString(event, "reason"));
|
|
144
|
+
if (!verdict)
|
|
145
|
+
return;
|
|
146
|
+
update({
|
|
147
|
+
...currentState,
|
|
148
|
+
verdict,
|
|
149
|
+
}, { complete: true });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (event.type === "approval:review_stream_error") {
|
|
153
|
+
if (!currentState.active)
|
|
154
|
+
return;
|
|
155
|
+
update({
|
|
156
|
+
...currentState,
|
|
157
|
+
streamError: getPayloadString(event, "message") ??
|
|
158
|
+
"Approval review stream failed",
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (!currentState.active)
|
|
163
|
+
return;
|
|
164
|
+
if (event.type === "approval:approved") {
|
|
165
|
+
update({
|
|
166
|
+
...currentState,
|
|
167
|
+
verdict: getApprovedVerdict("approved", getPayloadString(event, "reason")),
|
|
168
|
+
}, { complete: true });
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (event.type === "approval:denied" ||
|
|
172
|
+
event.type === "approval:failed" ||
|
|
173
|
+
event.type === "approval:timeout" ||
|
|
174
|
+
event.type === "approval:error") {
|
|
175
|
+
dismiss();
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
@@ -485,7 +485,10 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
|
|
|
485
485
|
// interactiveMode is true by default; --json disables it
|
|
486
486
|
const interactiveMode = !options.json;
|
|
487
487
|
const renderer = interactiveMode
|
|
488
|
-
? createInteractiveRenderer({
|
|
488
|
+
? createInteractiveRenderer({
|
|
489
|
+
sdk,
|
|
490
|
+
params: resolvedParams,
|
|
491
|
+
})
|
|
489
492
|
: createJsonRenderer();
|
|
490
493
|
try {
|
|
491
494
|
emitDeprecationWarning({
|