@zapier/zapier-sdk-cli 0.52.10 → 0.53.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +39 -1
  3. package/dist/cli.cjs +972 -473
  4. package/dist/cli.mjs +973 -474
  5. package/dist/experimental.cjs +914 -424
  6. package/dist/experimental.d.mts +1 -1
  7. package/dist/experimental.d.ts +1 -1
  8. package/dist/experimental.mjs +910 -420
  9. package/dist/index.cjs +914 -424
  10. package/dist/index.d.mts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.mjs +910 -420
  13. package/dist/login.cjs +8 -10
  14. package/dist/login.d.mts +2 -10
  15. package/dist/login.d.ts +2 -10
  16. package/dist/login.mjs +5 -9
  17. package/dist/package.json +1 -1
  18. package/dist/{sdk-B3nKAZdN.d.mts → sdk-SOLizjno.d.mts} +54 -16
  19. package/dist/{sdk-B3nKAZdN.d.ts → sdk-SOLizjno.d.ts} +54 -16
  20. package/dist/src/experimental.js +30 -27
  21. package/dist/src/login/index.d.ts +1 -9
  22. package/dist/src/login/index.js +12 -14
  23. package/dist/src/plugins/add/index.d.ts +15 -15
  24. package/dist/src/plugins/add/index.js +1 -1
  25. package/dist/src/plugins/buildManifest/index.d.ts +2 -2
  26. package/dist/src/plugins/bundleCode/index.d.ts +1 -1
  27. package/dist/src/plugins/bundleCode/index.js +2 -1
  28. package/dist/src/plugins/cliOverrides/index.d.ts +5 -10
  29. package/dist/src/plugins/cliOverrides/index.js +2 -6
  30. package/dist/src/plugins/curl/index.d.ts +2 -2
  31. package/dist/src/plugins/curl/schemas.d.ts +2 -2
  32. package/dist/src/plugins/feedback/index.d.ts +1 -1
  33. package/dist/src/plugins/generateAppTypes/index.d.ts +11 -11
  34. package/dist/src/plugins/getLoginConfigPath/index.d.ts +1 -1
  35. package/dist/src/plugins/index.d.ts +2 -1
  36. package/dist/src/plugins/index.js +2 -1
  37. package/dist/src/plugins/init/index.d.ts +1 -1
  38. package/dist/src/plugins/login/index.d.ts +3 -16
  39. package/dist/src/plugins/login/index.js +3 -191
  40. package/dist/src/plugins/logout/index.d.ts +1 -1
  41. package/dist/src/plugins/mcp/index.d.ts +1 -1
  42. package/dist/src/plugins/signup/index.d.ts +25 -0
  43. package/dist/src/plugins/signup/index.js +12 -0
  44. package/dist/src/plugins/signup/schemas.d.ts +9 -0
  45. package/dist/src/plugins/signup/schemas.js +26 -0
  46. package/dist/src/plugins/signup/test-harness.d.ts +34 -0
  47. package/dist/src/plugins/signup/test-harness.js +74 -0
  48. package/dist/src/sdk.js +32 -20
  49. package/dist/src/types/sdk.d.ts +2 -1
  50. package/dist/src/utils/auth/account-auth.d.ts +32 -0
  51. package/dist/src/utils/auth/account-auth.js +265 -0
  52. package/dist/src/utils/auth/oauth-callback.d.ts +6 -0
  53. package/dist/src/utils/auth/oauth-callback.js +28 -0
  54. package/dist/src/utils/auth/oauth-errors.d.ts +2 -0
  55. package/dist/src/utils/auth/oauth-errors.js +39 -0
  56. package/dist/src/utils/auth/oauth-flow.d.ts +31 -6
  57. package/dist/src/utils/auth/oauth-flow.js +258 -106
  58. package/dist/src/utils/auth/oauth-transaction.d.ts +35 -0
  59. package/dist/src/utils/auth/oauth-transaction.js +69 -0
  60. package/dist/src/utils/cli-generator.js +14 -7
  61. package/dist/src/utils/cli-renderer.d.ts +13 -3
  62. package/dist/src/utils/cli-renderer.js +27 -20
  63. package/dist/src/utils/log.js +9 -4
  64. package/dist/src/utils/non-interactive.d.ts +5 -4
  65. package/dist/src/utils/non-interactive.js +6 -5
  66. package/dist/src/utils/parameter-resolver.js +3 -1
  67. package/dist/src/utils/schema-formatter.d.ts +2 -2
  68. package/dist/src/utils/schema-formatter.js +4 -30
  69. package/dist/src/utils/version-checker.js +8 -3
  70. package/dist/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import type { FunctionRegistryEntry, SdkPage } from "@zapier/zapier-sdk";
