@zapier/zapier-sdk-cli 0.59.0 → 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 +33 -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 +4 -4
  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,831 +0,0 @@
1
- import { Option } from "commander";
2
- import { z } from "zod";
3
- import { isPositional, runWithCallerContext, } from "@zapier/zapier-sdk";
4
- import { SchemaParameterResolver } from "./parameter-resolver";
5
- import chalk from "chalk";
6
- import inquirer from "inquirer";
7
- import { ZapierCliError, ZapierCliExitError, ZapierCliMissingParametersError, ZapierCliValidationError, } from "./errors";
8
- import { SHARED_COMMAND_CLI_OPTIONS } from "./cli-options";
9
- import { buildCliCommandExecutedEvent } from "../telemetry/builders";
10
- import { createJsonRenderer, createInteractiveRenderer } from "./cli-renderer";
11
- import { toKebabCase } from "./string-utils";
12
- const CLI_COMMAND_EXECUTED_EVENT_SUBJECT = "platform.sdk.CliCommandExecutedEvent";
13
- const PAGINATION_PARAM_NAMES = new Set(["maxItems", "pageSize", "cursor"]);
14
- // Flags whose values may contain secrets and must not appear in telemetry
15
- const SENSITIVE_FLAGS = [
16
- "--credentials",
17
- "--credentials-client-secret",
18
- "--credentials-client-id",
19
- "--credentials-base-url",
20
- "--user",
21
- "--header",
22
- "-H",
23
- "-u",
24
- ];
25
- export function sanitizeCliArguments(args) {
26
- const sanitized = [];
27
- let skipNext = false;
28
- for (const arg of args) {
29
- if (skipNext) {
30
- skipNext = false;
31
- sanitized.push("[REDACTED]");
32
- continue;
33
- }
34
- if (SENSITIVE_FLAGS.some((flag) => arg.startsWith(flag + "="))) {
35
- sanitized.push(arg.split("=")[0] + "=[REDACTED]");
36
- }
37
- else if (SENSITIVE_FLAGS.includes(arg)) {
38
- sanitized.push(arg);
39
- skipNext = true;
40
- }
41
- else {
42
- sanitized.push(arg);
43
- }
44
- }
45
- return sanitized;
46
- }
47
- function getNormalizedResult(result, { isListCommand }) {
48
- if (result instanceof Response) {
49
- return { kind: "response", value: result };
50
- }
51
- if (isListCommand) {
52
- const sdkResult = result;
53
- if (!Array.isArray(sdkResult?.data)) {
54
- throw new Error(`List command returned unexpected shape (expected { data: [] }): ${JSON.stringify(result).slice(0, 200)}`);
55
- }
56
- return {
57
- kind: "list",
58
- data: sdkResult.data,
59
- nextCursor: sdkResult.nextCursor,
60
- };
61
- }
62
- const sdkResult = result;
63
- return {
64
- kind: "item",
65
- value: result !== null && typeof result === "object" && "data" in result
66
- ? sdkResult.data
67
- : result,
68
- };
69
- }
70
- function hasItems(sdkResult) {
71
- return (sdkResult != null &&
72
- typeof sdkResult.items === "function");
73
- }
74
- function hasPages(sdkResult) {
75
- return (sdkResult != null &&
76
- typeof sdkResult[Symbol.asyncIterator] === "function");
77
- }
78
- async function* toItemsStream(sdkResult) {
79
- if (hasItems(sdkResult)) {
80
- yield* sdkResult.items();
81
- return;
82
- }
83
- if (hasPages(sdkResult)) {
84
- for await (const page of sdkResult) {
85
- yield* page.data ?? [];
86
- }
87
- return;
88
- }
89
- throw new ZapierCliExitError(`SDK method returned a value that is not async-iterable. Got: ${typeof sdkResult}. ` +
90
- `List methods must return an AsyncIterable or an object with an items() method.`, 1);
91
- }
92
- async function collectItemsFromResult({ sdkResult, maxItems, }) {
93
- const items = [];
94
- for await (const item of toItemsStream(sdkResult)) {
95
- items.push(item);
96
- if (maxItems !== undefined && items.length >= maxItems)
97
- break;
98
- }
99
- return maxItems !== undefined ? items.slice(0, maxItems) : items;
100
- }
101
- const CONFIRM_MESSAGES = {
102
- "create-secret": {
103
- messageBefore: "You are about to create a sensitive secret that will be displayed as plain text.\n" +
104
- "Once created, you cannot retrieve it again.",
105
- messageAfter: "Please treat this secret like a password and store it securely!",
106
- },
107
- delete: (itemType) => ({
108
- messageBefore: `You are about to delete the ${itemType || "item"}.`,
109
- }),
110
- };
111
- async function promptConfirm(confirmType, itemType) {
112
- if (!confirmType || !CONFIRM_MESSAGES[confirmType]) {
113
- return { confirmed: true }; // No confirmation needed
114
- }
115
- const configOrFn = CONFIRM_MESSAGES[confirmType];
116
- const { messageBefore, messageAfter } = typeof configOrFn === "function" ? configOrFn(itemType) : configOrFn;
117
- console.log(chalk.yellow(`\n${messageBefore}\n`));
118
- const { confirmed } = await inquirer.prompt([
119
- {
120
- type: "confirm",
121
- name: "confirmed",
122
- message: "Continue?",
123
- default: false,
124
- },
125
- ]);
126
- return { confirmed, messageAfter };
127
- }
128
- function emitDeprecationWarning({ cliCommandName, deprecation, }) {
129
- if (!deprecation) {
130
- return;
131
- }
132
- console.warn();
133
- console.warn(chalk.yellow.bold("⚠️ DEPRECATION WARNING") +
134
- chalk.yellow(` - \`${cliCommandName}\` is deprecated.`));
135
- console.warn(chalk.yellow(` ${deprecation.message}`));
136
- console.warn();
137
- }
138
- function emitParamDeprecationWarnings({ options, parameters, }) {
139
- for (const param of parameters) {
140
- if (!param.isDeprecated)
141
- continue;
142
- const value = options[param.name];
143
- if (value === undefined)
144
- continue;
145
- if (Array.isArray(value) && value.length === 0)
146
- continue;
147
- console.warn();
148
- console.warn(chalk.yellow.bold("⚠️ DEPRECATION WARNING") +
149
- chalk.yellow(` - \`${toKebabCase(param.name)}\` is deprecated and may be removed in a future release.`));
150
- if (param.deprecationMessage) {
151
- console.warn(chalk.yellow(` ${param.deprecationMessage}`));
152
- }
153
- console.warn();
154
- }
155
- }
156
- function resolveOutputMode({ isListCommand, hasPaginationParams, hasUserSpecifiedMaxItems, }) {
157
- if (!isListCommand || !hasPaginationParams)
158
- return "single";
159
- if (hasUserSpecifiedMaxItems)
160
- return "collect";
161
- return "paginate";
162
- }
163
- /** Extract the aliases map from a schema's metadata (e.g., { appKey: "app" }). */
164
- function getSchemaAliases(schema) {
165
- return schema?.meta?.()?.aliases;
166
- }
167
- // ============================================================================
168
- // Schema Analysis
169
- // ============================================================================
170
- function analyzeZodSchema(schema, functionInfo) {
171
- const parameters = [];
172
- // Handle ZodEffects (schemas with .refine(), .transform(), etc.)
173
- // In Zod, effects have type "effect" and inner schema is accessed via innerType
174
- const schemaDef = schema._zod?.def;
175
- if (schemaDef?.type === "effect" && schemaDef.innerType) {
176
- return analyzeZodSchema(schemaDef.innerType, functionInfo);
177
- }
178
- if (schema instanceof z.ZodObject) {
179
- const shape = schema.shape;
180
- for (const [key, fieldSchema] of Object.entries(shape)) {
181
- const param = analyzeZodField(key, fieldSchema, functionInfo);
182
- if (param) {
183
- parameters.push(param);
184
- }
185
- }
186
- }
187
- return parameters;
188
- }
189
- function analyzeZodField(name, schema, functionInfo) {
190
- let baseSchema = schema;
191
- let required = true;
192
- let defaultValue = undefined;
193
- let isDeprecated = false;
194
- let deprecationMessage;
195
- // Unwrap optional, default, and nullable wrappers - keep unwrapping until we get to the base type.
196
- // Check .meta()?.deprecated at each level since it doesn't propagate through wrappers.
197
- while (true) {
198
- const meta = baseSchema.meta?.();
199
- if (meta?.deprecated) {
200
- isDeprecated = true;
201
- }
202
- if (meta?.deprecationMessage && !deprecationMessage) {
203
- deprecationMessage = meta.deprecationMessage;
204
- }
205
- if (baseSchema instanceof z.ZodOptional) {
206
- required = false;
207
- baseSchema = baseSchema._zod.def.innerType;
208
- }
209
- else if (baseSchema instanceof z.ZodDefault) {
210
- required = false;
211
- const defValue = baseSchema._zod.def.defaultValue;
212
- defaultValue = typeof defValue === "function" ? defValue() : defValue;
213
- baseSchema = baseSchema._zod.def.innerType;
214
- }
215
- else {
216
- // Check for ZodNullable - nullable doesn't affect CLI required status, but we need to unwrap it to get the base type
217
- // Use _zod.def.type for Zod 4 compatibility (matches patterns elsewhere in codebase)
218
- const zodDef = baseSchema._zod?.def;
219
- if (zodDef?.type === "nullable" && zodDef.innerType) {
220
- baseSchema = zodDef.innerType;
221
- continue;
222
- }
223
- // No more wrappers to unwrap
224
- break;
225
- }
226
- }
227
- // Some schema kinds aren't expressible as CLI flags and would
228
- // otherwise fall through to a bogus `--name <string>` flag:
229
- // - z.function() — onMessage / onError-style callbacks
230
- // - z.custom<AbortSignal>() and other custom predicates — passed
231
- // programmatically by callers, or filled in by a CLI-side
232
- // decorator plugin (closure-capture + override).
233
- // Skip them so the auto-generated CLI surface stays clean.
234
- const baseSchemaDef = baseSchema._zod?.def;
235
- if (baseSchema instanceof z.ZodFunction || baseSchemaDef?.type === "custom") {
236
- return null;
237
- }
238
- // Determine parameter type
239
- let paramType = "string";
240
- let elementType;
241
- let choices;
242
- if (baseSchema instanceof z.ZodString) {
243
- paramType = "string";
244
- }
245
- else if (baseSchema instanceof z.ZodNumber) {
246
- paramType = "number";
247
- }
248
- else if (baseSchema instanceof z.ZodBoolean) {
249
- paramType = "boolean";
250
- }
251
- else if (baseSchema instanceof z.ZodArray) {
252
- paramType = "array";
253
- const elementSchema = baseSchema._zod.def.element;
254
- if (elementSchema instanceof z.ZodObject ||
255
- elementSchema instanceof z.ZodRecord) {
256
- elementType = "object";
257
- }
258
- else if (elementSchema instanceof z.ZodNumber) {
259
- elementType = "number";
260
- }
261
- else if (elementSchema instanceof z.ZodBoolean) {
262
- elementType = "boolean";
263
- }
264
- }
265
- else if (baseSchema instanceof z.ZodEnum) {
266
- paramType = "string";
267
- choices = baseSchema.options;
268
- }
269
- else if (baseSchema instanceof z.ZodObject ||
270
- baseSchema instanceof z.ZodRecord) {
271
- // User passes a JSON string; convertValue will parse it to an object
272
- paramType = "object";
273
- }
274
- // Check if this parameter has a resolver
275
- let paramHasResolver = false;
276
- // Check function-specific resolvers first
277
- if (functionInfo?.resolvers?.[name]) {
278
- paramHasResolver = true;
279
- }
280
- // Extract resolver metadata
281
- return {
282
- name,
283
- type: paramType,
284
- required,
285
- description: schema.description,
286
- default: defaultValue,
287
- choices,
288
- hasResolver: paramHasResolver,
289
- isPositional: isPositional(schema),
290
- elementType,
291
- deprecationMessage,
292
- isDeprecated,
293
- };
294
- }
295
- /**
296
- * Analyze inputParameters (used by multi-parameter functions like fetch) into flat CLI parameters.
297
- * Simple-type params become positional args; object-type params have their properties flattened into flags.
298
- */
299
- function analyzeInputParameters(inputParameters, functionInfo) {
300
- const cliParams = [];
301
- for (const param of inputParameters) {
302
- let schema = param.schema;
303
- let isOptional = false;
304
- // Unwrap optional wrapper
305
- if (schema instanceof z.ZodOptional) {
306
- isOptional = true;
307
- schema = schema._zod.def.innerType;
308
- }
309
- if (schema instanceof z.ZodObject) {
310
- // Flatten object properties into individual CLI flags
311
- const shape = schema.shape;
312
- for (const [key, fieldSchema] of Object.entries(shape)) {
313
- const analyzed = analyzeZodField(key, fieldSchema, functionInfo);
314
- if (analyzed) {
315
- if (isOptional) {
316
- analyzed.required = false;
317
- }
318
- cliParams.push(analyzed);
319
- }
320
- }
321
- }
322
- else {
323
- // Simple type — treat as positional argument
324
- const analyzed = analyzeZodField(param.name, param.schema, functionInfo);
325
- if (analyzed) {
326
- analyzed.required = !isOptional;
327
- analyzed.isPositional = true;
328
- cliParams.push(analyzed);
329
- }
330
- }
331
- }
332
- return cliParams;
333
- }
334
- /**
335
- * Reconstruct positional arguments for SDK invocation from a flat params record.
336
- * Used when calling multi-parameter SDK functions (inputParameters) from the CLI.
337
- */
338
- function reconstructPositionalArgs(inputParameters, flatParams) {
339
- const args = [];
340
- for (const param of inputParameters) {
341
- let schema = param.schema;
342
- if (schema instanceof z.ZodOptional) {
343
- schema = schema._zod.def.innerType;
344
- }
345
- if (schema instanceof z.ZodObject) {
346
- const shape = schema.shape;
347
- const obj = {};
348
- let hasValues = false;
349
- for (const key of Object.keys(shape)) {
350
- if (key in flatParams && flatParams[key] !== undefined) {
351
- obj[key] = flatParams[key];
352
- hasValues = true;
353
- }
354
- }
355
- args.push(hasValues ? obj : undefined);
356
- }
357
- else {
358
- args.push(flatParams[param.name]);
359
- }
360
- }
361
- return args;
362
- }
363
- // ============================================================================
364
- // CLI Structure Derivation - Purely Generic
365
- // ============================================================================
366
- /**
367
- * Convert SDK method name directly to CLI command
368
- * e.g., listApps -> list-apps, getApp -> get-app, generateTypes -> generate-types
369
- */
370
- function methodNameToCliCommand(methodName) {
371
- return toKebabCase(methodName);
372
- }
373
- // ============================================================================
374
- // CLI Command Generation - Completely Generic
375
- // ============================================================================
376
- export function generateCliCommands(program, sdk) {
377
- // Check if SDK has registry
378
- if (typeof sdk.getRegistry !== "function") {
379
- console.error("SDK registry not available");
380
- return;
381
- }
382
- const registry = sdk.getRegistry({ package: "cli" });
383
- // Create all commands first
384
- registry.functions.forEach((fnInfo) => {
385
- if (!fnInfo.inputSchema && !fnInfo.inputParameters) {
386
- console.warn(`Schema not found for ${fnInfo.name}`);
387
- return;
388
- }
389
- // Convert methodName to kebab-case CLI command
390
- const cliCommandName = methodNameToCliCommand(fnInfo.name);
391
- const config = createCommandConfig(cliCommandName, fnInfo, sdk);
392
- addCommand(program, cliCommandName, config);
393
- });
394
- // Override the help display to show commands grouped by category
395
- program.configureHelp({
396
- formatHelp: (cmd, helper) => {
397
- const helpWidth = helper.helpWidth || 80;
398
- let output = helper.commandUsage(cmd) + "\n";
399
- if (cmd.description()) {
400
- output += helper.wrap(cmd.description(), helpWidth, 0) + "\n";
401
- }
402
- // Add options section
403
- const options = helper.visibleOptions(cmd);
404
- if (options.length > 0) {
405
- output += "\nOptions:\n";
406
- const longestOptionLength = Math.max(...options.map((opt) => helper.optionTerm(opt).length));
407
- options.forEach((option) => {
408
- const term = helper.optionTerm(option);
409
- const padding = " ".repeat(Math.max(2, longestOptionLength - term.length + 4));
410
- output += ` ${term}${padding}${helper.optionDescription(option)}\n`;
411
- });
412
- }
413
- // Add categorized commands section
414
- const commands = helper.visibleCommands(cmd);
415
- if (commands.length > 0) {
416
- output += "\nCommands:\n";
417
- // Collect all SDK commands that belong to categories
418
- const categorizedCommands = new Set();
419
- // Group SDK commands by categories
420
- registry.categories.forEach((category) => {
421
- const categoryCommands = commands.filter((command) => category.functions.some((functionName) => {
422
- const cliCommandName = methodNameToCliCommand(functionName);
423
- return command.name() === cliCommandName;
424
- }));
425
- if (categoryCommands.length > 0) {
426
- output += `\n ${category.titlePlural}:\n`;
427
- categoryCommands.forEach((command) => {
428
- output += ` ${helper.subcommandTerm(command)}\n`;
429
- categorizedCommands.add(command.name());
430
- });
431
- }
432
- });
433
- // Add any remaining commands that aren't part of SDK categories
434
- const otherCommands = commands.filter((command) => !categorizedCommands.has(command.name()));
435
- if (otherCommands.length > 0) {
436
- output += `\n Other:\n`;
437
- otherCommands.forEach((command) => {
438
- output += ` ${helper.subcommandTerm(command)}\n`;
439
- });
440
- }
441
- }
442
- return output;
443
- },
444
- });
445
- }
446
- function createCommandConfig(cliCommandName, functionInfo, sdk) {
447
- const usesInputParameters = !functionInfo.inputSchema && !!functionInfo.inputParameters;
448
- const schema = functionInfo.inputSchema;
449
- const parameters = usesInputParameters
450
- ? analyzeInputParameters(functionInfo.inputParameters, functionInfo)
451
- : analyzeZodSchema(schema, functionInfo);
452
- // Mark params that are aliases for other params (e.g., appKey is an alias for app).
453
- const schemaAliases = getSchemaAliases(schema);
454
- if (schemaAliases) {
455
- const aliasedNames = new Set(Object.keys(schemaAliases));
456
- for (const param of parameters) {
457
- if (aliasedNames.has(param.name)) {
458
- param.isAlias = true;
459
- }
460
- }
461
- }
462
- const baseDescription = functionInfo.description ||
463
- schema?.description ||
464
- `${cliCommandName} command`;
465
- // Mark experimental commands clearly in --help so users know what they're
466
- // touching. The command only reaches here at all when the experimental SDK
467
- // factory is loaded, so we don't need to gate help visibility separately.
468
- const description = functionInfo.experimental
469
- ? `${baseDescription} (experimental)`
470
- : baseDescription;
471
- const handler = async (...args) => {
472
- const startTime = Date.now();
473
- let success = true;
474
- let errorMessage = null;
475
- // `resolvedParams` is populated below either by `resolveParameters` or
476
- // by copying `rawParams`. The renderer captures this object by
477
- // reference and reads from it inside formatter callbacks, so we
478
- // mutate it in place (via `Object.assign`) once params are resolved
479
- // rather than reassigning the binding, which would leave the
480
- // renderer holding the empty initial object.
481
- const resolvedParams = {};
482
- // The last argument is always the command object with parsed options
483
- const commandObj = args[args.length - 1];
484
- const options = commandObj.opts();
485
- // interactiveMode is true by default; --json disables it
486
- const interactiveMode = !options.json;
487
- const renderer = interactiveMode
488
- ? createInteractiveRenderer({
489
- sdk,
490
- params: resolvedParams,
491
- })
492
- : createJsonRenderer();
493
- try {
494
- emitDeprecationWarning({
495
- cliCommandName,
496
- deprecation: functionInfo.deprecation,
497
- });
498
- emitParamDeprecationWarnings({ options, parameters });
499
- // Check if this is a list command for pagination
500
- const isListCommand = functionInfo.type === "list";
501
- const hasPaginationParams = parameters.some((p) => PAGINATION_PARAM_NAMES.has(p.name));
502
- const hasUserSpecifiedMaxItems = "maxItems" in options && options.maxItems !== undefined;
503
- const outputMode = resolveOutputMode({
504
- isListCommand,
505
- hasPaginationParams,
506
- hasUserSpecifiedMaxItems,
507
- });
508
- const rawParams = convertCliArgsToSdkParams(parameters, args.slice(0, -1), options);
509
- // Remap aliased parameter names (e.g., authenticationId → connectionId)
510
- const schemaAliases = getSchemaAliases(schema);
511
- if (schemaAliases) {
512
- for (const [oldName, newName] of Object.entries(schemaAliases)) {
513
- if (oldName in rawParams && !(newName in rawParams)) {
514
- rawParams[newName] = rawParams[oldName];
515
- delete rawParams[oldName];
516
- }
517
- }
518
- }
519
- if (schema && !usesInputParameters) {
520
- const resolver = new SchemaParameterResolver();
521
- const resolved = (await resolver.resolveParameters(schema, rawParams, sdk, functionInfo.name, {
522
- interactiveMode,
523
- debug: !!options.debug ||
524
- process.env.DEBUG === "true" ||
525
- process.argv.includes("--debug"),
526
- }));
527
- Object.assign(resolvedParams, resolved);
528
- }
529
- else {
530
- Object.assign(resolvedParams, rawParams);
531
- }
532
- const confirm = functionInfo.confirm;
533
- let confirmMessageAfter;
534
- if (confirm && interactiveMode) {
535
- const confirmResult = await promptConfirm(confirm, functionInfo.itemType);
536
- if (!confirmResult.confirmed) {
537
- console.log(chalk.yellow("Operation cancelled."));
538
- return;
539
- }
540
- confirmMessageAfter = confirmResult.messageAfter;
541
- }
542
- const sdkMethod = sdk[functionInfo.name];
543
- switch (outputMode) {
544
- case "paginate": {
545
- const source = sdkMethod(resolvedParams);
546
- await renderer.renderPaginatedList(source, functionInfo);
547
- break;
548
- }
549
- case "collect": {
550
- const maxItems = resolvedParams.maxItems;
551
- const sdkResult = sdkMethod({ ...resolvedParams, maxItems });
552
- const allItems = await collectItemsFromResult({
553
- sdkResult,
554
- maxItems,
555
- });
556
- await renderer.renderCollectedList(allItems, {
557
- maxItems,
558
- userSpecifiedMaxItems: hasUserSpecifiedMaxItems,
559
- functionInfo,
560
- });
561
- break;
562
- }
563
- case "single": {
564
- const callSdkMethod = () => {
565
- if (usesInputParameters) {
566
- const positionalArgs = reconstructPositionalArgs(functionInfo.inputParameters, resolvedParams);
567
- return sdkMethod(...positionalArgs);
568
- }
569
- return sdkMethod(resolvedParams);
570
- };
571
- const outputFile = resolvedParams.output;
572
- if (outputFile) {
573
- await callSdkMethod();
574
- renderer.renderItem(null, {
575
- outputFile,
576
- commandName: cliCommandName,
577
- });
578
- break;
579
- }
580
- const result = await callSdkMethod();
581
- const normalizedResult = getNormalizedResult(result, {
582
- isListCommand,
583
- });
584
- if (normalizedResult.kind === "response") {
585
- await renderer.renderResponse(normalizedResult.value);
586
- }
587
- else if (normalizedResult.kind === "list") {
588
- await renderer.renderCollectedList(normalizedResult.data, {
589
- maxItems: resolvedParams.maxItems,
590
- userSpecifiedMaxItems: hasUserSpecifiedMaxItems,
591
- functionInfo,
592
- });
593
- }
594
- else {
595
- renderer.renderItem(normalizedResult.value);
596
- }
597
- if (confirmMessageAfter) {
598
- console.log(chalk.yellow(`\n${confirmMessageAfter}`));
599
- }
600
- break;
601
- }
602
- }
603
- }
604
- catch (error) {
605
- success = false;
606
- errorMessage = error instanceof Error ? error.message : String(error);
607
- if (error instanceof ZapierCliMissingParametersError) {
608
- renderer.renderError(error);
609
- }
610
- else if (error instanceof ZapierCliValidationError) {
611
- renderer.renderError(error);
612
- }
613
- else if (error instanceof ZapierCliError) {
614
- throw error;
615
- }
616
- else {
617
- renderer.renderError(error);
618
- }
619
- }
620
- finally {
621
- try {
622
- const event = buildCliCommandExecutedEvent({
623
- data: {
624
- cli_primary_command: cliCommandName,
625
- success_flag: success,
626
- execution_duration_ms: Date.now() - startTime,
627
- exit_code: success ? 0 : 1,
628
- error_message: errorMessage,
629
- command_category: functionInfo.categories?.[0] ?? null,
630
- requires_auth: null,
631
- cli_arguments: sanitizeCliArguments(process.argv.slice(2)),
632
- },
633
- context: {
634
- selected_api: resolvedParams.app ?? null,
635
- },
636
- });
637
- sdk.context.eventEmission.emit(CLI_COMMAND_EXECUTED_EVENT_SUBJECT, event);
638
- }
639
- catch {
640
- // Never let telemetry failures affect command execution
641
- }
642
- }
643
- };
644
- const handlerWithCallerContext = async (...args) => {
645
- return runWithCallerContext({ packageOperation: cliCommandName }, () => handler(...args));
646
- };
647
- return {
648
- description,
649
- parameters,
650
- handler: handlerWithCallerContext,
651
- hidden: !!functionInfo.deprecation,
652
- aliases: functionInfo.aliases,
653
- supportsJsonOutput: functionInfo.supportsJsonOutput,
654
- };
655
- }
656
- // Collect function for repeatable options (e.g., -d foo -d bar → ['foo', 'bar'])
657
- function collect(value, previous = []) {
658
- previous.push(value);
659
- return previous;
660
- }
661
- function addCommand(program, commandName, config) {
662
- const command = program
663
- .command(commandName, { hidden: config.hidden ?? false })
664
- .description(config.description);
665
- // Track whether we've already used a positional array parameter
666
- let hasPositionalArray = false;
667
- // Add parameters to command
668
- config.parameters.forEach((param) => {
669
- const kebabName = toKebabCase(param.name);
670
- if (param.hasResolver && param.required) {
671
- // Required parameters with resolvers become optional positional arguments (resolver handles prompting)
672
- command.argument(`[${kebabName}]`, param.description || `${kebabName} parameter`);
673
- }
674
- else if (param.required &&
675
- param.type === "array" &&
676
- !hasPositionalArray) {
677
- // First required array parameter becomes a variadic positional argument
678
- hasPositionalArray = true;
679
- command.argument(`<${kebabName}...>`, param.description || `${kebabName} parameter`);
680
- }
681
- else if (param.required && param.type === "array") {
682
- // Subsequent required array parameters become required flags (repeatable)
683
- const flags = [`--${kebabName}`];
684
- const flagSignature = flags.join(", ") + ` <value>`;
685
- command.requiredOption(flagSignature, param.description || `${kebabName} parameter (required, repeatable)`, collect, []);
686
- }
687
- else if (param.required) {
688
- // Required parameters without resolvers become required positional arguments
689
- command.argument(`<${kebabName}>`, param.description || `${kebabName} parameter`);
690
- }
691
- else if (param.isPositional && !param.isDeprecated && !param.isAlias) {
692
- // Optional parameters marked as positional become optional positional arguments
693
- command.argument(`[${kebabName}]`, param.description || `${kebabName} parameter`);
694
- }
695
- else {
696
- // Optional parameters become flags (whether they have resolvers or not)
697
- const flags = [];
698
- // Add short alias if defined (single-letter aliases only)
699
- const alias = config.aliases?.[param.name];
700
- if (alias && alias.length === 1) {
701
- flags.push(`-${alias}`);
702
- }
703
- flags.push(`--${kebabName}`);
704
- if (param.type === "boolean") {
705
- const opt = new Option(flags.join(", "), param.description);
706
- if (param.isDeprecated)
707
- opt.hideHelp();
708
- command.addOption(opt);
709
- }
710
- else if (param.type === "array") {
711
- // For arrays, use collect pattern for repeatable flags (e.g., -d foo -d bar)
712
- const flagSignature = flags.join(", ") + ` <value>`;
713
- const opt = new Option(flagSignature, param.description || "");
714
- opt.default([]);
715
- opt.argParser((value, previous) => (previous || []).concat([value]));
716
- if (param.isDeprecated)
717
- opt.hideHelp();
718
- command.addOption(opt);
719
- }
720
- else {
721
- const flagSignature = flags.join(", ") + ` <${param.type}>`;
722
- const opt = new Option(flagSignature, param.description || "");
723
- if (param.default !== undefined) {
724
- opt.default(param.default);
725
- }
726
- if (param.isDeprecated)
727
- opt.hideHelp();
728
- command.addOption(opt);
729
- }
730
- }
731
- });
732
- // Add shared command options (if not already included or excluded by interactive mode)
733
- const paramNames = new Set(config.parameters.map((p) => p.name));
734
- SHARED_COMMAND_CLI_OPTIONS.forEach((opt) => {
735
- if (paramNames.has(opt.name))
736
- return;
737
- if (config.supportsJsonOutput === false && opt.name === "json")
738
- return;
739
- command.option(opt.flag, opt.description);
740
- });
741
- command.action(config.handler);
742
- }
743
- // ============================================================================
744
- // Parameter Conversion
745
- // ============================================================================
746
- function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
747
- const sdkParams = {};
748
- // Handle positional arguments (required parameters or optional positional parameters)
749
- let argIndex = 0;
750
- parameters.forEach((param) => {
751
- if ((param.required ||
752
- (param.isPositional && !param.isDeprecated && !param.isAlias)) &&
753
- argIndex < positionalArgs.length) {
754
- // Use the original camelCase parameter name for the SDK
755
- sdkParams[param.name] = convertValue(positionalArgs[argIndex], param.type, param.elementType);
756
- argIndex++;
757
- }
758
- });
759
- // Handle option flags
760
- Object.entries(options).forEach(([key, value]) => {
761
- // Convert kebab-case back to camelCase
762
- const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
763
- const param = parameters.find((p) => p.name === camelKey);
764
- if (param && value !== undefined) {
765
- // Skip empty arrays — Commander initializes repeatable options with []
766
- // so an empty array means the user didn't pass the flag. Omitting it
767
- // lets Zod's .default() supply the intended default value.
768
- if (param.type === "array" &&
769
- Array.isArray(value) &&
770
- value.length === 0) {
771
- return;
772
- }
773
- sdkParams[camelKey] = convertValue(value, param.type, param.elementType);
774
- }
775
- });
776
- return sdkParams;
777
- }
778
- function convertValue(value, type, elementType) {
779
- // Don't convert undefined values - let the resolver system handle them
780
- if (value === undefined) {
781
- return undefined;
782
- }
783
- switch (type) {
784
- case "number":
785
- return Number(value);
786
- case "boolean":
787
- return Boolean(value);
788
- case "array": {
789
- const arr = Array.isArray(value) ? value : [value];
790
- if (elementType !== "object")
791
- return arr;
792
- return arr.flatMap((item) => {
793
- if (typeof item === "string" &&
794
- (item.startsWith("{") || item.startsWith("["))) {
795
- try {
796
- return JSON.parse(item);
797
- }
798
- catch {
799
- return item;
800
- }
801
- }
802
- return item;
803
- });
804
- }
805
- case "string":
806
- return value;
807
- case "object":
808
- // Parse JSON string to object for z.record() and similar types
809
- if (typeof value === "string") {
810
- try {
811
- return JSON.parse(value);
812
- }
813
- catch {
814
- return value;
815
- }
816
- }
817
- return value;
818
- default:
819
- // Unknown schema types - try to parse if it looks like JSON
820
- if (typeof value === "string" &&
821
- (value.startsWith("{") || value.startsWith("["))) {
822
- try {
823
- return JSON.parse(value);
824
- }
825
- catch {
826
- return value;
827
- }
828
- }
829
- return value;
830
- }
831
- }