@zapier/zapier-sdk-cli 0.59.1 → 0.59.2

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.
Files changed (174) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cli.cjs +2 -2
  3. package/dist/cli.mjs +2 -2
  4. package/dist/experimental.cjs +1 -1
  5. package/dist/experimental.mjs +1 -1
  6. package/dist/index.cjs +2 -2
  7. package/dist/index.mjs +2 -2
  8. package/package.json +3 -3
  9. package/dist/package.json +0 -121
  10. package/dist/src/cli.d.ts +0 -2
  11. package/dist/src/cli.js +0 -219
  12. package/dist/src/experimental.d.ts +0 -33
  13. package/dist/src/experimental.js +0 -86
  14. package/dist/src/generators/ast-generator.d.ts +0 -41
  15. package/dist/src/generators/ast-generator.js +0 -405
  16. package/dist/src/index.d.ts +0 -5
  17. package/dist/src/index.js +0 -5
  18. package/dist/src/login/config.d.ts +0 -4
  19. package/dist/src/login/config.js +0 -21
  20. package/dist/src/login/credentials-revoke.d.ts +0 -14
  21. package/dist/src/login/credentials-revoke.js +0 -95
  22. package/dist/src/login/credentials-store.d.ts +0 -60
  23. package/dist/src/login/credentials-store.js +0 -181
  24. package/dist/src/login/filesystem-cache.d.ts +0 -25
  25. package/dist/src/login/filesystem-cache.js +0 -195
  26. package/dist/src/login/index.d.ts +0 -110
  27. package/dist/src/login/index.js +0 -424
  28. package/dist/src/login/keychain.d.ts +0 -18
  29. package/dist/src/login/keychain.js +0 -74
  30. package/dist/src/login/legacy-jwt.d.ts +0 -4
  31. package/dist/src/login/legacy-jwt.js +0 -18
  32. package/dist/src/login.d.ts +0 -10
  33. package/dist/src/login.js +0 -10
  34. package/dist/src/paths.d.ts +0 -1
  35. package/dist/src/paths.js +0 -6
  36. package/dist/src/plugins/add/index.d.ts +0 -254
  37. package/dist/src/plugins/add/index.js +0 -95
  38. package/dist/src/plugins/add/schemas.d.ts +0 -8
  39. package/dist/src/plugins/add/schemas.js +0 -22
  40. package/dist/src/plugins/auth/credentials-base-url.d.ts +0 -11
  41. package/dist/src/plugins/auth/credentials-base-url.js +0 -24
  42. package/dist/src/plugins/buildManifest/index.d.ts +0 -120
  43. package/dist/src/plugins/buildManifest/index.js +0 -71
  44. package/dist/src/plugins/buildManifest/schemas.d.ts +0 -44
  45. package/dist/src/plugins/buildManifest/schemas.js +0 -17
  46. package/dist/src/plugins/bundleCode/index.d.ts +0 -23
  47. package/dist/src/plugins/bundleCode/index.js +0 -62
  48. package/dist/src/plugins/bundleCode/schemas.d.ts +0 -10
  49. package/dist/src/plugins/bundleCode/schemas.js +0 -19
  50. package/dist/src/plugins/cliOverrides/index.d.ts +0 -21
  51. package/dist/src/plugins/cliOverrides/index.js +0 -17
  52. package/dist/src/plugins/curl/index.d.ts +0 -76
  53. package/dist/src/plugins/curl/index.js +0 -236
  54. package/dist/src/plugins/curl/schemas.d.ts +0 -40
  55. package/dist/src/plugins/curl/schemas.js +0 -108
  56. package/dist/src/plugins/curl/utils.d.ts +0 -34
  57. package/dist/src/plugins/curl/utils.js +0 -150
  58. package/dist/src/plugins/drainTriggerInbox/index.d.ts +0 -46
  59. package/dist/src/plugins/drainTriggerInbox/index.js +0 -178
  60. package/dist/src/plugins/feedback/index.d.ts +0 -24
  61. package/dist/src/plugins/feedback/index.js +0 -52
  62. package/dist/src/plugins/feedback/schemas.d.ts +0 -5
  63. package/dist/src/plugins/feedback/schemas.js +0 -8
  64. package/dist/src/plugins/generateAppTypes/index.d.ts +0 -265
  65. package/dist/src/plugins/generateAppTypes/index.js +0 -129
  66. package/dist/src/plugins/generateAppTypes/schemas.d.ts +0 -58
  67. package/dist/src/plugins/generateAppTypes/schemas.js +0 -21
  68. package/dist/src/plugins/getLoginConfigPath/index.d.ts +0 -16
  69. package/dist/src/plugins/getLoginConfigPath/index.js +0 -9
  70. package/dist/src/plugins/getLoginConfigPath/schemas.d.ts +0 -3
  71. package/dist/src/plugins/getLoginConfigPath/schemas.js +0 -5
  72. package/dist/src/plugins/index.d.ts +0 -15
  73. package/dist/src/plugins/index.js +0 -15
  74. package/dist/src/plugins/init/display.d.ts +0 -9
  75. package/dist/src/plugins/init/display.js +0 -72
  76. package/dist/src/plugins/init/index.d.ts +0 -21
  77. package/dist/src/plugins/init/index.js +0 -56
  78. package/dist/src/plugins/init/schemas.d.ts +0 -9
  79. package/dist/src/plugins/init/schemas.js +0 -19
  80. package/dist/src/plugins/init/steps.d.ts +0 -39
  81. package/dist/src/plugins/init/steps.js +0 -141
  82. package/dist/src/plugins/init/types.d.ts +0 -31
  83. package/dist/src/plugins/init/types.js +0 -1
  84. package/dist/src/plugins/init/utils.d.ts +0 -48
  85. package/dist/src/plugins/init/utils.js +0 -135
  86. package/dist/src/plugins/login/index.d.ts +0 -25
  87. package/dist/src/plugins/login/index.js +0 -12
  88. package/dist/src/plugins/login/schemas.d.ts +0 -9
  89. package/dist/src/plugins/login/schemas.js +0 -27
  90. package/dist/src/plugins/logout/index.d.ts +0 -30
  91. package/dist/src/plugins/logout/index.js +0 -33
  92. package/dist/src/plugins/logout/schemas.d.ts +0 -2
  93. package/dist/src/plugins/logout/schemas.js +0 -4
  94. package/dist/src/plugins/mcp/index.d.ts +0 -28
  95. package/dist/src/plugins/mcp/index.js +0 -24
  96. package/dist/src/plugins/mcp/schemas.d.ts +0 -5
  97. package/dist/src/plugins/mcp/schemas.js +0 -10
  98. package/dist/src/plugins/signup/index.d.ts +0 -25
  99. package/dist/src/plugins/signup/index.js +0 -12
  100. package/dist/src/plugins/signup/schemas.d.ts +0 -9
  101. package/dist/src/plugins/signup/schemas.js +0 -26
  102. package/dist/src/plugins/signup/test-harness.d.ts +0 -34
  103. package/dist/src/plugins/signup/test-harness.js +0 -76
  104. package/dist/src/plugins/watchTriggerInbox/index.d.ts +0 -46
  105. package/dist/src/plugins/watchTriggerInbox/index.js +0 -166
  106. package/dist/src/sdk.d.ts +0 -17
  107. package/dist/src/sdk.js +0 -67
  108. package/dist/src/telemetry/builders.d.ts +0 -44
  109. package/dist/src/telemetry/builders.js +0 -59
  110. package/dist/src/telemetry/events.d.ts +0 -40
  111. package/dist/src/telemetry/events.js +0 -4
  112. package/dist/src/types/sdk.d.ts +0 -6
  113. package/dist/src/types/sdk.js +0 -1
  114. package/dist/src/utils/api/client.d.ts +0 -15
  115. package/dist/src/utils/api/client.js +0 -27
  116. package/dist/src/utils/approval-errors.d.ts +0 -1
  117. package/dist/src/utils/approval-errors.js +0 -9
  118. package/dist/src/utils/approval-progress.d.ts +0 -12
  119. package/dist/src/utils/approval-progress.js +0 -179
  120. package/dist/src/utils/auth/account-auth.d.ts +0 -33
  121. package/dist/src/utils/auth/account-auth.js +0 -302
  122. package/dist/src/utils/auth/client-credentials.d.ts +0 -26
  123. package/dist/src/utils/auth/client-credentials.js +0 -67
  124. package/dist/src/utils/auth/oauth-callback.d.ts +0 -6
  125. package/dist/src/utils/auth/oauth-callback.js +0 -28
  126. package/dist/src/utils/auth/oauth-errors.d.ts +0 -2
  127. package/dist/src/utils/auth/oauth-errors.js +0 -39
  128. package/dist/src/utils/auth/oauth-flow.d.ts +0 -37
  129. package/dist/src/utils/auth/oauth-flow.js +0 -313
  130. package/dist/src/utils/auth/oauth-transaction.d.ts +0 -35
  131. package/dist/src/utils/auth/oauth-transaction.js +0 -69
  132. package/dist/src/utils/cli-generator-utils.d.ts +0 -14
  133. package/dist/src/utils/cli-generator-utils.js +0 -122
  134. package/dist/src/utils/cli-generator.d.ts +0 -4
  135. package/dist/src/utils/cli-generator.js +0 -831
  136. package/dist/src/utils/cli-options.d.ts +0 -16
  137. package/dist/src/utils/cli-options.js +0 -34
  138. package/dist/src/utils/cli-renderer.d.ts +0 -53
  139. package/dist/src/utils/cli-renderer.js +0 -265
  140. package/dist/src/utils/constants.d.ts +0 -3
  141. package/dist/src/utils/constants.js +0 -5
  142. package/dist/src/utils/directory-detection.d.ts +0 -5
  143. package/dist/src/utils/directory-detection.js +0 -21
  144. package/dist/src/utils/errors.d.ts +0 -33
  145. package/dist/src/utils/errors.js +0 -36
  146. package/dist/src/utils/extensions.d.ts +0 -20
  147. package/dist/src/utils/extensions.js +0 -66
  148. package/dist/src/utils/getCallablePromise.d.ts +0 -6
  149. package/dist/src/utils/getCallablePromise.js +0 -14
  150. package/dist/src/utils/log.d.ts +0 -8
  151. package/dist/src/utils/log.js +0 -26
  152. package/dist/src/utils/manifest-helpers.d.ts +0 -10
  153. package/dist/src/utils/manifest-helpers.js +0 -19
  154. package/dist/src/utils/non-interactive.d.ts +0 -14
  155. package/dist/src/utils/non-interactive.js +0 -15
  156. package/dist/src/utils/package-manager-detector.d.ts +0 -18
  157. package/dist/src/utils/package-manager-detector.js +0 -72
  158. package/dist/src/utils/parameter-resolver.d.ts +0 -179
  159. package/dist/src/utils/parameter-resolver.js +0 -1554
  160. package/dist/src/utils/retry.d.ts +0 -6
  161. package/dist/src/utils/retry.js +0 -21
  162. package/dist/src/utils/schema-formatter.d.ts +0 -11
  163. package/dist/src/utils/schema-formatter.js +0 -131
  164. package/dist/src/utils/serializeAsync.d.ts +0 -2
  165. package/dist/src/utils/serializeAsync.js +0 -16
  166. package/dist/src/utils/spinner.d.ts +0 -1
  167. package/dist/src/utils/spinner.js +0 -21
  168. package/dist/src/utils/string-utils.d.ts +0 -1
  169. package/dist/src/utils/string-utils.js +0 -6
  170. package/dist/src/utils/triggerDrain.d.ts +0 -144
  171. package/dist/src/utils/triggerDrain.js +0 -351
  172. package/dist/src/utils/version-checker.d.ts +0 -17
  173. package/dist/src/utils/version-checker.js +0 -154
  174. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,351 +0,0 @@