1
+ import type { FunctionRegistryEntry, SdkPage, ZapierSdk } from "@zapier/zapier-sdk";
2
2
  export interface JsonErrorEntry {
3
3
  code: string;
4
4
  message: string;
@@ -15,7 +15,7 @@ export interface CliRenderer {
15
15
  maxItems?: number;
16
16
  userSpecifiedMaxItems?: boolean;
17
17
  functionInfo?: FunctionRegistryEntry;
18
- }): void;
18
+ }): Promise<void>;
19
19
  renderItem(value: unknown, options?: {
20
20
  outputFile?: unknown;
21
21
  commandName?: string;
@@ -24,6 +24,16 @@ export interface CliRenderer {
24
24
  renderResponse(response: Response): Promise<void>;
25
25
  renderError(error: unknown): never;
26
26
  }
27
+ /**
28
+ * Per-invocation context the interactive renderer threads into the registry
29
+ * formatter. `sdk` and `params` are passed to `formatter.fetch(...)` so a
30
+ * formatter can enrich items by calling back into the SDK (for example, the
31
+ * table-record formatter resolves field IDs to human-readable names).
32
+ */
33
+ export interface RendererContext {
34
+ sdk?: ZapierSdk;
35
+ params?: Record<string, unknown>;
36
+ }
27
37
  export declare function buildJsonErrors(error: unknown): JsonErrorEntry[];
28
38
  /**
29
39
  * Replacer for JSON.stringify that coerces Error instances to a plain
@@ -38,5 +48,5 @@ export declare function buildJsonErrors(error: unknown): JsonErrorEntry[];
38
48
  */
39
49
  export declare function jsonReplacer(_key: string, value: unknown): unknown;
40
50
  export declare function createJsonRenderer(): CliRenderer;
41
- export declare function createInteractiveRenderer(): CliRenderer;
51
+ export declare function createInteractiveRenderer(context?: RendererContext): CliRenderer;
42
52
  export {};
@@ -93,7 +93,7 @@ export function createJsonRenderer() {
93
93
  errors: [],
94
94
  });
95
95
  },
