@zapier/zapier-sdk-cli 0.4.1 → 0.4.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.
- package/CHANGELOG.md +8 -0
- package/dist/cli.js +961 -284
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +28 -0
- package/dist/src/commands/bundle-code/cli.d.ts +2 -0
- package/dist/src/commands/bundle-code/cli.js +77 -0
- package/dist/src/commands/bundle-code/index.d.ts +5 -0
- package/dist/src/commands/bundle-code/index.js +62 -0
- package/dist/src/commands/bundle-code/schemas.d.ts +24 -0
- package/dist/src/commands/bundle-code/schemas.js +19 -0
- package/dist/src/commands/configPath.d.ts +2 -0
- package/dist/src/commands/configPath.js +9 -0
- package/dist/src/commands/generate-types/cli.d.ts +2 -0
- package/dist/src/commands/generate-types/cli.js +73 -0
- package/dist/src/commands/generate-types/index.d.ts +8 -0
- package/dist/src/commands/generate-types/index.js +273 -0
- package/dist/src/commands/generate-types/schemas.d.ts +18 -0
- package/dist/src/commands/generate-types/schemas.js +11 -0
- package/dist/src/commands/index.d.ts +6 -0
- package/dist/src/commands/index.js +6 -0
- package/dist/src/commands/login.d.ts +2 -0
- package/dist/src/commands/login.js +25 -0
- package/dist/src/commands/logout.d.ts +2 -0
- package/dist/src/commands/logout.js +16 -0
- package/dist/src/commands/mcp.d.ts +2 -0
- package/dist/src/commands/mcp.js +11 -0
- package/dist/src/index.d.ts +0 -0
- package/dist/src/index.js +3 -0
- package/dist/src/utils/api/client.d.ts +15 -0
- package/dist/src/utils/api/client.js +27 -0
- package/dist/src/utils/auth/login.d.ts +2 -0
- package/dist/src/utils/auth/login.js +134 -0
- package/dist/src/utils/cli-generator-utils.d.ts +13 -0
- package/dist/src/utils/cli-generator-utils.js +116 -0
- package/dist/src/utils/cli-generator.d.ts +3 -0
- package/dist/src/utils/cli-generator.js +443 -0
- package/dist/src/utils/constants.d.ts +5 -0
- package/dist/src/utils/constants.js +6 -0
- package/dist/src/utils/getCallablePromise.d.ts +6 -0
- package/dist/src/utils/getCallablePromise.js +14 -0
- package/dist/src/utils/log.d.ts +7 -0
- package/dist/src/utils/log.js +16 -0
- package/dist/src/utils/parameter-resolver.d.ts +14 -0
- package/dist/src/utils/parameter-resolver.js +387 -0
- package/dist/src/utils/schema-formatter.d.ts +2 -0
- package/dist/src/utils/schema-formatter.js +71 -0
- package/dist/src/utils/serializeAsync.d.ts +2 -0
- package/dist/src/utils/serializeAsync.js +16 -0
- package/dist/src/utils/spinner.d.ts +1 -0
- package/dist/src/utils/spinner.js +13 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +5 -3
- package/src/cli.test.ts +15 -0
- package/src/cli.ts +9 -3
- package/src/commands/bundle-code/cli.ts +103 -0
- package/src/commands/bundle-code/index.ts +91 -0
- package/src/commands/bundle-code/schemas.ts +24 -0
- package/src/commands/generate-types/cli.ts +110 -0
- package/src/commands/generate-types/index.ts +365 -0
- package/src/commands/generate-types/schemas.ts +23 -0
- package/src/commands/index.ts +3 -1
- package/src/commands/mcp.ts +14 -0
- package/src/utils/cli-generator-utils.ts +157 -0
- package/src/utils/cli-generator.ts +148 -91
- package/src/utils/parameter-resolver.ts +217 -85
- package/src/utils/schema-formatter.ts +1 -1
- package/tsconfig.json +3 -5
- package/src/commands/whoami.ts +0 -25
- package/src/utils/pager.ts +0 -202
- package/test/cli.test.ts +0 -46
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { hasResolver, isPositional, formatErrorMessage, ZapierError, } from "@zapier/zapier-sdk";
|
|
3
|
+
import { SchemaParameterResolver } from "./parameter-resolver";
|
|
4
|
+
import { formatItemsFromSchema } from "./schema-formatter";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import util from "util";
|
|
7
|
+
import inquirer from "inquirer";
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// JSON Formatting
|
|
10
|
+
// ============================================================================
|
|
11
|
+
function formatJsonOutput(data) {
|
|
12
|
+
// Show success message for action results
|
|
13
|
+
if (data &&
|
|
14
|
+
typeof data === "object" &&
|
|
15
|
+
!Array.isArray(data) &&
|
|
16
|
+
(data.success !== undefined || data.id || data.status)) {
|
|
17
|
+
console.log(chalk.green("✅ Action completed successfully!\n"));
|
|
18
|
+
}
|
|
19
|
+
// Use util.inspect for colored output
|
|
20
|
+
console.log(util.inspect(data, { colors: true, depth: null, breakLength: 80 }));
|
|
21
|
+
}
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Schema Analysis
|
|
24
|
+
// ============================================================================
|
|
25
|
+
function analyzeZodSchema(schema) {
|
|
26
|
+
const parameters = [];
|
|
27
|
+
if (schema instanceof z.ZodObject) {
|
|
28
|
+
const shape = schema.shape;
|
|
29
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
30
|
+
const param = analyzeZodField(key, fieldSchema);
|
|
31
|
+
if (param) {
|
|
32
|
+
parameters.push(param);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return parameters;
|
|
37
|
+
}
|
|
38
|
+
function analyzeZodField(name, schema) {
|
|
39
|
+
let baseSchema = schema;
|
|
40
|
+
let required = true;
|
|
41
|
+
let defaultValue = undefined;
|
|
42
|
+
// Unwrap optional and default wrappers
|
|
43
|
+
if (baseSchema instanceof z.ZodOptional) {
|
|
44
|
+
required = false;
|
|
45
|
+
baseSchema = baseSchema._def.innerType;
|
|
46
|
+
}
|
|
47
|
+
if (baseSchema instanceof z.ZodDefault) {
|
|
48
|
+
required = false;
|
|
49
|
+
defaultValue = baseSchema._def.defaultValue();
|
|
50
|
+
baseSchema = baseSchema._def.innerType;
|
|
51
|
+
}
|
|
52
|
+
// Determine parameter type
|
|
53
|
+
let paramType = "string";
|
|
54
|
+
let choices;
|
|
55
|
+
if (baseSchema instanceof z.ZodString) {
|
|
56
|
+
paramType = "string";
|
|
57
|
+
}
|
|
58
|
+
else if (baseSchema instanceof z.ZodNumber) {
|
|
59
|
+
paramType = "number";
|
|
60
|
+
}
|
|
61
|
+
else if (baseSchema instanceof z.ZodBoolean) {
|
|
62
|
+
paramType = "boolean";
|
|
63
|
+
}
|
|
64
|
+
else if (baseSchema instanceof z.ZodArray) {
|
|
65
|
+
paramType = "array";
|
|
66
|
+
}
|
|
67
|
+
else if (baseSchema instanceof z.ZodEnum) {
|
|
68
|
+
paramType = "string";
|
|
69
|
+
choices = baseSchema._def.values;
|
|
70
|
+
}
|
|
71
|
+
else if (baseSchema instanceof z.ZodRecord) {
|
|
72
|
+
// Handle Record<string, any> as JSON string input
|
|
73
|
+
paramType = "string";
|
|
74
|
+
}
|
|
75
|
+
// Extract resolver metadata
|
|
76
|
+
return {
|
|
77
|
+
name,
|
|
78
|
+
type: paramType,
|
|
79
|
+
required,
|
|
80
|
+
description: schema.description,
|
|
81
|
+
default: defaultValue,
|
|
82
|
+
choices,
|
|
83
|
+
hasResolver: hasResolver(name),
|
|
84
|
+
isPositional: isPositional(schema),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// CLI Structure Derivation - Purely Generic
|
|
89
|
+
// ============================================================================
|
|
90
|
+
/**
|
|
91
|
+
* Convert camelCase to kebab-case
|
|
92
|
+
* e.g., listApps -> list-apps, generateTypes -> generate-types
|
|
93
|
+
*/
|
|
94
|
+
function toKebabCase(str) {
|
|
95
|
+
return str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Convert SDK method name directly to CLI command
|
|
99
|
+
* e.g., listApps -> list-apps, getApp -> get-app, generateTypes -> generate-types
|
|
100
|
+
*/
|
|
101
|
+
function methodNameToCliCommand(methodName) {
|
|
102
|
+
return toKebabCase(methodName);
|
|
103
|
+
}
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// CLI Command Generation - Completely Generic
|
|
106
|
+
// ============================================================================
|
|
107
|
+
export function generateCliCommands(program, sdk) {
|
|
108
|
+
// Check if SDK has registry
|
|
109
|
+
if (!sdk.__registry) {
|
|
110
|
+
console.error("SDK registry not available");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// Generate one flat command for each function in the registry
|
|
114
|
+
sdk.__registry.forEach((fnInfo) => {
|
|
115
|
+
if (!fnInfo.inputSchema) {
|
|
116
|
+
console.warn(`Schema not found for ${fnInfo.name}`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Convert methodName to kebab-case CLI command
|
|
120
|
+
const cliCommandName = methodNameToCliCommand(fnInfo.name);
|
|
121
|
+
const config = createCommandConfig(cliCommandName, fnInfo.name, fnInfo.inputSchema, sdk);
|
|
122
|
+
addCommand(program, cliCommandName, config);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk) {
|
|
126
|
+
const parameters = analyzeZodSchema(schema);
|
|
127
|
+
const description = schema.description || `${cliCommandName} command`;
|
|
128
|
+
const handler = async (...args) => {
|
|
129
|
+
try {
|
|
130
|
+
// The last argument is always the command object with parsed options
|
|
131
|
+
const commandObj = args[args.length - 1];
|
|
132
|
+
const options = commandObj.opts();
|
|
133
|
+
// Check if this is a list command for pagination
|
|
134
|
+
const isListCommand = cliCommandName.startsWith("list-");
|
|
135
|
+
const hasPaginationParams = parameters.some((p) => p.name === "maxItems" || p.name === "pageSize");
|
|
136
|
+
const hasUserSpecifiedMaxItems = "maxItems" in options && options.maxItems !== undefined;
|
|
137
|
+
const shouldUseJson = options.json;
|
|
138
|
+
// Convert CLI args to SDK method parameters
|
|
139
|
+
const rawParams = convertCliArgsToSdkParams(parameters, args.slice(0, -1), options);
|
|
140
|
+
// Resolve missing parameters interactively using schema metadata
|
|
141
|
+
const resolver = new SchemaParameterResolver();
|
|
142
|
+
const resolvedParams = await resolver.resolveParameters(schema, rawParams, sdk);
|
|
143
|
+
// Special handling for commands that write to files
|
|
144
|
+
const hasOutputFile = resolvedParams.output;
|
|
145
|
+
if (hasOutputFile) {
|
|
146
|
+
// Call the SDK method for file output commands
|
|
147
|
+
await sdk[sdkMethodName](resolvedParams);
|
|
148
|
+
console.log(chalk.green(`✅ ${cliCommandName} completed successfully!`));
|
|
149
|
+
console.log(chalk.gray(`Output written to: ${resolvedParams.output}`));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// Handle paginated list commands with async iteration
|
|
153
|
+
if (isListCommand &&
|
|
154
|
+
hasPaginationParams &&
|
|
155
|
+
!shouldUseJson &&
|
|
156
|
+
!hasUserSpecifiedMaxItems) {
|
|
157
|
+
// Get the async iterator directly from the SDK method call
|
|
158
|
+
const sdkIterator = sdk[sdkMethodName](resolvedParams);
|
|
159
|
+
await handlePaginatedListWithAsyncIteration(sdkMethodName, sdkIterator, schema);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Call the SDK method and handle non-paginated results
|
|
163
|
+
const result = await sdk[sdkMethodName](resolvedParams);
|
|
164
|
+
const items = result?.data ? result.data : result;
|
|
165
|
+
if (shouldUseJson) {
|
|
166
|
+
console.log(JSON.stringify(items, null, 2));
|
|
167
|
+
}
|
|
168
|
+
else if (isListCommand) {
|
|
169
|
+
formatNonPaginatedResults(items, resolvedParams.maxItems, hasUserSpecifiedMaxItems, shouldUseJson, schema, sdkMethodName);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
formatJsonOutput(items);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
// Handle Zod validation errors more gracefully
|
|
178
|
+
if (error instanceof Error && error.message.includes('"code"')) {
|
|
179
|
+
try {
|
|
180
|
+
const validationErrors = JSON.parse(error.message);
|
|
181
|
+
console.error(chalk.red("❌ Validation Error:"));
|
|
182
|
+
validationErrors.forEach((err) => {
|
|
183
|
+
const field = err.path?.join(".") || "unknown";
|
|
184
|
+
console.error(chalk.yellow(` • ${field}: ${err.message}`));
|
|
185
|
+
});
|
|
186
|
+
console.error("\n" + chalk.dim(`Use --help to see available options`));
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
console.error(chalk.red("Error:"), error.message);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else if (error instanceof ZapierError) {
|
|
193
|
+
// Handle SDK errors with clean, user-friendly messages using our formatter
|
|
194
|
+
const formattedMessage = formatErrorMessage(error);
|
|
195
|
+
console.error(chalk.red("❌ Error:"), formattedMessage);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Handle other errors
|
|
199
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
200
|
+
console.error(chalk.red("❌ Error:"), errorMessage);
|
|
201
|
+
}
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
return {
|
|
206
|
+
description,
|
|
207
|
+
parameters,
|
|
208
|
+
handler,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function addCommand(program, commandName, config) {
|
|
212
|
+
const command = program.command(commandName).description(config.description);
|
|
213
|
+
// Add parameters to command
|
|
214
|
+
config.parameters.forEach((param) => {
|
|
215
|
+
// Convert camelCase to kebab-case for CLI display
|
|
216
|
+
const kebabName = param.name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
217
|
+
if (param.hasResolver && param.required) {
|
|
218
|
+
// Required parameters with resolvers become optional positional arguments (resolver handles prompting)
|
|
219
|
+
command.argument(`[${kebabName}]`, param.description || `${kebabName} parameter`);
|
|
220
|
+
}
|
|
221
|
+
else if (param.required) {
|
|
222
|
+
// Required parameters without resolvers become required positional arguments
|
|
223
|
+
command.argument(`<${kebabName}>`, param.description || `${kebabName} parameter`);
|
|
224
|
+
}
|
|
225
|
+
else if (param.isPositional) {
|
|
226
|
+
// Optional parameters marked as positional become optional positional arguments
|
|
227
|
+
command.argument(`[${kebabName}]`, param.description || `${kebabName} parameter`);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
// Optional parameters become flags (whether they have resolvers or not)
|
|
231
|
+
const flags = [`--${kebabName}`];
|
|
232
|
+
if (param.type === "boolean") {
|
|
233
|
+
command.option(flags.join(", "), param.description);
|
|
234
|
+
}
|
|
235
|
+
else if (param.type === "array") {
|
|
236
|
+
// For arrays, use variadic syntax to collect multiple values
|
|
237
|
+
const flagSignature = flags.join(", ") + ` <values...>`;
|
|
238
|
+
command.option(flagSignature, param.description, param.default);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
const flagSignature = flags.join(", ") + ` <${param.type}>`;
|
|
242
|
+
command.option(flagSignature, param.description, param.default);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
// Add formatting options for all commands
|
|
247
|
+
command.option("--json", "Output raw JSON instead of formatted results");
|
|
248
|
+
command.action(config.handler);
|
|
249
|
+
}
|
|
250
|
+
// ============================================================================
|
|
251
|
+
// Parameter Conversion
|
|
252
|
+
// ============================================================================
|
|
253
|
+
function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
254
|
+
const sdkParams = {};
|
|
255
|
+
// Handle positional arguments (required parameters or optional positional parameters)
|
|
256
|
+
let argIndex = 0;
|
|
257
|
+
parameters.forEach((param) => {
|
|
258
|
+
if ((param.required || param.isPositional) &&
|
|
259
|
+
argIndex < positionalArgs.length) {
|
|
260
|
+
// Use the original camelCase parameter name for the SDK
|
|
261
|
+
sdkParams[param.name] = convertValue(positionalArgs[argIndex], param.type);
|
|
262
|
+
argIndex++;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
// Handle option flags
|
|
266
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
267
|
+
// Convert kebab-case back to camelCase
|
|
268
|
+
const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
269
|
+
const param = parameters.find((p) => p.name === camelKey);
|
|
270
|
+
if (param && value !== undefined) {
|
|
271
|
+
sdkParams[camelKey] = convertValue(value, param.type);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
return sdkParams;
|
|
275
|
+
}
|
|
276
|
+
function convertValue(value, type) {
|
|
277
|
+
switch (type) {
|
|
278
|
+
case "number":
|
|
279
|
+
return Number(value);
|
|
280
|
+
case "boolean":
|
|
281
|
+
return Boolean(value);
|
|
282
|
+
case "array":
|
|
283
|
+
return Array.isArray(value) ? value : [value];
|
|
284
|
+
case "string":
|
|
285
|
+
default:
|
|
286
|
+
// Handle JSON string for objects
|
|
287
|
+
if (typeof value === "string" &&
|
|
288
|
+
(value.startsWith("{") || value.startsWith("["))) {
|
|
289
|
+
try {
|
|
290
|
+
return JSON.parse(value);
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return value;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return value;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// ============================================================================
|
|
300
|
+
// Pagination Handlers
|
|
301
|
+
// ============================================================================
|
|
302
|
+
async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, schema) {
|
|
303
|
+
const itemName = getItemNameFromMethod(sdkMethodName);
|
|
304
|
+
let totalShown = 0;
|
|
305
|
+
let pageCount = 0;
|
|
306
|
+
console.log(chalk.blue(`📋 ${getListTitleFromMethod(sdkMethodName)}\n`));
|
|
307
|
+
try {
|
|
308
|
+
// Use async iteration to go through pages
|
|
309
|
+
for await (const page of sdkResult) {
|
|
310
|
+
const items = page.data || page;
|
|
311
|
+
pageCount++;
|
|
312
|
+
if (!Array.isArray(items)) {
|
|
313
|
+
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (items.length === 0 && pageCount === 1) {
|
|
317
|
+
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (items.length === 0) {
|
|
321
|
+
break; // No more items
|
|
322
|
+
}
|
|
323
|
+
// Clear screen for subsequent pages (not the first)
|
|
324
|
+
if (pageCount > 1) {
|
|
325
|
+
console.clear();
|
|
326
|
+
console.log(chalk.blue(`📋 ${getListTitleFromMethod(sdkMethodName)}\n`));
|
|
327
|
+
}
|
|
328
|
+
// Format and display items using schema
|
|
329
|
+
if (schema) {
|
|
330
|
+
formatItemsFromSchema(schema, items);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
formatItemsGeneric(items);
|
|
334
|
+
}
|
|
335
|
+
totalShown += items.length;
|
|
336
|
+
console.log(chalk.green(`\n✅ Showing ${totalShown} ${itemName} (page ${pageCount})`));
|
|
337
|
+
// Only prompt if there's a nextCursor (more pages available)
|
|
338
|
+
if (page.nextCursor) {
|
|
339
|
+
const { continueReading } = await inquirer.prompt([
|
|
340
|
+
{
|
|
341
|
+
type: "confirm",
|
|
342
|
+
name: "continueReading",
|
|
343
|
+
message: `Load next page?`,
|
|
344
|
+
default: true,
|
|
345
|
+
},
|
|
346
|
+
]);
|
|
347
|
+
if (!continueReading) {
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
// No more pages available, exit gracefully
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
console.log(chalk.gray(`\n📄 Finished browsing ${itemName}`));
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
// If the result is not async iterable, fall back to showing the first page
|
|
360
|
+
const items = sdkResult?.data || sdkResult;
|
|
361
|
+
if (Array.isArray(items)) {
|
|
362
|
+
if (items.length === 0) {
|
|
363
|
+
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (schema) {
|
|
367
|
+
formatItemsFromSchema(schema, items);
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
formatItemsGeneric(items);
|
|
371
|
+
}
|
|
372
|
+
console.log(chalk.green(`\n✅ Showing ${items.length} ${itemName}`));
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function formatNonPaginatedResults(result, requestedMaxItems, userSpecifiedMaxItems, useRawJson, schema, methodName) {
|
|
380
|
+
if (!Array.isArray(result)) {
|
|
381
|
+
if (useRawJson) {
|
|
382
|
+
console.log(JSON.stringify(result, null, 2));
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
formatJsonOutput(result);
|
|
386
|
+
}
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (useRawJson) {
|
|
390
|
+
console.log(JSON.stringify(result, null, 2));
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const itemName = methodName ? getItemNameFromMethod(methodName) : "items";
|
|
394
|
+
if (result.length === 0) {
|
|
395
|
+
console.log(chalk.yellow(`No ${itemName} found.`));
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
console.log(chalk.green(`\n✅ Found ${result.length} ${itemName}:\n`));
|
|
399
|
+
// Use schema for formatting
|
|
400
|
+
if (schema) {
|
|
401
|
+
formatItemsFromSchema(schema, result);
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
// Fallback to generic formatting
|
|
405
|
+
formatItemsGeneric(result);
|
|
406
|
+
}
|
|
407
|
+
// Show appropriate status message
|
|
408
|
+
if (userSpecifiedMaxItems && requestedMaxItems) {
|
|
409
|
+
console.log(chalk.gray(`\n📄 Showing up to ${requestedMaxItems} ${itemName} (--max-items ${requestedMaxItems})`));
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
console.log(chalk.gray(`\n📄 All available ${itemName} shown`));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function formatItemsGeneric(items) {
|
|
416
|
+
// Fallback formatting for items without schema metadata
|
|
417
|
+
items.forEach((item, index) => {
|
|
418
|
+
const name = item.title || item.name || item.key || item.id || "Item";
|
|
419
|
+
console.log(`${chalk.gray(`${index + 1}.`)} ${chalk.cyan(name)}`);
|
|
420
|
+
if (item.description) {
|
|
421
|
+
console.log(` ${chalk.dim(item.description)}`);
|
|
422
|
+
}
|
|
423
|
+
console.log();
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
// Generic helper functions that infer from schema description or method name
|
|
427
|
+
function getItemNameFromMethod(methodName) {
|
|
428
|
+
// Extract from method name: listApps -> apps, listActions -> actions
|
|
429
|
+
const listMatch = methodName.match(/^list(.+)$/);
|
|
430
|
+
if (listMatch) {
|
|
431
|
+
return listMatch[1].toLowerCase();
|
|
432
|
+
}
|
|
433
|
+
// Fallback to generic
|
|
434
|
+
return "items";
|
|
435
|
+
}
|
|
436
|
+
function getListTitleFromMethod(methodName) {
|
|
437
|
+
const itemName = getItemNameFromMethod(methodName);
|
|
438
|
+
if (itemName === "items")
|
|
439
|
+
return "Available Items";
|
|
440
|
+
// Capitalize first letter: apps -> Apps
|
|
441
|
+
const capitalized = itemName.charAt(0).toUpperCase() + itemName.slice(1);
|
|
442
|
+
return `Available ${capitalized}`;
|
|
443
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const ZAPIER_BASE = "https://zapier.com";
|
|
2
|
+
export declare const LOGIN_CLIENT_ID = "K5eEnRE9TTmSFATdkkWhKF8NOKwoiOnYAyIqJjae";
|
|
3
|
+
export declare const LOGIN_PORTS: number[];
|
|
4
|
+
export declare const LOGIN_TIMEOUT_MS = 300000;
|
|
5
|
+
export declare const AUTH_MODE_HEADER = "X-Auth";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const ZAPIER_BASE = "https://zapier.com";
|
|
2
|
+
// OAuth client ID for zapier-sdk CLI
|
|
3
|
+
export const LOGIN_CLIENT_ID = "K5eEnRE9TTmSFATdkkWhKF8NOKwoiOnYAyIqJjae";
|
|
4
|
+
export const LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
5
|
+
export const LOGIN_TIMEOUT_MS = 300000; // 5 minutes
|
|
6
|
+
export const AUTH_MODE_HEADER = "X-Auth";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const getCallablePromise = () => {
|
|
2
|
+
let resolve = () => { };
|
|
3
|
+
let reject = () => { };
|
|
4
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
5
|
+
resolve = _resolve;
|
|
6
|
+
reject = _reject;
|
|
7
|
+
});
|
|
8
|
+
return {
|
|
9
|
+
promise,
|
|
10
|
+
resolve,
|
|
11
|
+
reject,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export default getCallablePromise;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
const log = {
|
|
3
|
+
info: (message, ...args) => {
|
|
4
|
+
console.log(chalk.blue("ℹ"), message, ...args);
|
|
5
|
+
},
|
|
6
|
+
error: (message, ...args) => {
|
|
7
|
+
console.error(chalk.red("✖"), message, ...args);
|
|
8
|
+
},
|
|
9
|
+
success: (message, ...args) => {
|
|
10
|
+
console.log(chalk.green("✓"), message, ...args);
|
|
11
|
+
},
|
|
12
|
+
warn: (message, ...args) => {
|
|
13
|
+
console.log(chalk.yellow("⚠"), message, ...args);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
export default log;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ZapierSdk } from "@zapier/zapier-sdk";
|
|
3
|
+
export declare class SchemaParameterResolver {
|
|
4
|
+
resolveParameters(schema: z.ZodSchema, providedParams: any, sdk: ZapierSdk): Promise<any>;
|
|
5
|
+
private extractParametersFromSchema;
|
|
6
|
+
private analyzeFieldSchema;
|
|
7
|
+
private createResolvableParameter;
|
|
8
|
+
private resolveParameter;
|
|
9
|
+
private resolveFieldsRecursively;
|
|
10
|
+
private getNestedValue;
|
|
11
|
+
private setNestedValue;
|
|
12
|
+
private promptForField;
|
|
13
|
+
private isUserCancellation;
|
|
14
|
+
}
|