1
- /**
2
- * Shared CLI helpers for the `drain-trigger-inbox` and
3
- * `watch-trigger-inbox` commands. Both wrap the eager SDK callback API
4
- * and dispatch on the same flag set: interactive default (TTY),
5
- * `--exec` (binary + argv, no shell), `--exec-shell` (shell handler),
6
- * `--json` (drain: collect-and-print; watch: NDJSON streaming).
7
- */
8
- import { spawn } from "child_process";
9
- import inquirer from "inquirer";
10
- import chalk from "chalk";
11
- import { ZapierAbortDrainSignal, ZapierReleaseTriggerMessageSignal, } from "@zapier/zapier-sdk";
12
- import { ZapierCliValidationError } from "./errors";
13
- /**
14
- * Marker error thrown by `createInteractiveCallback` when the user
15
- * picks "Skip (let lease expire)". The SDK treats it like any other
16
- * Error subclass — leave-leased per default `releaseOnError: false`
17
- * — so the lease-timeout recovery path is preserved. The CLI uses
18
- * the marker type to distinguish a deliberate skip from an unhandled
19
- * exception when counting summary lines. Not a `ZapierSignal`: the
20
- * SDK's signal-handling auto-releases the message, which is exactly
21
- * what skip-expire does *not* want.
22
- */
23
- export class CliSkipLeaseExpireError extends Error {
24
- constructor() {
25
- super("user skipped (let lease expire)");
26
- this.name = "CliSkipLeaseExpireError";
27
- }
28
- }
29
- /**
30
- * Prompts the user per message. Choices:
31
- *
32
- * - **Ack**: returns normally so the SDK acks the message.
33
- * - **Skip (release after draining)**: throws
34
- * `ZapierReleaseTriggerMessageSignal`. The SDK marks the message for
35
- * release; the actual release call is deferred until the drain
36
- * finishes so the same drain doesn't immediately re-lease it. After
37
- * drain ends, the message returns to `available` for a future drain
38
- * run or another consumer.
39
- * - **Skip (let lease expire)**: throws `CliSkipLeaseExpireError` so
40
- * the SDK leaves the message leased (it's not a `ZapierSignal`,
41
- * so the SDK's catch-all "leave on error" path applies); the lease
42
- * timeout (~5 min default) is the recovery path. Use this when you
43
- * want backpressure on reprocessing. The CLI catches the marker
44
- * to count it as a skip in the drain summary.
45
- * - **Quit**: throws `ZapierAbortDrainSignal` so the SDK stops draining
46
- * after the current batch finishes (in-flight callbacks complete;
47
- * not-yet-started messages in the batch are released).
48
- *
49
- * Ctrl-C during the prompt is translated to `ZapierAbortDrainSignal`
50
- * (same as Quit) — inquirer raises `ExitPromptError`, which we catch
51
- * and re-throw as the abort signal.
52
- */
53
- export function createInteractiveCallback() {
54
- let messageNumber = 0;
55
- return async (message) => {
56
- messageNumber++;
57
- const attrs = message.message_attributes;
58
- console.log(`\n${chalk.bold(`Message #${messageNumber}`)} ${chalk.dim(message.id)} ` +
59
- `${chalk.dim(`(lease #${attrs.lease_count})`)}`);
60
- if (attrs.error_message) {
61
- console.log(chalk.yellow(` upstream error: ${attrs.error_message}`));
62
- }
63
- if (attrs.possible_duplicate_data) {
64
- console.log(chalk.yellow(" possible duplicate data"));
65
- }
66
- while (true) {
67
- let action;
68
- try {
69
- const answer = await inquirer.prompt([
70
- {
71
- type: "list",
72
- name: "action",
73
- message: "Action?",
74
- choices: [
75
- { name: "Ack (remove from inbox)", value: "ack" },
76
- {
77
- name: "Skip (release after draining)",
78
- value: "skip-release",
79
- },
80
- { name: "Skip (let lease expire)", value: "skip-expire" },
81
- { name: "View payload", value: "view" },
82
- { name: "Quit", value: "quit" },
83
- ],
84
- },
85
- ]);
86
- action = answer.action;
87
- }
88
- catch (error) {
89
- // Inquirer raises `ExitPromptError` on Ctrl-C / Ctrl-D / ESC.
90
- // Translate to the SDK abort signal so the drain stops cleanly.
91
- if (error instanceof Error && error.name === "ExitPromptError") {
92
- throw new ZapierAbortDrainSignal("user pressed Ctrl-C");
93
- }
94
- throw error;
95
- }
96
- if (action === "view") {
97
- console.log(chalk.dim(JSON.stringify(message.payload, null, 2)));
98
- continue;
99
- }
100
- if (action === "ack") {
101
- return;
102
- }
103
- if (action === "skip-release") {
104
- throw new ZapierReleaseTriggerMessageSignal("user skipped (release)");
105
- }
106
- if (action === "skip-expire") {
107
- throw new CliSkipLeaseExpireError();
108
- }
109
- if (action === "quit") {
110
- throw new ZapierAbortDrainSignal("user requested quit");
111
- }
112
- }
113
- };
114
- }
115
- /**
116
- * Writes one JSON object per line to stdout (NDJSON) for piping. Acks
117
- * each message after the write resolves; if stdout is closed mid-drain
118
- * (broken pipe), the write throws and the message stays unacked.
119
- *
120
- * The write callback alone provides backpressure: it doesn't fire until
121
- * the chunk is fully committed to the underlying resource, so awaiting
122
- * it pauses the drain when stdout is busy. No separate `drain` listener
123
- * needed — and adding one would race with the callback (drain fires at
124
- * highWaterMark, callback fires after full commit; if drain wins, the
125
- * later callback's error gets dropped on the floor).
126
- */
127
- export function createNdjsonCallback() {
128
- return (message) => new Promise((resolve, reject) => {
129
- process.stdout.write(JSON.stringify(message) + "\n", (err) => {
130
- if (err)
131
- reject(err);
132
- else
133
- resolve();
134
- });
135
- });
136
- }
137
- /**
138
- * Run a subprocess per message, piping the message JSON to the
139
- * subprocess on stdin. Exit code 0 acks the message (resolves);
140
- * non-zero rejects so the SDK leaves it unacked.
141
- *
142
- * When `shell` is true (used by `runShellCommand`), Node picks the
143
- * platform's default shell (`sh` on POSIX, `cmd.exe` on Windows) and
144
- * pipelines/redirects/expansions work everywhere. When false (used by
145
- * `runExecCommand`), the binary is invoked directly with argv passed
146
- * literally — no shell parsing, no glob expansion.
147
- *
148
- * Threads through the abort signal so a Ctrl-C during forever-watch
149
- * cleanly terminates in-flight subprocesses rather than leaving them
150
- * orphaned. On abort, the subprocess is killed and the close-event
151
- * rejects with `ZapierAbortDrainSignal` so the SDK stops cleanly
152
- * rather than recording the kill as a handler error.
153
- */
154
- function runSubprocess(options) {
155
- const { command, args, shell, label, message, signal } = options;
156
- return new Promise((resolve, reject) => {
157
- const child = spawn(command, args, {
158
- shell,
159
- stdio: ["pipe", "inherit", "inherit"],
160
- });
161
- let abortListener;
162
- if (signal) {
163
- if (signal.aborted) {
164
- child.kill();
165
- }
166
- else {
167
- abortListener = () => {
168
- child.kill();
169
- };
170
- signal.addEventListener("abort", abortListener, { once: true });
171
- }
172
- }
173
- child.on("error", (err) => {
174
- if (signal && abortListener) {
175
- signal.removeEventListener("abort", abortListener);
176
- }
177
- reject(err);
178
- });
179
- child.on("close", (code) => {
180
- if (signal && abortListener) {
181
- signal.removeEventListener("abort", abortListener);
182
- }
183
- if (signal?.aborted) {
184
- reject(new ZapierAbortDrainSignal(`${label} aborted`));
185
- return;
186
- }
187
- if (code === 0)
188
- resolve();
189
- else
190
- reject(new Error(`${label} exited with code ${code} for message ${message.id}`));
191
- });
192
- // Subprocess can exit before reading stdin (e.g. `exit 0`), which
193
- // breaks the pipe and surfaces EPIPE on the stdin stream. Exit code
194
- // drives the outcome, so a write racing with subprocess exit isn't
195
- // a failure. Swallow EPIPE; let other errors reject.
196
- child.stdin.on("error", (err) => {
197
- if (err.code !== "EPIPE")
198
- reject(err);
199
- });
200
- child.stdin.end(JSON.stringify(message) + "\n");
201
- });
202
- }
203
- export function runShellCommand(command, message, signal) {
204
- return runSubprocess({
205
- command,
206
- args: [],
207
- shell: true,
208
- label: "exec-shell",
209
- message,
210
- signal,
211
- });
212
- }
213
- /**
214
- * Run a binary per message with no shell interpretation. `argv[0]` is
215
- * the executable; the rest are passed literally as argv to the child.
216
- * Otherwise identical to `runShellCommand`: stdin = message JSON, exit
217
- * code 0 acks, non-zero rejects, abort signal kills the child.
218
- */
219
- export function runExecCommand(argv, message, signal) {
220
- if (argv.length === 0) {
221
- return Promise.reject(new Error("exec requires at least one element (the binary)"));
222
- }
223
- const [command, ...args] = argv;
224
- return runSubprocess({
225
- command,
226
- args,
227
- shell: false,
228
- label: "exec",
229
- message,
230
- signal,
231
- });
232
- }
233
- function describeReason(reason) {
234
- return reason instanceof Error ? reason.message : String(reason);
235
- }
236
- /**
237
- * Print a single per-message error to stderr. Used as the live
238
- * `onError` body so failures surface as they happen (vs accumulated
239
- * and dumped at the end, which is broken for `watch-trigger-inbox`
240
- * where "the end" is Ctrl-C).
241
- */
242
- export function printDrainError(reason, message) {
243
- console.error(chalk.red(`Error processing ${message.id}: ${describeReason(reason)}`));
244
- }
245
- /**
246
- * One-line summary printed when the CLI finished a drain in a mode
247
- * where the data array is uninformative (interactive, exec, exec-shell).
248
- * Both the bounded and forever variants use the same format.
249
- *
250
- * `skipped` is the interactive-mode count of user-driven Skip choices
251
- * (release-after-draining + let-lease-expire). Omitted when zero so the
252
- * subprocess modes — which have no skip semantics — keep their original
253
- * two-part summary.
254
- */
255
- export function printDrainSummary(counts) {
256
- const skipped = counts.skipped ?? 0;
257
- const total = counts.fulfilled + counts.rejected + skipped;
258
- const parts = [`${counts.fulfilled} fulfilled`];
259
- if (skipped > 0)
260
- parts.push(`${skipped} skipped`);
261
- parts.push(`${counts.rejected} rejected`);
262
- console.log(chalk.dim(`\nProcessed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`));
263
- }
264
- /**
265
- * Warn on stderr that interactive mode is overriding an explicit
266
- * `continueOnError: false`. Only fires when the caller (programmatic
267
- * SDK consumer or future flag form that takes `=false`) opted into
268
- * fail-fast — bare `--continue-on-error` flag absence leaves it
269
- * `undefined` and doesn't trigger this. Interactive mode mechanically
270
- * requires continue-on-error: the "Skip (let lease expire)" choice
271
- * throws a plain Error to leave the message leased, and a fail-fast
272
- * drain would tear down on the first skip.
273
- */
274
- export function warnInteractiveContinueOnErrorOverride() {
275
- console.warn(chalk.yellow('Note: continueOnError=false is overridden to true in interactive mode (the "Skip (let lease expire)" choice would otherwise terminate the drain).'));
276
- }
277
- /**
278
- * Throw a CliValidationError if the current process isn't attached to
279
- * a real terminal on both stdin and stdout. Used by the interactive
280
- * default to fail fast with a useful message instead of letting
281
- * inquirer fall over later.
282
- */
283
- export function requireInteractiveTty(commandName) {
284
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
285
- throw new ZapierCliValidationError(`${commandName} needs an interactive terminal by default. ` +
286
- "Pass --exec '<bin>' (with optional `-- args...`) or " +
287
- "--exec-shell '<cmd>' to run a script per message, " +
288
- "or --json for non-interactive output.");
289
- }
290
- }
291
- /**
292
- * Reject more than one of `--exec`, `--exec-shell`, and `--json`.
293
- * Each is a non-interactive output path and choosing implicitly is
294
- * ambiguous.
295
- */
296
- export function rejectExecJsonMutex(opts) {
297
- const picked = [
298
- opts.exec ? "--exec" : null,
299
- opts.execShell ? "--exec-shell" : null,
300
- opts.json ? "--json" : null,
301
- ].filter((x) => x !== null);
302
- if (picked.length > 1) {
303
- throw new ZapierCliValidationError(`${picked.join(", ")} are mutually exclusive. Pick one.`);
304
- }
305
- }
306
- /**
307
- * Pull argv tokens after the first `--` separator out of `process.argv`.
308
- * Returns `[]` when there's no `--`. Used by drain/watch to append
309
- * post-`--` args to the `--exec` binary, mirroring `xargs`, `gh`, and
310
- * `npm run -- ...` semantics.
311
- *
312
- * Read from `process.argv` rather than threading via cli-generator
313
- * because Commander already consumes `--` at parse time and there's
314
- * no per-command API for "the args after `--`" exposed through the
315
- * SDK options object.
316
- */
317
- export function getPostDashArgs(argv = process.argv) {
318
- const idx = argv.indexOf("--");
319
- if (idx === -1)
320
- return [];
321
- return argv.slice(idx + 1);
322
- }
323
- /**
324
- * Combine an optional user signal with an internal one (typically the
325
- * SIGINT controller) into a single AbortSignal that fires when either
326
- * source aborts. Returns a `dispose` to detach the listeners; safe to
327
- * call regardless of whether the combined signal fired.
328
- *
329
- * Plain shape rather than the SDK's `combineAbortSignals`, which works
330
- * over `DisposableAbortSignal` handles and returns a different shape.
331
- */
332
- export function combineSignals(a, b) {
333
- if (!a) {
334
- return { signal: b, dispose: () => undefined };
335
- }
336
- const controller = new AbortController();
337
- const onAbort = () => controller.abort();
338
- if (a.aborted || b.aborted)
339
- controller.abort();
340
- else {
341
- a.addEventListener("abort", onAbort, { once: true });
342
- b.addEventListener("abort", onAbort, { once: true });
343
- }
344
- return {
345
- signal: controller.signal,
346
- dispose: () => {
347
- a.removeEventListener("abort", onAbort);
348
- b.removeEventListener("abort", onAbort);
349
- },
350
- };
351
- }
@@ -1,17 +0,0 @@
1
- interface VersionInfo {
2
- hasUpdate: boolean;
3
- latestVersion?: string;
4
- currentVersion: string;
5
- isDeprecated: boolean;
6
- deprecationMessage?: string;
7
- }
8
- export declare function checkForUpdates({ packageName, currentVersion, }: {
9
- packageName: string;
10
- currentVersion: string;
11
- }): Promise<VersionInfo>;
12
- export declare function displayUpdateNotification(versionInfo: VersionInfo, packageName: string): void;
13
- export declare function checkAndNotifyUpdates({ packageName, currentVersion, }: {
14
- packageName: string;
15
- currentVersion: string;
16
- }): Promise<void>;
17
- export {};
@@ -1,154 +0,0 @@
1
- import packageJsonLib, { VersionNotFoundError } from "package-json";
2
- import chalk from "chalk";
3
- import log from "./log";
4
- import { getConfig } from "../login";
5
- import { getUpdateCommand } from "./package-manager-detector";
6
- import semver from "semver";
7
- const ONE_DAY_MS = 24 * 60 * 60 * 1000;
8
- const CACHE_RESET_INTERVAL_MS = (() => {
9
- const { ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS = `${ONE_DAY_MS}` } = process.env;
10
- const interval = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
11
- if (isNaN(interval) || interval < 0) {
12
- return -1;
13
- }
14
- return interval;
15
- })();
16
- function getVersionCache() {
17
- try {
18
- const cache = getConfig().get("version_cache");
19
- const now = Date.now();
20
- // If no cache, missing timestamp, or it's been more than a day, reset the cache
21
- if (!cache ||
22
- !cache.last_reset_timestamp ||
23
- now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MS) {
24
- const newCache = {
25
- last_reset_timestamp: now,
26
- packages: {},
27
- };
28
- getConfig().set("version_cache", newCache);
29
- return newCache;
30
- }
31
- return cache;
32
- }
33
- catch (error) {
34
- log.debug(`Failed to read version cache: ${error}`);
35
- return {
36
- last_reset_timestamp: Date.now(),
37
- packages: {},
38
- };
39
- }
40
- }
41
- function setCachedPackageInfo(packageName, version, info) {
42
- try {
43
- const cache = getVersionCache();
44
- if (!cache.packages[packageName]) {
45
- cache.packages[packageName] = {};
46
- }
47
- cache.packages[packageName][version] = info;
48
- getConfig().set("version_cache", cache);
49
- }
50
- catch (error) {
51
- log.debug(`Failed to cache package info: ${error}`);
52
- }
53
- }
54
- function getCachedPackageInfo(packageName, version) {
55
- try {
56
- const cache = getVersionCache();
57
- return cache.packages[packageName]?.[version];
58
- }
59
- catch (error) {
60
- log.debug(`Failed to get cached package info: ${error}`);
61
- return undefined;
62
- }
63
- }
64
- async function fetchCachedPackageInfo(packageName, version) {
65
- const cacheKey = version || "latest";
66
- // Try cache first
67
- let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
68
- if (cachedInfo) {
69
- return cachedInfo;
70
- }
71
- // Not in cache, fetch from npm
72
- const packageInfo = await packageJsonLib(packageName, {
73
- version,
74
- fullMetadata: true,
75
- });
76
- const info = {
77
- version: packageInfo.version,
78
- deprecated: packageInfo.deprecated,
79
- fetched_at: new Date().toISOString(),
80
- };
81
- // Cache for next time
82
- setCachedPackageInfo(packageName, cacheKey, info);
83
- return info;
84
- }
85
- export async function checkForUpdates({ packageName, currentVersion, }) {
86
- try {
87
- // Get latest version info (with caching)
88
- const latestPackageInfo = await fetchCachedPackageInfo(packageName);
89
- const latestVersion = latestPackageInfo.version;
90
- const hasUpdate = semver.gt(latestVersion, currentVersion);
91
- // Check deprecation status of the current version (with caching)
92
- let currentPackageInfo;
93
- try {
94
- currentPackageInfo = await fetchCachedPackageInfo(packageName, currentVersion);
95
- }
96
- catch (error) {
97
- // A `VersionNotFoundError` is the normal state during a publish
98
- // pipeline: the running CLI is the very build about to be published,
99
- // so npm doesn't have it yet. Silently fall back to the latest info
100
- // and only log unexpected errors.
101
- if (!(error instanceof VersionNotFoundError)) {
102
- log.debug(`Failed to check deprecation for current version: ${error}`);
103
- }
104
- currentPackageInfo = latestPackageInfo;
105
- }
106
- const isDeprecated = Boolean(currentPackageInfo.deprecated);
107
- const deprecationMessage = isDeprecated
108
- ? String(currentPackageInfo.deprecated)
109
- : undefined;
110
- return {
111
- hasUpdate,
112
- latestVersion,
113
- currentVersion,
114
- isDeprecated,
115
- deprecationMessage,
116
- };
117
- }
118
- catch (error) {
119
- // If we can't check for updates (network issues, etc.), fail silently
120
- log.debug(`Failed to check for updates: ${error}`);
121
- return {
122
- hasUpdate: false,
123
- currentVersion,
124
- isDeprecated: false,
125
- };
126
- }
127
- }
128
- export function displayUpdateNotification(versionInfo, packageName) {
129
- if (versionInfo.isDeprecated) {
130
- console.error();
131
- console.error(chalk.red.bold("⚠️ DEPRECATION WARNING") +
132
- chalk.red(` - ${packageName} v${versionInfo.currentVersion} is deprecated.`));
133
- if (versionInfo.deprecationMessage) {
134
- console.error(chalk.red(` ${versionInfo.deprecationMessage}`));
135
- }
136
- console.error(chalk.red(` Please update to the latest version.`));
137
- console.error();
138
- }
139
- // Use stderr so update notifications don't pollute stdout when piping JSON to jq
140
- if (versionInfo.hasUpdate) {
141
- console.error();
142
- console.error(chalk.yellow.bold("📦 Update available!") +
143
- chalk.yellow(` ${packageName} v${versionInfo.currentVersion} → v${versionInfo.latestVersion}`));
144
- console.error(chalk.yellow(` Run ${chalk.bold(getUpdateCommand(packageName))} to update.`));
145
- console.error();
146
- }
147
- }
148
- export async function checkAndNotifyUpdates({ packageName, currentVersion, }) {
149
- if (CACHE_RESET_INTERVAL_MS < 0) {
150
- return;
151
- }
152
- const versionInfo = await checkForUpdates({ packageName, currentVersion });
153
- displayUpdateNotification(versionInfo, packageName);
154
- }