96
- renderCollectedList(items, _options) {
96
+ async renderCollectedList(items, _options) {
97
97
  outputJson({ data: items, errors: [] });
98
98
  },
99
99
  renderItem(value, options) {
@@ -131,22 +131,29 @@ function getListTitle(functionInfo) {
131
131
  return `Available ${functionInfo.itemType} items`;
132
132
  return "items";
133
133
  }
134
- function renderItemsForDisplay(items, functionInfo, startingNumber = 0) {
135
- if (functionInfo?.inputSchema) {
136
- formatItemsFromSchema(functionInfo, items, startingNumber);
137
- }
138
- else {
139
- items.forEach((item, index) => {
140
- const obj = item;
141
- const name = obj?.name || obj?.key || obj?.id || "Item";
142
- console.log(`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`);
143
- if (obj?.description)
144
- console.log(` ${chalk.dim(String(obj.description))}`);
145
- console.log();
146
- });
134
+ export function createInteractiveRenderer(context = {}) {
135
+ async function renderItemsForDisplay(items, functionInfo, startingNumber = 0) {
136
+ if (functionInfo?.inputSchema) {
137
+ // `formatter` on the registry entry is typed `unknown` so the registry
138
+ // layer stays SDK-agnostic; cast back to the CLI-side shape here at the
139
+ // boundary where we actually use it.
140
+ await formatItemsFromSchema(functionInfo, items, startingNumber, {
141
+ formatter: functionInfo.formatter,
142
+ sdk: context.sdk,
143
+ params: context.params,
144
+ });
145
+ }
146
+ else {
147
+ items.forEach((item, index) => {
148
+ const obj = item;
149
+ const name = obj?.name || obj?.key || obj?.id || "Item";
150
+ console.log(`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`);
151
+ if (obj?.description)
152
+ console.log(` ${chalk.dim(String(obj.description))}`);
153
+ console.log();
154
+ });
155
+ }
147
156
  }
148
- }
149
- export function createInteractiveRenderer() {
150
157
  return {
151
158
  async renderPaginatedList(source, functionInfo) {
152
159
  const itemName = getItemName(functionInfo);
@@ -156,7 +163,7 @@ export function createInteractiveRenderer() {
156
163
  console.log(chalk.yellow(`No ${itemName} found.`));
157
164
  return;
158
165
  }
159
- renderItemsForDisplay(items, functionInfo, 0);
166
+ await renderItemsForDisplay(items, functionInfo, 0);
160
167
  console.log(chalk.green(`\n✅ Showing ${items.length} ${itemName}`));
161
168
  return;
162
169
  }
@@ -176,7 +183,7 @@ export function createInteractiveRenderer() {
176
183
  console.clear();
177
184
  console.log(chalk.blue(`📋 ${getListTitle(functionInfo)}\n`));
178
185
  }
179
- renderItemsForDisplay(items, functionInfo, totalShown);
186
+ await renderItemsForDisplay(items, functionInfo, totalShown);
180
187
  totalShown += items.length;
181
188
  console.log(chalk.green(`\n✅ Showing ${totalShown} ${itemName} (page ${pageCount})`));
182
189
  if (page.nextCursor) {
@@ -197,7 +204,7 @@ export function createInteractiveRenderer() {
197
204
  }
198
205
  console.log(chalk.gray(`\n📄 Finished browsing ${itemName}`));
199
206
  },
200
- renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
207
+ async renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
201
208
  if (!Array.isArray(items)) {
202
209
  formatJsonOutput(items);
203
210
  return;
@@ -208,7 +215,7 @@ export function createInteractiveRenderer() {
208
215
  return;
209
216
  }
210
217
  console.log(chalk.green(`\n✅ Found ${items.length} ${itemName}:\n`));
211
- renderItemsForDisplay(items, functionInfo);
218
+ await renderItemsForDisplay(items, functionInfo);
212
219
  if (userSpecifiedMaxItems && maxItems) {
213
220
  console.log(chalk.gray(`\n📄 Showing up to ${maxItems} ${itemName} (--max-items ${maxItems})`));
214
221
  }
@@ -1,20 +1,25 @@
1
1
  import chalk from "chalk";
2
+ // Every method here writes to stderr. The CLI reserves stdout for the
3
+ // program's data payload (command output, JSON, response bodies); status,
4
+ // info, warnings, errors, and debug all belong on stderr so they don't
5
+ // break callers piping CLI output through jq, > redirect, or JSON.parse.
6
+ // In a TTY both streams interleave, so interactive users see no change.
2
7
  const log = {
3
8
  info: (message, ...args) => {
4
- console.log(chalk.blue("ℹ"), message, ...args);
9
+ console.error(chalk.blue("ℹ"), message, ...args);
5
10
  },
6
11
  error: (message, ...args) => {
7
12
  console.error(chalk.red("✖"), message, ...args);
8
13
  },
9
14
  success: (message, ...args) => {
10
- console.log(chalk.green("✓"), message, ...args);
15
+ console.error(chalk.green("✓"), message, ...args);
11
16
  },
12
17
  warn: (message, ...args) => {
13
- console.log(chalk.yellow("⚠"), message, ...args);
18
+ console.error(chalk.yellow("⚠"), message, ...args);
14
19
  },
15
20
  debug: (message, ...args) => {
16
21
  if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
17
- console.log(chalk.gray("🐛"), message, ...args);
22
+ console.error(chalk.gray("🐛"), message, ...args);
18
23
  }
19
24
  },
20
25
  };
@@ -2,12 +2,13 @@
2
2
  * Resolve whether a CLI invocation should run non-interactively.
3
3
  *
4
4
  * A command is non-interactive when the user explicitly opts out via
5
- * `--non-interactive` / `--skip-prompts`, OR when stdin or stdout isn't a
6
- * TTY (CI, piped output, etc.). The TTY check matters because prompting
7
- * against a non-TTY stream hangs or crashes — every plugin that gates
8
- * inquirer prompts on this flag needs the same answer.
5
+ * `--non-interactive`, OR when stdin or stdout isn't a TTY (CI, piped output,
6
+ * etc.). The TTY check matters because prompting against a non-TTY stream
7
+ * hangs or crashes — every plugin that gates inquirer prompts on this flag
8
+ * needs the same answer.
9
9
  */
10
10
  export declare function resolveNonInteractive(options: {
11
11
  nonInteractive?: boolean;
12
+ /** @deprecated Use `nonInteractive` instead. */
12
13
  skipPrompts?: boolean;
13
14
  }): boolean;
@@ -2,13 +2,14 @@
2
2
  * Resolve whether a CLI invocation should run non-interactively.
3
3
  *
4
4
  * A command is non-interactive when the user explicitly opts out via
5
- * `--non-interactive` / `--skip-prompts`, OR when stdin or stdout isn't a
6
- * TTY (CI, piped output, etc.). The TTY check matters because prompting
7
- * against a non-TTY stream hangs or crashes — every plugin that gates
8
- * inquirer prompts on this flag needs the same answer.
5
+ * `--non-interactive`, OR when stdin or stdout isn't a TTY (CI, piped output,
6
+ * etc.). The TTY check matters because prompting against a non-TTY stream
7
+ * hangs or crashes — every plugin that gates inquirer prompts on this flag
8
+ * needs the same answer.
9
9
  */
10
10
  export function resolveNonInteractive(options) {
11
- return ((options.nonInteractive ?? options.skipPrompts) === true ||
11
+ return (options.nonInteractive === true ||
12
+ options.skipPrompts === true ||
12
13
  !process.stdin.isTTY ||
13
14
  !process.stdout.isTTY);
14
15
  }
@@ -129,7 +129,9 @@ export class SchemaParameterResolver {
129
129
  debugLog(message) {
130
130
  if (this.debug) {
131
131
  this.stopSpinner();
132
- console.log(chalk.gray(`[Zapier CLI] ${message}`));
132
+ // stderr so debug output never pollutes stdout (jq, > redirect,
133
+ // JSON.parse all consume stdout).
134
+ console.error(chalk.gray(`[Zapier CLI] ${message}`));
133
135
  }
134
136
  }
135
137
  startSpinner() {
@@ -1,11 +1,11 @@
1
1
  import type { z } from "zod";
2
2
  import type { OutputFormatter, ZapierSdk } from "@zapier/zapier-sdk";
3
3
  export declare function formatJsonOutput(data: unknown): void;
4
- export declare function formatItemsFromSchema(functionInfo: {
4
+ export declare function formatItemsFromSchema(_functionInfo: {
5
5
  inputSchema: z.ZodType;
6
6
  outputSchema?: z.ZodType;
7
7
  }, items: unknown[], startingNumber?: number, options?: {
8
- formatter?: OutputFormatter;
8
+ formatter?: OutputFormatter<ZapierSdk>;
9
9
  sdk?: ZapierSdk;
10
10
  params?: Record<string, unknown>;
11
11
  }): Promise<void>;
@@ -1,16 +1,6 @@
1
1
  import chalk from "chalk";
2
2
  import util from "util";
3
3
  import wrapAnsi from "wrap-ansi";
4
- // These functions are internal to SDK, implementing basic formatting fallback
5
- // TODO: Consider exposing these utilities or implementing proper CLI formatting
6
- function getFormatMetadata(schema) {
7
- return schema?._zod
8
- ?.def?.formatMeta;
9
- }
10
- function getOutputSchema(schema) {
11
- return schema?._zod?.def
12
- ?.outputSchema;
13
- }
14
4
  // ============================================================================
15
5
  // JSON Formatting
16
6
  // ============================================================================
@@ -25,8 +15,8 @@ export function formatJsonOutput(data) {
25
15
  // ============================================================================
26
16
  // Generic Schema-Driven Formatter
27
17
  // ============================================================================
28
- export async function formatItemsFromSchema(functionInfo, items, startingNumber = 0, options) {
29
- // If a registry-level OutputFormatter is provided, use it
18
+ export async function formatItemsFromSchema(_functionInfo, items, startingNumber = 0, options) {
19
+ // Use the registry-level formatter when the plugin declared one.
30
20
  if (options?.formatter) {
31
21
  let context;
32
22
  if (options.formatter.fetch && options.sdk && options.params) {
@@ -40,24 +30,8 @@ export async function formatItemsFromSchema(functionInfo, items, startingNumber
40
30
  });
41
31
  return;
42
32
  }
43
- // Get the output schema from function info or fall back to input schema output schema
44
- const outputSchema = functionInfo.outputSchema || getOutputSchema(functionInfo.inputSchema);
45
- if (!outputSchema) {
46
- // Fallback to generic formatting if no output schema
47
- formatItemsGeneric(items, startingNumber);
48
- return;
49
- }
50
- const formatMeta = getFormatMetadata(outputSchema);
51
- if (!formatMeta) {
52
- // Fallback to generic formatting if no format metadata
53
- formatItemsGeneric(items, startingNumber);
54
- return;
55
- }
56
- // Format each item using the schema metadata
57
- items.forEach((item, index) => {
58
- const formatted = formatMeta.format(item);
59
- formatSingleItem(formatted, startingNumber + index);
60
- });
33
+ // No formatter declared; fall back to generic field-sniffing.
34
+ formatItemsGeneric(items, startingNumber);
61
35
  }
62
36
  function formatSingleItem(formatted, itemNumber) {
63
37
  // Build the main title line with optional subtitle
@@ -1,4 +1,4 @@
1
- import packageJsonLib from "package-json";
1
+ import packageJsonLib, { VersionNotFoundError } from "package-json";
2
2
  import chalk from "chalk";
3
3
  import log from "./log";
4
4
  import { getConfig } from "../login";
@@ -94,8 +94,13 @@ export async function checkForUpdates({ packageName, currentVersion, }) {
94
94
  currentPackageInfo = await fetchCachedPackageInfo(packageName, currentVersion);
95
95
  }
96
96
  catch (error) {
97
- // If we can't fetch the current version info, use the latest version info
98
- log.debug(`Failed to check deprecation for current version: ${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
+ }
99
104
  currentPackageInfo = latestPackageInfo;
100
105
  }
101
106
  const isDeprecated = Boolean(currentPackageInfo.deprecated);