@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
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
5
|
-
import { createZapierSdk } from "@zapier/zapier-sdk";
|
|
4
|
+
import { Command as Command7 } from "commander";
|
|
5
|
+
import { createZapierSdk as createZapierSdk2 } from "@zapier/zapier-sdk";
|
|
6
6
|
|
|
7
7
|
// src/utils/cli-generator.ts
|
|
8
8
|
import { z as z2 } from "zod";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
hasResolver as hasResolver2,
|
|
11
|
+
isPositional,
|
|
12
|
+
formatErrorMessage,
|
|
13
|
+
ZapierError
|
|
14
|
+
} from "@zapier/zapier-sdk";
|
|
10
15
|
|
|
11
16
|
// src/utils/parameter-resolver.ts
|
|
12
17
|
import inquirer from "inquirer";
|
|
@@ -30,18 +35,25 @@ var SchemaParameterResolver = class {
|
|
|
30
35
|
});
|
|
31
36
|
const functionallyRequired = missingResolvable.filter((param) => {
|
|
32
37
|
if (param.isRequired) return true;
|
|
33
|
-
if (param.name === "inputs"
|
|
38
|
+
if (param.name === "inputs") {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
});
|
|
43
|
+
const alwaysPrompt = missingResolvable.filter((param) => {
|
|
44
|
+
if (functionallyRequired.includes(param)) return false;
|
|
45
|
+
if (param.name === "authenticationId") {
|
|
34
46
|
return true;
|
|
35
47
|
}
|
|
36
48
|
return false;
|
|
37
49
|
});
|
|
38
50
|
const trulyOptional = missingResolvable.filter(
|
|
39
|
-
(param) => !functionallyRequired.includes(param)
|
|
51
|
+
(param) => !functionallyRequired.includes(param) && !alwaysPrompt.includes(param)
|
|
40
52
|
);
|
|
41
|
-
if (parseResult.success && functionallyRequired.length === 0) {
|
|
53
|
+
if (parseResult.success && functionallyRequired.length === 0 && alwaysPrompt.length === 0) {
|
|
42
54
|
return parseResult.data;
|
|
43
55
|
}
|
|
44
|
-
if (functionallyRequired.length === 0) {
|
|
56
|
+
if (functionallyRequired.length === 0 && alwaysPrompt.length === 0) {
|
|
45
57
|
if (!parseResult.success) {
|
|
46
58
|
throw parseResult.error;
|
|
47
59
|
}
|
|
@@ -56,9 +68,16 @@ var SchemaParameterResolver = class {
|
|
|
56
68
|
if (functionallyRequired.length > 0) {
|
|
57
69
|
const requiredParamNames = functionallyRequired.map((p) => p.name);
|
|
58
70
|
const requiredResolutionOrder = getResolutionOrderForParams(requiredParamNames);
|
|
59
|
-
const orderedRequiredParams = requiredResolutionOrder.map(
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
const orderedRequiredParams = requiredResolutionOrder.map((paramName) => {
|
|
72
|
+
let param = functionallyRequired.find((p) => p.name === paramName);
|
|
73
|
+
if (!param) {
|
|
74
|
+
param = alwaysPrompt.find((p) => p.name === paramName);
|
|
75
|
+
}
|
|
76
|
+
if (!param) {
|
|
77
|
+
param = trulyOptional.find((p) => p.name === paramName);
|
|
78
|
+
}
|
|
79
|
+
return param;
|
|
80
|
+
}).filter((param) => param !== void 0);
|
|
62
81
|
for (const param of orderedRequiredParams) {
|
|
63
82
|
try {
|
|
64
83
|
const value = await this.resolveParameter(param, context);
|
|
@@ -69,7 +88,37 @@ var SchemaParameterResolver = class {
|
|
|
69
88
|
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
70
89
|
process.exit(0);
|
|
71
90
|
}
|
|
72
|
-
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const resolvedParamNames = new Set(
|
|
95
|
+
orderedRequiredParams.map((p) => p.name)
|
|
96
|
+
);
|
|
97
|
+
alwaysPrompt.splice(
|
|
98
|
+
0,
|
|
99
|
+
alwaysPrompt.length,
|
|
100
|
+
...alwaysPrompt.filter((p) => !resolvedParamNames.has(p.name))
|
|
101
|
+
);
|
|
102
|
+
trulyOptional.splice(
|
|
103
|
+
0,
|
|
104
|
+
trulyOptional.length,
|
|
105
|
+
...trulyOptional.filter((p) => !resolvedParamNames.has(p.name))
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
if (alwaysPrompt.length > 0) {
|
|
109
|
+
const alwaysPromptNames = alwaysPrompt.map((p) => p.name);
|
|
110
|
+
const alwaysPromptResolutionOrder = getResolutionOrderForParams(alwaysPromptNames);
|
|
111
|
+
const orderedAlwaysPromptParams = alwaysPromptResolutionOrder.map((paramName) => alwaysPrompt.find((p) => p.name === paramName)).filter((param) => param !== void 0);
|
|
112
|
+
for (const param of orderedAlwaysPromptParams) {
|
|
113
|
+
try {
|
|
114
|
+
const value = await this.resolveParameter(param, context);
|
|
115
|
+
this.setNestedValue(resolvedParams, param.path, value);
|
|
116
|
+
context.resolvedParams = resolvedParams;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (this.isUserCancellation(error)) {
|
|
119
|
+
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
73
122
|
throw error;
|
|
74
123
|
}
|
|
75
124
|
}
|
|
@@ -98,7 +147,6 @@ var SchemaParameterResolver = class {
|
|
|
98
147
|
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
99
148
|
process.exit(0);
|
|
100
149
|
}
|
|
101
|
-
console.error(chalk.red(`Failed to resolve ${param.name}:`), error);
|
|
102
150
|
throw error;
|
|
103
151
|
}
|
|
104
152
|
}
|
|
@@ -139,12 +187,12 @@ var SchemaParameterResolver = class {
|
|
|
139
187
|
}
|
|
140
188
|
return this.createResolvableParameter([fieldName], baseSchema, isRequired);
|
|
141
189
|
}
|
|
142
|
-
createResolvableParameter(
|
|
143
|
-
if (
|
|
144
|
-
const name =
|
|
190
|
+
createResolvableParameter(path3, schema, isRequired) {
|
|
191
|
+
if (path3.length === 0) return null;
|
|
192
|
+
const name = path3[path3.length - 1];
|
|
145
193
|
return {
|
|
146
194
|
name,
|
|
147
|
-
path,
|
|
195
|
+
path: path3,
|
|
148
196
|
schema,
|
|
149
197
|
description: schema.description,
|
|
150
198
|
isRequired
|
|
@@ -168,97 +216,138 @@ var SchemaParameterResolver = class {
|
|
|
168
216
|
return answers[param.name];
|
|
169
217
|
} else if (resolver.type === "dynamic") {
|
|
170
218
|
try {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (!items || items.length === 0) {
|
|
174
|
-
throw new Error(`No options available for ${param.name}`);
|
|
219
|
+
if (param.isRequired && param.name !== "authenticationId") {
|
|
220
|
+
console.log(chalk.gray(`Fetching options for ${param.name}...`));
|
|
175
221
|
}
|
|
176
|
-
const
|
|
222
|
+
const items = await resolver.fetch(context.sdk, context.resolvedParams);
|
|
223
|
+
const safeItems = items || [];
|
|
224
|
+
const promptConfig = resolver.prompt(safeItems, context.resolvedParams);
|
|
177
225
|
const answers = await inquirer.prompt([promptConfig]);
|
|
178
226
|
return answers[param.name];
|
|
179
227
|
} catch (error) {
|
|
180
|
-
console.error(
|
|
181
|
-
chalk.red(`Failed to fetch options for ${param.name}:`),
|
|
182
|
-
error instanceof Error ? error.message : error
|
|
183
|
-
);
|
|
184
228
|
throw error;
|
|
185
229
|
}
|
|
186
230
|
} else if (resolver.type === "fields") {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
231
|
+
return await this.resolveFieldsRecursively(
|
|
232
|
+
resolver,
|
|
233
|
+
context,
|
|
234
|
+
param
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
throw new Error(`Unknown resolver type for ${param.name}`);
|
|
238
|
+
}
|
|
239
|
+
async resolveFieldsRecursively(resolver, context, param) {
|
|
240
|
+
const inputs = {};
|
|
241
|
+
let processedFieldKeys = /* @__PURE__ */ new Set();
|
|
242
|
+
let iteration = 0;
|
|
243
|
+
const maxIterations = 5;
|
|
244
|
+
while (iteration < maxIterations) {
|
|
245
|
+
iteration++;
|
|
246
|
+
const updatedContext = {
|
|
247
|
+
...context,
|
|
248
|
+
resolvedParams: {
|
|
249
|
+
...context.resolvedParams,
|
|
250
|
+
inputs
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
console.log(
|
|
254
|
+
chalk.gray(
|
|
255
|
+
`Fetching input fields for ${param.name}${iteration > 1 ? ` (iteration ${iteration})` : ""}...`
|
|
256
|
+
)
|
|
257
|
+
);
|
|
258
|
+
const fields = await resolver.fetch(
|
|
259
|
+
updatedContext.sdk,
|
|
260
|
+
updatedContext.resolvedParams
|
|
261
|
+
);
|
|
262
|
+
if (!fields || fields.length === 0) {
|
|
263
|
+
if (iteration === 1) {
|
|
194
264
|
console.log(
|
|
195
265
|
chalk.yellow(`No input fields required for this action.`)
|
|
196
266
|
);
|
|
197
|
-
return {};
|
|
198
267
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
const newFields = fields.filter(
|
|
271
|
+
(field) => !processedFieldKeys.has(field.key)
|
|
272
|
+
);
|
|
273
|
+
if (newFields.length === 0) {
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
const newRequiredFields = newFields.filter(
|
|
277
|
+
(field) => field.required
|
|
278
|
+
);
|
|
279
|
+
const newOptionalFields = newFields.filter(
|
|
280
|
+
(field) => !field.required
|
|
281
|
+
);
|
|
282
|
+
if (newRequiredFields.length > 0) {
|
|
283
|
+
console.log(
|
|
284
|
+
chalk.blue(
|
|
285
|
+
`
|
|
286
|
+
\u{1F4DD} Please provide values for the following ${iteration === 1 ? "" : "additional "}input fields:`
|
|
287
|
+
)
|
|
288
|
+
);
|
|
289
|
+
for (const field of newRequiredFields) {
|
|
290
|
+
await this.promptForField(field, inputs);
|
|
291
|
+
processedFieldKeys.add(field.key);
|
|
212
292
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
]);
|
|
230
|
-
} catch (error) {
|
|
231
|
-
if (this.isUserCancellation(error)) {
|
|
232
|
-
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
233
|
-
process.exit(0);
|
|
293
|
+
}
|
|
294
|
+
let shouldConfigureOptional = { configure: false };
|
|
295
|
+
if (newOptionalFields.length > 0) {
|
|
296
|
+
console.log(
|
|
297
|
+
chalk.gray(
|
|
298
|
+
`
|
|
299
|
+
There are ${newOptionalFields.length} ${iteration === 1 ? "" : "additional "}optional field(s) available.`
|
|
300
|
+
)
|
|
301
|
+
);
|
|
302
|
+
try {
|
|
303
|
+
shouldConfigureOptional = await inquirer.prompt([
|
|
304
|
+
{
|
|
305
|
+
type: "confirm",
|
|
306
|
+
name: "configure",
|
|
307
|
+
message: `Would you like to configure ${iteration === 1 ? "" : "these additional "}optional fields?`,
|
|
308
|
+
default: false
|
|
234
309
|
}
|
|
235
|
-
|
|
310
|
+
]);
|
|
311
|
+
} catch (error) {
|
|
312
|
+
if (this.isUserCancellation(error)) {
|
|
313
|
+
console.log(chalk.yellow("\n\nOperation cancelled by user"));
|
|
314
|
+
process.exit(0);
|
|
236
315
|
}
|
|
237
|
-
|
|
238
|
-
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
if (shouldConfigureOptional.configure) {
|
|
319
|
+
console.log(chalk.cyan(`
|
|
239
320
|
Optional fields:`));
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
321
|
+
for (const field of newOptionalFields) {
|
|
322
|
+
await this.promptForField(field, inputs);
|
|
323
|
+
processedFieldKeys.add(field.key);
|
|
243
324
|
}
|
|
325
|
+
} else {
|
|
326
|
+
newOptionalFields.forEach(
|
|
327
|
+
(field) => processedFieldKeys.add(field.key)
|
|
328
|
+
);
|
|
244
329
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
chalk.red(`Failed to fetch fields for ${param.name}:`),
|
|
249
|
-
error instanceof Error ? error.message : error
|
|
250
|
-
);
|
|
251
|
-
throw error;
|
|
330
|
+
}
|
|
331
|
+
if (newRequiredFields.length === 0 && (!newOptionalFields.length || !shouldConfigureOptional.configure)) {
|
|
332
|
+
break;
|
|
252
333
|
}
|
|
253
334
|
}
|
|
254
|
-
|
|
335
|
+
if (iteration >= maxIterations) {
|
|
336
|
+
console.log(
|
|
337
|
+
chalk.yellow(
|
|
338
|
+
`
|
|
339
|
+
\u26A0\uFE0F Maximum field resolution iterations reached. Some dynamic fields may not have been discovered.`
|
|
340
|
+
)
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
return inputs;
|
|
255
344
|
}
|
|
256
|
-
getNestedValue(obj,
|
|
257
|
-
return
|
|
345
|
+
getNestedValue(obj, path3) {
|
|
346
|
+
return path3.reduce((current, key) => current?.[key], obj);
|
|
258
347
|
}
|
|
259
|
-
setNestedValue(obj,
|
|
260
|
-
const lastKey =
|
|
261
|
-
const parent =
|
|
348
|
+
setNestedValue(obj, path3, value) {
|
|
349
|
+
const lastKey = path3[path3.length - 1];
|
|
350
|
+
const parent = path3.slice(0, -1).reduce((current, key) => {
|
|
262
351
|
if (!(key in current)) {
|
|
263
352
|
current[key] = {};
|
|
264
353
|
}
|
|
@@ -302,86 +391,8 @@ Optional fields:`));
|
|
|
302
391
|
}
|
|
303
392
|
};
|
|
304
393
|
|
|
305
|
-
// src/utils/pager.ts
|
|
306
|
-
import inquirer2 from "inquirer";
|
|
307
|
-
import chalk2 from "chalk";
|
|
308
|
-
var Pager = class {
|
|
309
|
-
constructor(options = {}) {
|
|
310
|
-
this.allItems = [];
|
|
311
|
-
this.currentOffset = 0;
|
|
312
|
-
this.pageSize = options.pageSize || 20;
|
|
313
|
-
this.showPrompt = options.showPrompt !== false;
|
|
314
|
-
this.itemName = options.itemName || "items";
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Fetch and display paginated results with interactive loading
|
|
318
|
-
*/
|
|
319
|
-
async paginate(fetchFunction, baseParams, displayFunction) {
|
|
320
|
-
let hasMore = true;
|
|
321
|
-
let totalAvailable;
|
|
322
|
-
while (hasMore) {
|
|
323
|
-
const params = {
|
|
324
|
-
...baseParams,
|
|
325
|
-
limit: this.pageSize,
|
|
326
|
-
offset: this.currentOffset
|
|
327
|
-
};
|
|
328
|
-
try {
|
|
329
|
-
const items = await fetchFunction(params);
|
|
330
|
-
if (items.length === 0) {
|
|
331
|
-
displayFunction(this.allItems, this.allItems.length, totalAvailable);
|
|
332
|
-
hasMore = false;
|
|
333
|
-
break;
|
|
334
|
-
}
|
|
335
|
-
const pagination = items.__pagination;
|
|
336
|
-
if (pagination && pagination.count) {
|
|
337
|
-
totalAvailable = pagination.count;
|
|
338
|
-
hasMore = pagination.hasNext;
|
|
339
|
-
} else {
|
|
340
|
-
hasMore = items.length >= this.pageSize;
|
|
341
|
-
}
|
|
342
|
-
this.allItems.push(...items);
|
|
343
|
-
this.currentOffset += items.length;
|
|
344
|
-
displayFunction(this.allItems, this.allItems.length, totalAvailable);
|
|
345
|
-
if (!this.showPrompt) {
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
const totalInfo = totalAvailable ? ` of ${totalAvailable.toLocaleString()}` : "";
|
|
349
|
-
const message = `Load more ${this.itemName}? (${this.allItems.length}${totalInfo} shown so far)`;
|
|
350
|
-
const { loadMore } = await inquirer2.prompt([
|
|
351
|
-
{
|
|
352
|
-
type: "confirm",
|
|
353
|
-
name: "loadMore",
|
|
354
|
-
message,
|
|
355
|
-
default: true
|
|
356
|
-
}
|
|
357
|
-
]);
|
|
358
|
-
if (!loadMore) {
|
|
359
|
-
hasMore = false;
|
|
360
|
-
}
|
|
361
|
-
} catch (error) {
|
|
362
|
-
throw error;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
return {
|
|
366
|
-
items: this.allItems,
|
|
367
|
-
hasMore: this.currentOffset > 0 && hasMore,
|
|
368
|
-
totalShown: this.allItems.length
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Reset the pager state
|
|
373
|
-
*/
|
|
374
|
-
reset() {
|
|
375
|
-
this.allItems = [];
|
|
376
|
-
this.currentOffset = 0;
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
function createPager(options = {}) {
|
|
380
|
-
return new Pager(options);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
394
|
// src/utils/schema-formatter.ts
|
|
384
|
-
import
|
|
395
|
+
import chalk2 from "chalk";
|
|
385
396
|
function getFormatMetadata(schema) {
|
|
386
397
|
return schema?._def?.formatMeta;
|
|
387
398
|
}
|
|
@@ -405,9 +416,9 @@ function formatItemsFromSchema(inputSchema, items) {
|
|
|
405
416
|
}
|
|
406
417
|
function formatSingleItem(item, index, formatMeta) {
|
|
407
418
|
const formatted = formatMeta.format(item);
|
|
408
|
-
let titleLine = `${
|
|
419
|
+
let titleLine = `${chalk2.gray(`${index + 1}.`)} ${chalk2.cyan(formatted.title)}`;
|
|
409
420
|
if (formatted.subtitle) {
|
|
410
|
-
titleLine += ` ${
|
|
421
|
+
titleLine += ` ${chalk2.gray(formatted.subtitle)}`;
|
|
411
422
|
}
|
|
412
423
|
console.log(titleLine);
|
|
413
424
|
for (const detail of formatted.details) {
|
|
@@ -419,35 +430,36 @@ function formatSingleItem(item, index, formatMeta) {
|
|
|
419
430
|
function applyStyle(value, style) {
|
|
420
431
|
switch (style) {
|
|
421
432
|
case "dim":
|
|
422
|
-
return
|
|
433
|
+
return chalk2.dim(value);
|
|
423
434
|
case "accent":
|
|
424
|
-
return
|
|
435
|
+
return chalk2.magenta(value);
|
|
425
436
|
case "warning":
|
|
426
|
-
return
|
|
437
|
+
return chalk2.red(value);
|
|
427
438
|
case "success":
|
|
428
|
-
return
|
|
439
|
+
return chalk2.green(value);
|
|
429
440
|
case "normal":
|
|
430
441
|
default:
|
|
431
|
-
return
|
|
442
|
+
return chalk2.blue(value);
|
|
432
443
|
}
|
|
433
444
|
}
|
|
434
445
|
function formatItemsGeneric(items) {
|
|
435
446
|
items.forEach((item, index) => {
|
|
436
|
-
const name = item.name || item.key || item.id || "Item";
|
|
437
|
-
console.log(`${
|
|
447
|
+
const name = item.title || item.name || item.key || item.id || "Item";
|
|
448
|
+
console.log(`${chalk2.gray(`${index + 1}.`)} ${chalk2.cyan(name)}`);
|
|
438
449
|
if (item.description) {
|
|
439
|
-
console.log(` ${
|
|
450
|
+
console.log(` ${chalk2.dim(item.description)}`);
|
|
440
451
|
}
|
|
441
452
|
console.log();
|
|
442
453
|
});
|
|
443
454
|
}
|
|
444
455
|
|
|
445
456
|
// src/utils/cli-generator.ts
|
|
446
|
-
import
|
|
457
|
+
import chalk3 from "chalk";
|
|
447
458
|
import util from "util";
|
|
459
|
+
import inquirer2 from "inquirer";
|
|
448
460
|
function formatJsonOutput(data) {
|
|
449
461
|
if (data && typeof data === "object" && !Array.isArray(data) && (data.success !== void 0 || data.id || data.status)) {
|
|
450
|
-
console.log(
|
|
462
|
+
console.log(chalk3.green("\u2705 Action completed successfully!\n"));
|
|
451
463
|
}
|
|
452
464
|
console.log(
|
|
453
465
|
util.inspect(data, { colors: true, depth: null, breakLength: 80 })
|
|
@@ -541,10 +553,9 @@ function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
|
|
|
541
553
|
const options = commandObj.opts();
|
|
542
554
|
const isListCommand = cliCommandName.startsWith("list-");
|
|
543
555
|
const hasPaginationParams = parameters.some(
|
|
544
|
-
(p) => p.name === "
|
|
556
|
+
(p) => p.name === "maxItems" || p.name === "pageSize"
|
|
545
557
|
);
|
|
546
|
-
const
|
|
547
|
-
const shouldUsePaging = isListCommand && hasPaginationParams && !hasUserSpecifiedLimit;
|
|
558
|
+
const hasUserSpecifiedMaxItems = "maxItems" in options && options.maxItems !== void 0;
|
|
548
559
|
const shouldUseJson = options.json;
|
|
549
560
|
const rawParams = convertCliArgsToSdkParams(
|
|
550
561
|
parameters,
|
|
@@ -557,55 +568,61 @@ function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
|
|
|
557
568
|
rawParams,
|
|
558
569
|
sdk2
|
|
559
570
|
);
|
|
560
|
-
|
|
561
|
-
|
|
571
|
+
const hasOutputFile = resolvedParams.output;
|
|
572
|
+
if (hasOutputFile) {
|
|
573
|
+
await sdk2[sdkMethodName](resolvedParams);
|
|
574
|
+
console.log(
|
|
575
|
+
chalk3.green(`\u2705 ${cliCommandName} completed successfully!`)
|
|
576
|
+
);
|
|
577
|
+
console.log(chalk3.gray(`Output written to: ${resolvedParams.output}`));
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
if (isListCommand && hasPaginationParams && !shouldUseJson && !hasUserSpecifiedMaxItems) {
|
|
581
|
+
const sdkIterator = sdk2[sdkMethodName](resolvedParams);
|
|
582
|
+
await handlePaginatedListWithAsyncIteration(
|
|
583
|
+
sdkMethodName,
|
|
584
|
+
sdkIterator,
|
|
585
|
+
schema
|
|
586
|
+
);
|
|
562
587
|
} else {
|
|
563
588
|
const result = await sdk2[sdkMethodName](resolvedParams);
|
|
564
|
-
const
|
|
565
|
-
if (
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
} else {
|
|
569
|
-
formatJsonOutput(result);
|
|
570
|
-
}
|
|
571
|
-
} else if (!hasOutputFile) {
|
|
589
|
+
const items = result?.data ? result.data : result;
|
|
590
|
+
if (shouldUseJson) {
|
|
591
|
+
console.log(JSON.stringify(items, null, 2));
|
|
592
|
+
} else if (isListCommand) {
|
|
572
593
|
formatNonPaginatedResults(
|
|
573
|
-
|
|
574
|
-
resolvedParams.
|
|
575
|
-
|
|
594
|
+
items,
|
|
595
|
+
resolvedParams.maxItems,
|
|
596
|
+
hasUserSpecifiedMaxItems,
|
|
576
597
|
shouldUseJson,
|
|
577
598
|
schema,
|
|
578
599
|
sdkMethodName
|
|
579
600
|
);
|
|
580
|
-
} else
|
|
581
|
-
|
|
582
|
-
chalk4.green(`\u2705 ${cliCommandName} completed successfully!`)
|
|
583
|
-
);
|
|
584
|
-
console.log(
|
|
585
|
-
chalk4.gray(`Output written to: ${resolvedParams.output}`)
|
|
586
|
-
);
|
|
601
|
+
} else {
|
|
602
|
+
formatJsonOutput(items);
|
|
587
603
|
}
|
|
588
604
|
}
|
|
589
605
|
} catch (error) {
|
|
590
606
|
if (error instanceof Error && error.message.includes('"code"')) {
|
|
591
607
|
try {
|
|
592
608
|
const validationErrors = JSON.parse(error.message);
|
|
593
|
-
console.error(
|
|
609
|
+
console.error(chalk3.red("\u274C Validation Error:"));
|
|
594
610
|
validationErrors.forEach((err) => {
|
|
595
611
|
const field = err.path?.join(".") || "unknown";
|
|
596
|
-
console.error(
|
|
612
|
+
console.error(chalk3.yellow(` \u2022 ${field}: ${err.message}`));
|
|
597
613
|
});
|
|
598
614
|
console.error(
|
|
599
|
-
"\n" +
|
|
615
|
+
"\n" + chalk3.dim(`Use --help to see available options`)
|
|
600
616
|
);
|
|
601
617
|
} catch {
|
|
602
|
-
console.error(
|
|
618
|
+
console.error(chalk3.red("Error:"), error.message);
|
|
603
619
|
}
|
|
620
|
+
} else if (error instanceof ZapierError) {
|
|
621
|
+
const formattedMessage = formatErrorMessage(error);
|
|
622
|
+
console.error(chalk3.red("\u274C Error:"), formattedMessage);
|
|
604
623
|
} else {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
608
|
-
);
|
|
624
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
625
|
+
console.error(chalk3.red("\u274C Error:"), errorMessage);
|
|
609
626
|
}
|
|
610
627
|
process.exit(1);
|
|
611
628
|
}
|
|
@@ -639,6 +656,9 @@ function addCommand(program2, commandName, config) {
|
|
|
639
656
|
const flags = [`--${kebabName}`];
|
|
640
657
|
if (param.type === "boolean") {
|
|
641
658
|
command.option(flags.join(", "), param.description);
|
|
659
|
+
} else if (param.type === "array") {
|
|
660
|
+
const flagSignature = flags.join(", ") + ` <values...>`;
|
|
661
|
+
command.option(flagSignature, param.description, param.default);
|
|
642
662
|
} else {
|
|
643
663
|
const flagSignature = flags.join(", ") + ` <${param.type}>`;
|
|
644
664
|
command.option(flagSignature, param.description, param.default);
|
|
@@ -689,45 +709,84 @@ function convertValue(value, type) {
|
|
|
689
709
|
return value;
|
|
690
710
|
}
|
|
691
711
|
}
|
|
692
|
-
async function
|
|
693
|
-
const limit = baseParams.limit || 20;
|
|
712
|
+
async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, schema) {
|
|
694
713
|
const itemName = getItemNameFromMethod(sdkMethodName);
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
itemName
|
|
699
|
-
});
|
|
700
|
-
const displayFunction = (items, totalShown, totalAvailable) => {
|
|
701
|
-
if (items.length > 0) {
|
|
702
|
-
console.clear();
|
|
703
|
-
}
|
|
704
|
-
console.log(chalk4.blue(`\u{1F4CB} ${getListTitleFromMethod(sdkMethodName)}
|
|
714
|
+
let totalShown = 0;
|
|
715
|
+
let pageCount = 0;
|
|
716
|
+
console.log(chalk3.blue(`\u{1F4CB} ${getListTitleFromMethod(sdkMethodName)}
|
|
705
717
|
`));
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
718
|
+
try {
|
|
719
|
+
for await (const page of sdkResult) {
|
|
720
|
+
const items = page.data || page;
|
|
721
|
+
pageCount++;
|
|
722
|
+
if (!Array.isArray(items)) {
|
|
723
|
+
console.log(chalk3.yellow(`No ${itemName} found.`));
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
if (items.length === 0 && pageCount === 1) {
|
|
727
|
+
console.log(chalk3.yellow(`No ${itemName} found.`));
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
if (items.length === 0) {
|
|
731
|
+
break;
|
|
732
|
+
}
|
|
733
|
+
if (pageCount > 1) {
|
|
734
|
+
console.clear();
|
|
735
|
+
console.log(
|
|
736
|
+
chalk3.blue(`\u{1F4CB} ${getListTitleFromMethod(sdkMethodName)}
|
|
737
|
+
`)
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
if (schema) {
|
|
741
|
+
formatItemsFromSchema(schema, items);
|
|
742
|
+
} else {
|
|
743
|
+
formatItemsGeneric2(items);
|
|
744
|
+
}
|
|
745
|
+
totalShown += items.length;
|
|
746
|
+
console.log(
|
|
747
|
+
chalk3.green(
|
|
748
|
+
`
|
|
749
|
+
\u2705 Showing ${totalShown} ${itemName} (page ${pageCount})`
|
|
750
|
+
)
|
|
751
|
+
);
|
|
752
|
+
if (page.nextCursor) {
|
|
753
|
+
const { continueReading } = await inquirer2.prompt([
|
|
754
|
+
{
|
|
755
|
+
type: "confirm",
|
|
756
|
+
name: "continueReading",
|
|
757
|
+
message: `Load next page?`,
|
|
758
|
+
default: true
|
|
759
|
+
}
|
|
760
|
+
]);
|
|
761
|
+
if (!continueReading) {
|
|
762
|
+
break;
|
|
763
|
+
}
|
|
764
|
+
} else {
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
709
767
|
}
|
|
710
|
-
|
|
711
|
-
|
|
768
|
+
console.log(chalk3.gray(`
|
|
769
|
+
\u{1F4C4} Finished browsing ${itemName}`));
|
|
770
|
+
} catch (error) {
|
|
771
|
+
const items = sdkResult?.data || sdkResult;
|
|
772
|
+
if (Array.isArray(items)) {
|
|
773
|
+
if (items.length === 0) {
|
|
774
|
+
console.log(chalk3.yellow(`No ${itemName} found.`));
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
if (schema) {
|
|
778
|
+
formatItemsFromSchema(schema, items);
|
|
779
|
+
} else {
|
|
780
|
+
formatItemsGeneric2(items);
|
|
781
|
+
}
|
|
782
|
+
console.log(chalk3.green(`
|
|
783
|
+
\u2705 Showing ${items.length} ${itemName}`));
|
|
712
784
|
} else {
|
|
713
|
-
|
|
785
|
+
throw error;
|
|
714
786
|
}
|
|
715
|
-
|
|
716
|
-
console.log(
|
|
717
|
-
chalk4.green(`
|
|
718
|
-
\u2705 Showing ${totalShown}${totalInfo} ${itemName}`)
|
|
719
|
-
);
|
|
720
|
-
};
|
|
721
|
-
await pager.paginate(
|
|
722
|
-
(params) => sdk2[sdkMethodName]({
|
|
723
|
-
...baseParams,
|
|
724
|
-
...params
|
|
725
|
-
}),
|
|
726
|
-
{},
|
|
727
|
-
displayFunction
|
|
728
|
-
);
|
|
787
|
+
}
|
|
729
788
|
}
|
|
730
|
-
function formatNonPaginatedResults(result,
|
|
789
|
+
function formatNonPaginatedResults(result, requestedMaxItems, userSpecifiedMaxItems, useRawJson, schema, methodName) {
|
|
731
790
|
if (!Array.isArray(result)) {
|
|
732
791
|
if (useRawJson) {
|
|
733
792
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -742,10 +801,10 @@ function formatNonPaginatedResults(result, requestedLimit, userSpecifiedLimit, u
|
|
|
742
801
|
}
|
|
743
802
|
const itemName = methodName ? getItemNameFromMethod(methodName) : "items";
|
|
744
803
|
if (result.length === 0) {
|
|
745
|
-
console.log(
|
|
804
|
+
console.log(chalk3.yellow(`No ${itemName} found.`));
|
|
746
805
|
return;
|
|
747
806
|
}
|
|
748
|
-
console.log(
|
|
807
|
+
console.log(chalk3.green(`
|
|
749
808
|
\u2705 Found ${result.length} ${itemName}:
|
|
750
809
|
`));
|
|
751
810
|
if (schema) {
|
|
@@ -753,24 +812,24 @@ function formatNonPaginatedResults(result, requestedLimit, userSpecifiedLimit, u
|
|
|
753
812
|
} else {
|
|
754
813
|
formatItemsGeneric2(result);
|
|
755
814
|
}
|
|
756
|
-
if (
|
|
815
|
+
if (userSpecifiedMaxItems && requestedMaxItems) {
|
|
757
816
|
console.log(
|
|
758
|
-
|
|
817
|
+
chalk3.gray(
|
|
759
818
|
`
|
|
760
|
-
\u{1F4C4} Showing up to ${
|
|
819
|
+
\u{1F4C4} Showing up to ${requestedMaxItems} ${itemName} (--max-items ${requestedMaxItems})`
|
|
761
820
|
)
|
|
762
821
|
);
|
|
763
822
|
} else {
|
|
764
|
-
console.log(
|
|
823
|
+
console.log(chalk3.gray(`
|
|
765
824
|
\u{1F4C4} All available ${itemName} shown`));
|
|
766
825
|
}
|
|
767
826
|
}
|
|
768
827
|
function formatItemsGeneric2(items) {
|
|
769
828
|
items.forEach((item, index) => {
|
|
770
|
-
const name = item.name || item.key || item.id || "Item";
|
|
771
|
-
console.log(`${
|
|
829
|
+
const name = item.title || item.name || item.key || item.id || "Item";
|
|
830
|
+
console.log(`${chalk3.gray(`${index + 1}.`)} ${chalk3.cyan(name)}`);
|
|
772
831
|
if (item.description) {
|
|
773
|
-
console.log(` ${
|
|
832
|
+
console.log(` ${chalk3.dim(item.description)}`);
|
|
774
833
|
}
|
|
775
834
|
console.log();
|
|
776
835
|
});
|
|
@@ -820,19 +879,19 @@ var spinPromise = async (promise, text) => {
|
|
|
820
879
|
};
|
|
821
880
|
|
|
822
881
|
// src/utils/log.ts
|
|
823
|
-
import
|
|
882
|
+
import chalk4 from "chalk";
|
|
824
883
|
var log = {
|
|
825
884
|
info: (message, ...args) => {
|
|
826
|
-
console.log(
|
|
885
|
+
console.log(chalk4.blue("\u2139"), message, ...args);
|
|
827
886
|
},
|
|
828
887
|
error: (message, ...args) => {
|
|
829
|
-
console.error(
|
|
888
|
+
console.error(chalk4.red("\u2716"), message, ...args);
|
|
830
889
|
},
|
|
831
890
|
success: (message, ...args) => {
|
|
832
|
-
console.log(
|
|
891
|
+
console.log(chalk4.green("\u2713"), message, ...args);
|
|
833
892
|
},
|
|
834
893
|
warn: (message, ...args) => {
|
|
835
|
-
console.log(
|
|
894
|
+
console.log(chalk4.yellow("\u26A0"), message, ...args);
|
|
836
895
|
}
|
|
837
896
|
};
|
|
838
897
|
var log_default = log;
|
|
@@ -868,17 +927,17 @@ var client_default = api;
|
|
|
868
927
|
|
|
869
928
|
// src/utils/getCallablePromise.ts
|
|
870
929
|
var getCallablePromise = () => {
|
|
871
|
-
let
|
|
930
|
+
let resolve2 = () => {
|
|
872
931
|
};
|
|
873
932
|
let reject = () => {
|
|
874
933
|
};
|
|
875
934
|
const promise = new Promise((_resolve, _reject) => {
|
|
876
|
-
|
|
935
|
+
resolve2 = _resolve;
|
|
877
936
|
reject = _reject;
|
|
878
937
|
});
|
|
879
938
|
return {
|
|
880
939
|
promise,
|
|
881
|
-
resolve,
|
|
940
|
+
resolve: resolve2,
|
|
882
941
|
reject
|
|
883
942
|
};
|
|
884
943
|
};
|
|
@@ -887,12 +946,12 @@ var getCallablePromise_default = getCallablePromise;
|
|
|
887
946
|
// src/utils/auth/login.ts
|
|
888
947
|
import { updateLogin, logout } from "@zapier/zapier-sdk-cli-login";
|
|
889
948
|
var findAvailablePort = () => {
|
|
890
|
-
return new Promise((
|
|
949
|
+
return new Promise((resolve2, reject) => {
|
|
891
950
|
let portIndex = 0;
|
|
892
951
|
const tryPort = (port) => {
|
|
893
952
|
const server = express().listen(port, () => {
|
|
894
953
|
server.close();
|
|
895
|
-
|
|
954
|
+
resolve2(port);
|
|
896
955
|
});
|
|
897
956
|
server.on("error", (err) => {
|
|
898
957
|
if (err.code === "EADDRINUSE") {
|
|
@@ -982,15 +1041,15 @@ var login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
|
|
|
982
1041
|
} finally {
|
|
983
1042
|
process.off("SIGINT", cleanup);
|
|
984
1043
|
process.off("SIGTERM", cleanup);
|
|
985
|
-
await new Promise((
|
|
1044
|
+
await new Promise((resolve2) => {
|
|
986
1045
|
const timeout = setTimeout(() => {
|
|
987
1046
|
log_default.info("Server close timed out, forcing connection shutdown...");
|
|
988
1047
|
connections.forEach((conn) => conn.destroy());
|
|
989
|
-
|
|
1048
|
+
resolve2();
|
|
990
1049
|
}, 1e3);
|
|
991
1050
|
server.close(() => {
|
|
992
1051
|
clearTimeout(timeout);
|
|
993
|
-
|
|
1052
|
+
resolve2();
|
|
994
1053
|
});
|
|
995
1054
|
});
|
|
996
1055
|
}
|
|
@@ -1062,47 +1121,665 @@ function createLogoutCommand() {
|
|
|
1062
1121
|
});
|
|
1063
1122
|
}
|
|
1064
1123
|
|
|
1065
|
-
// src/commands/
|
|
1124
|
+
// src/commands/configPath.ts
|
|
1066
1125
|
import { Command as Command3 } from "commander";
|
|
1067
|
-
import {
|
|
1068
|
-
function
|
|
1069
|
-
return new Command3("
|
|
1126
|
+
import { getConfigPath } from "@zapier/zapier-sdk-cli-login";
|
|
1127
|
+
function createConfigPathCommand() {
|
|
1128
|
+
return new Command3("get-config-path").description("Show the path to the configuration file").action(async () => {
|
|
1129
|
+
console.log(`Configuration file: ${getConfigPath()}`);
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
// src/commands/generate-types/cli.ts
|
|
1134
|
+
import { Command as Command4 } from "commander";
|
|
1135
|
+
import { createZapierSdk } from "@zapier/zapier-sdk";
|
|
1136
|
+
|
|
1137
|
+
// src/commands/generate-types/schemas.ts
|
|
1138
|
+
import { z as z3 } from "zod";
|
|
1139
|
+
import {
|
|
1140
|
+
AppKeyPropertySchema,
|
|
1141
|
+
AuthenticationIdPropertySchema,
|
|
1142
|
+
OutputPropertySchema,
|
|
1143
|
+
DebugPropertySchema
|
|
1144
|
+
} from "@zapier/zapier-sdk";
|
|
1145
|
+
var GenerateTypesSchema = z3.object({
|
|
1146
|
+
appKey: AppKeyPropertySchema.describe("App key to generate SDK code for"),
|
|
1147
|
+
authenticationId: AuthenticationIdPropertySchema.optional(),
|
|
1148
|
+
output: OutputPropertySchema.optional().describe(
|
|
1149
|
+
"Output file path (defaults to generated/<appKey>.ts)"
|
|
1150
|
+
),
|
|
1151
|
+
debug: DebugPropertySchema.describe(
|
|
1152
|
+
"Enable debug logging during generation"
|
|
1153
|
+
)
|
|
1154
|
+
}).describe("Generate TypeScript SDK code for a specific app");
|
|
1155
|
+
|
|
1156
|
+
// src/commands/generate-types/index.ts
|
|
1157
|
+
import * as fs from "fs";
|
|
1158
|
+
import * as path from "path";
|
|
1159
|
+
function generateFetchMethodSignature() {
|
|
1160
|
+
return ` /** Make authenticated HTTP requests through Zapier's Relay service */
|
|
1161
|
+
fetch: (options: Omit<z.infer<typeof RelayFetchSchema>, 'authenticationId'>) => Promise<Response>`;
|
|
1162
|
+
}
|
|
1163
|
+
async function generateTypes(options) {
|
|
1164
|
+
const {
|
|
1165
|
+
appKey,
|
|
1166
|
+
authenticationId,
|
|
1167
|
+
output = `./types/${appKey}.d.ts`,
|
|
1168
|
+
sdk: sdk2
|
|
1169
|
+
} = options;
|
|
1170
|
+
const { app, version } = parseAppIdentifier(appKey);
|
|
1171
|
+
const actionsResult = await sdk2.listActions({
|
|
1172
|
+
appKey: app
|
|
1173
|
+
});
|
|
1174
|
+
const actions = actionsResult.data;
|
|
1175
|
+
if (actions.length === 0) {
|
|
1176
|
+
const typeDefinitions2 = generateEmptyTypesFile(app, version);
|
|
1177
|
+
if (output) {
|
|
1178
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
1179
|
+
fs.writeFileSync(output, typeDefinitions2, "utf8");
|
|
1180
|
+
}
|
|
1181
|
+
return typeDefinitions2;
|
|
1182
|
+
}
|
|
1183
|
+
const actionsWithFields = [];
|
|
1184
|
+
if (authenticationId) {
|
|
1185
|
+
for (const action of actions) {
|
|
1186
|
+
try {
|
|
1187
|
+
const fieldsResult = await sdk2.listInputFields({
|
|
1188
|
+
appKey: action.app_key,
|
|
1189
|
+
actionKey: action.key,
|
|
1190
|
+
actionType: action.action_type,
|
|
1191
|
+
authenticationId
|
|
1192
|
+
});
|
|
1193
|
+
const fields = fieldsResult.data;
|
|
1194
|
+
actionsWithFields.push({ ...action, inputFields: fields });
|
|
1195
|
+
} catch {
|
|
1196
|
+
actionsWithFields.push({ ...action, inputFields: [] });
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
} else {
|
|
1200
|
+
actions.forEach((action) => {
|
|
1201
|
+
actionsWithFields.push({ ...action, inputFields: [] });
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
const typeDefinitions = generateTypeDefinitions(
|
|
1205
|
+
app,
|
|
1206
|
+
actionsWithFields,
|
|
1207
|
+
version
|
|
1208
|
+
);
|
|
1209
|
+
if (output) {
|
|
1210
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
1211
|
+
fs.writeFileSync(output, typeDefinitions, "utf8");
|
|
1212
|
+
}
|
|
1213
|
+
return typeDefinitions;
|
|
1214
|
+
}
|
|
1215
|
+
function parseAppIdentifier(identifier) {
|
|
1216
|
+
const parts = identifier.split("@");
|
|
1217
|
+
return {
|
|
1218
|
+
app: parts[0],
|
|
1219
|
+
version: parts[1]
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
function generateTypeDefinitions(appKey, actions, version) {
|
|
1223
|
+
if (actions.length === 0) {
|
|
1224
|
+
return generateEmptyTypesFile(appKey, version);
|
|
1225
|
+
}
|
|
1226
|
+
const actionsByType = actions.reduce(
|
|
1227
|
+
(acc, action) => {
|
|
1228
|
+
if (!acc[action.action_type]) {
|
|
1229
|
+
acc[action.action_type] = [];
|
|
1230
|
+
}
|
|
1231
|
+
acc[action.action_type].push(action);
|
|
1232
|
+
return acc;
|
|
1233
|
+
},
|
|
1234
|
+
{}
|
|
1235
|
+
);
|
|
1236
|
+
const appName = capitalize(appKey);
|
|
1237
|
+
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
1238
|
+
let output = `/* eslint-disable @typescript-eslint/naming-convention */
|
|
1239
|
+
/**
|
|
1240
|
+
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
1241
|
+
${versionComment}
|
|
1242
|
+
* Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1243
|
+
*
|
|
1244
|
+
* Usage:
|
|
1245
|
+
* import type { ${appName}Sdk } from './path/to/this/file'
|
|
1246
|
+
* const sdk = createZapierSdk() as unknown as ${appName}Sdk
|
|
1247
|
+
*
|
|
1248
|
+
* // Direct usage (per-call auth):
|
|
1249
|
+
* await sdk.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
|
|
1250
|
+
*
|
|
1251
|
+
* // Factory usage (pinned auth):
|
|
1252
|
+
* const my${appName} = sdk.apps.${appKey}({ authenticationId: 123 })
|
|
1253
|
+
* await my${appName}.search.user_by_email({ inputs: { email } })
|
|
1254
|
+
*/
|
|
1255
|
+
|
|
1256
|
+
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
1257
|
+
import { z } from 'zod'
|
|
1258
|
+
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
1259
|
+
|
|
1260
|
+
`;
|
|
1261
|
+
actions.forEach((action) => {
|
|
1262
|
+
if (action.inputFields.length > 0) {
|
|
1263
|
+
const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
|
|
1264
|
+
sanitizeActionName(action.key)
|
|
1265
|
+
)}Inputs`;
|
|
1266
|
+
output += `interface ${inputTypeName} {
|
|
1267
|
+
`;
|
|
1268
|
+
action.inputFields.forEach((field) => {
|
|
1269
|
+
const isOptional = !field.required;
|
|
1270
|
+
const fieldType = mapFieldTypeToTypeScript(field);
|
|
1271
|
+
const description = field.helpText ? ` /** ${escapeComment(field.helpText)} */
|
|
1272
|
+
` : "";
|
|
1273
|
+
output += `${description} ${sanitizeFieldName(field.key)}${isOptional ? "?" : ""}: ${fieldType}
|
|
1274
|
+
`;
|
|
1275
|
+
});
|
|
1276
|
+
output += `}
|
|
1277
|
+
|
|
1278
|
+
`;
|
|
1279
|
+
}
|
|
1280
|
+
});
|
|
1281
|
+
Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
|
|
1282
|
+
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
1283
|
+
output += `interface ${typeName} {
|
|
1284
|
+
`;
|
|
1285
|
+
typeActions.forEach((action) => {
|
|
1286
|
+
const actionName = sanitizeActionName(action.key);
|
|
1287
|
+
const description = action.description ? ` /** ${escapeComment(action.description)} */
|
|
1288
|
+
` : "";
|
|
1289
|
+
if (action.inputFields.length > 0) {
|
|
1290
|
+
const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
|
|
1291
|
+
sanitizeActionName(action.key)
|
|
1292
|
+
)}Inputs`;
|
|
1293
|
+
output += `${description} ${actionName}: (options: { inputs: ${inputTypeName} } & Omit<ActionExecutionOptions, 'inputs'>) => Promise<ActionExecutionResult>
|
|
1294
|
+
`;
|
|
1295
|
+
} else {
|
|
1296
|
+
output += `${description} ${actionName}: (options?: { inputs?: Record<string, any> } & ActionExecutionOptions) => Promise<ActionExecutionResult>
|
|
1297
|
+
`;
|
|
1298
|
+
}
|
|
1299
|
+
});
|
|
1300
|
+
output += `}
|
|
1301
|
+
|
|
1302
|
+
`;
|
|
1303
|
+
});
|
|
1304
|
+
output += `interface ${appName}AppProxy {
|
|
1305
|
+
`;
|
|
1306
|
+
Object.keys(actionsByType).forEach((actionType) => {
|
|
1307
|
+
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
1308
|
+
output += ` ${actionType}: ${typeName}
|
|
1309
|
+
`;
|
|
1310
|
+
});
|
|
1311
|
+
output += generateFetchMethodSignature() + "\n";
|
|
1312
|
+
output += `}
|
|
1313
|
+
|
|
1314
|
+
`;
|
|
1315
|
+
output += `interface ${appName}AppFactory {
|
|
1316
|
+
`;
|
|
1317
|
+
output += ` (options: { authenticationId: number }): ${appName}AppProxy
|
|
1318
|
+
`;
|
|
1319
|
+
output += `}
|
|
1320
|
+
|
|
1321
|
+
`;
|
|
1322
|
+
output += `type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
|
|
1323
|
+
|
|
1324
|
+
`;
|
|
1325
|
+
output += `export interface ${appName}Sdk {
|
|
1326
|
+
`;
|
|
1327
|
+
output += ` apps: {
|
|
1328
|
+
`;
|
|
1329
|
+
output += ` ${appKey}: ${appName}AppWithFactory
|
|
1330
|
+
`;
|
|
1331
|
+
output += ` }
|
|
1332
|
+
`;
|
|
1333
|
+
output += `}
|
|
1334
|
+
`;
|
|
1335
|
+
return output;
|
|
1336
|
+
}
|
|
1337
|
+
function generateEmptyTypesFile(appKey, version) {
|
|
1338
|
+
const appName = capitalize(appKey);
|
|
1339
|
+
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
1340
|
+
return `/* eslint-disable @typescript-eslint/naming-convention */
|
|
1341
|
+
/**
|
|
1342
|
+
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
1343
|
+
${versionComment}
|
|
1344
|
+
* Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1345
|
+
*
|
|
1346
|
+
* No actions found for this app.
|
|
1347
|
+
*/
|
|
1348
|
+
|
|
1349
|
+
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
1350
|
+
import { z } from 'zod'
|
|
1351
|
+
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
1352
|
+
|
|
1353
|
+
interface ${appName}AppProxy {
|
|
1354
|
+
// No actions available
|
|
1355
|
+
${generateFetchMethodSignature()}
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
interface ${appName}AppFactory {
|
|
1359
|
+
(options: { authenticationId: number }): ${appName}AppProxy
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
|
|
1363
|
+
|
|
1364
|
+
export interface ${appName}Sdk {
|
|
1365
|
+
apps: {
|
|
1366
|
+
${appKey}: ${appName}AppWithFactory
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
`;
|
|
1370
|
+
}
|
|
1371
|
+
function capitalize(str) {
|
|
1372
|
+
return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
|
|
1373
|
+
}
|
|
1374
|
+
function sanitizeActionName(actionKey) {
|
|
1375
|
+
let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1376
|
+
if (/^[0-9]/.test(sanitized)) {
|
|
1377
|
+
sanitized = "_" + sanitized;
|
|
1378
|
+
}
|
|
1379
|
+
return sanitized;
|
|
1380
|
+
}
|
|
1381
|
+
function sanitizeFieldName(fieldKey) {
|
|
1382
|
+
let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1383
|
+
if (/^[0-9]/.test(sanitized)) {
|
|
1384
|
+
sanitized = "_" + sanitized;
|
|
1385
|
+
}
|
|
1386
|
+
return sanitized;
|
|
1387
|
+
}
|
|
1388
|
+
function escapeComment(comment) {
|
|
1389
|
+
return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
1390
|
+
}
|
|
1391
|
+
function mapFieldTypeToTypeScript(field) {
|
|
1392
|
+
if (field.choices && field.choices.length > 0) {
|
|
1393
|
+
const choiceValues = field.choices.filter(
|
|
1394
|
+
(choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
|
|
1395
|
+
).map(
|
|
1396
|
+
(choice) => typeof choice.value === "string" ? `"${choice.value}"` : choice.value
|
|
1397
|
+
);
|
|
1398
|
+
if (choiceValues.length > 0) {
|
|
1399
|
+
return choiceValues.join(" | ");
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
switch (field.type?.toLowerCase()) {
|
|
1403
|
+
case "string":
|
|
1404
|
+
case "text":
|
|
1405
|
+
case "email":
|
|
1406
|
+
case "url":
|
|
1407
|
+
case "password":
|
|
1408
|
+
return "string";
|
|
1409
|
+
case "integer":
|
|
1410
|
+
case "number":
|
|
1411
|
+
return "number";
|
|
1412
|
+
case "boolean":
|
|
1413
|
+
return "boolean";
|
|
1414
|
+
case "datetime":
|
|
1415
|
+
case "date":
|
|
1416
|
+
return "string";
|
|
1417
|
+
// ISO date strings
|
|
1418
|
+
case "file":
|
|
1419
|
+
return "string";
|
|
1420
|
+
// File URL or content
|
|
1421
|
+
case "array":
|
|
1422
|
+
return "any[]";
|
|
1423
|
+
case "object":
|
|
1424
|
+
return "Record<string, any>";
|
|
1425
|
+
default:
|
|
1426
|
+
return "string | number | boolean";
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
// src/commands/generate-types/cli.ts
|
|
1431
|
+
import chalk5 from "chalk";
|
|
1432
|
+
|
|
1433
|
+
// src/utils/cli-generator-utils.ts
|
|
1434
|
+
import { z as z4 } from "zod";
|
|
1435
|
+
import { hasResolver as hasResolver3, isPositional as isPositional2 } from "@zapier/zapier-sdk";
|
|
1436
|
+
function analyzeZodSchema2(schema) {
|
|
1437
|
+
const parameters = [];
|
|
1438
|
+
if (schema instanceof z4.ZodObject) {
|
|
1439
|
+
const shape = schema.shape;
|
|
1440
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
1441
|
+
const param = analyzeZodField2(key, fieldSchema);
|
|
1442
|
+
if (param) {
|
|
1443
|
+
parameters.push(param);
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
return parameters;
|
|
1448
|
+
}
|
|
1449
|
+
function analyzeZodField2(name, schema) {
|
|
1450
|
+
let baseSchema = schema;
|
|
1451
|
+
let required = true;
|
|
1452
|
+
let defaultValue = void 0;
|
|
1453
|
+
if (baseSchema instanceof z4.ZodOptional) {
|
|
1454
|
+
required = false;
|
|
1455
|
+
baseSchema = baseSchema._def.innerType;
|
|
1456
|
+
}
|
|
1457
|
+
if (baseSchema instanceof z4.ZodDefault) {
|
|
1458
|
+
required = false;
|
|
1459
|
+
defaultValue = baseSchema._def.defaultValue();
|
|
1460
|
+
baseSchema = baseSchema._def.innerType;
|
|
1461
|
+
}
|
|
1462
|
+
let paramType = "string";
|
|
1463
|
+
let choices;
|
|
1464
|
+
if (baseSchema instanceof z4.ZodString) {
|
|
1465
|
+
paramType = "string";
|
|
1466
|
+
} else if (baseSchema instanceof z4.ZodNumber) {
|
|
1467
|
+
paramType = "number";
|
|
1468
|
+
} else if (baseSchema instanceof z4.ZodBoolean) {
|
|
1469
|
+
paramType = "boolean";
|
|
1470
|
+
} else if (baseSchema instanceof z4.ZodArray) {
|
|
1471
|
+
paramType = "array";
|
|
1472
|
+
} else if (baseSchema instanceof z4.ZodEnum) {
|
|
1473
|
+
paramType = "string";
|
|
1474
|
+
choices = baseSchema._def.values;
|
|
1475
|
+
} else if (baseSchema instanceof z4.ZodRecord) {
|
|
1476
|
+
paramType = "string";
|
|
1477
|
+
}
|
|
1478
|
+
return {
|
|
1479
|
+
name,
|
|
1480
|
+
type: paramType,
|
|
1481
|
+
required,
|
|
1482
|
+
description: schema.description,
|
|
1483
|
+
default: defaultValue,
|
|
1484
|
+
choices,
|
|
1485
|
+
hasResolver: hasResolver3(name),
|
|
1486
|
+
isPositional: isPositional2(schema)
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
function convertCliArgsToSdkParams2(parameters, positionalArgs, options) {
|
|
1490
|
+
const sdkParams = {};
|
|
1491
|
+
let argIndex = 0;
|
|
1492
|
+
parameters.forEach((param) => {
|
|
1493
|
+
if ((param.required || param.isPositional) && argIndex < positionalArgs.length) {
|
|
1494
|
+
sdkParams[param.name] = convertValue2(
|
|
1495
|
+
positionalArgs[argIndex],
|
|
1496
|
+
param.type
|
|
1497
|
+
);
|
|
1498
|
+
argIndex++;
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
1502
|
+
const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
1503
|
+
const param = parameters.find((p) => p.name === camelKey);
|
|
1504
|
+
if (param && value !== void 0) {
|
|
1505
|
+
sdkParams[camelKey] = convertValue2(value, param.type);
|
|
1506
|
+
}
|
|
1507
|
+
});
|
|
1508
|
+
return sdkParams;
|
|
1509
|
+
}
|
|
1510
|
+
function convertValue2(value, type) {
|
|
1511
|
+
switch (type) {
|
|
1512
|
+
case "number":
|
|
1513
|
+
return Number(value);
|
|
1514
|
+
case "boolean":
|
|
1515
|
+
return Boolean(value);
|
|
1516
|
+
case "array":
|
|
1517
|
+
return Array.isArray(value) ? value : [value];
|
|
1518
|
+
case "string":
|
|
1519
|
+
default:
|
|
1520
|
+
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
|
|
1521
|
+
try {
|
|
1522
|
+
return JSON.parse(value);
|
|
1523
|
+
} catch {
|
|
1524
|
+
return value;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
return value;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
// src/commands/generate-types/cli.ts
|
|
1532
|
+
function createGenerateTypesCommand() {
|
|
1533
|
+
const parameters = analyzeZodSchema2(GenerateTypesSchema);
|
|
1534
|
+
const description = GenerateTypesSchema.description || "Generate TypeScript SDK types for a specific app";
|
|
1535
|
+
const command = new Command4("generate-types").description(description);
|
|
1536
|
+
parameters.forEach((param) => {
|
|
1537
|
+
const kebabName = param.name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
1538
|
+
if (param.hasResolver && param.required) {
|
|
1539
|
+
command.argument(
|
|
1540
|
+
`[${kebabName}]`,
|
|
1541
|
+
param.description || `${kebabName} parameter`
|
|
1542
|
+
);
|
|
1543
|
+
} else if (param.required) {
|
|
1544
|
+
command.argument(
|
|
1545
|
+
`<${kebabName}>`,
|
|
1546
|
+
param.description || `${kebabName} parameter`
|
|
1547
|
+
);
|
|
1548
|
+
} else if (param.isPositional) {
|
|
1549
|
+
command.argument(
|
|
1550
|
+
`[${kebabName}]`,
|
|
1551
|
+
param.description || `${kebabName} parameter`
|
|
1552
|
+
);
|
|
1553
|
+
} else {
|
|
1554
|
+
const flags = [`--${kebabName}`];
|
|
1555
|
+
if (param.type === "boolean") {
|
|
1556
|
+
command.option(flags.join(", "), param.description);
|
|
1557
|
+
} else {
|
|
1558
|
+
const flagSignature = flags.join(", ") + ` <${param.type}>`;
|
|
1559
|
+
command.option(flagSignature, param.description, param.default);
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
});
|
|
1563
|
+
command.option("--json", "Output raw JSON instead of formatted results");
|
|
1564
|
+
command.action(async (...args) => {
|
|
1070
1565
|
try {
|
|
1071
|
-
const
|
|
1072
|
-
|
|
1073
|
-
|
|
1566
|
+
const commandObj = args[args.length - 1];
|
|
1567
|
+
const options = commandObj.opts();
|
|
1568
|
+
const rawParams = convertCliArgsToSdkParams2(
|
|
1569
|
+
parameters,
|
|
1570
|
+
args.slice(0, -1),
|
|
1571
|
+
options
|
|
1074
1572
|
);
|
|
1075
|
-
|
|
1076
|
-
|
|
1573
|
+
const sdk2 = createZapierSdk();
|
|
1574
|
+
const resolver = new SchemaParameterResolver();
|
|
1575
|
+
const resolvedParams = await resolver.resolveParameters(
|
|
1576
|
+
GenerateTypesSchema,
|
|
1577
|
+
rawParams,
|
|
1578
|
+
sdk2
|
|
1077
1579
|
);
|
|
1078
|
-
} catch {
|
|
1079
1580
|
console.log(
|
|
1080
|
-
|
|
1581
|
+
chalk5.blue(
|
|
1582
|
+
`\u{1F527} Generating TypeScript types for ${resolvedParams.appKey}...`
|
|
1583
|
+
)
|
|
1584
|
+
);
|
|
1585
|
+
const result = await generateTypes({ ...resolvedParams, sdk: sdk2 });
|
|
1586
|
+
if (options.json) {
|
|
1587
|
+
console.log(JSON.stringify({ result }, null, 2));
|
|
1588
|
+
} else {
|
|
1589
|
+
const output = resolvedParams.output || `./types/${resolvedParams.appKey}.d.ts`;
|
|
1590
|
+
console.log(chalk5.green("\u2705 TypeScript types generated successfully!"));
|
|
1591
|
+
console.log(chalk5.gray(`Output written to: ${output}`));
|
|
1592
|
+
}
|
|
1593
|
+
} catch (error) {
|
|
1594
|
+
console.error(
|
|
1595
|
+
chalk5.red("Error:"),
|
|
1596
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1081
1597
|
);
|
|
1082
1598
|
process.exit(1);
|
|
1083
1599
|
}
|
|
1084
1600
|
});
|
|
1601
|
+
return command;
|
|
1085
1602
|
}
|
|
1086
1603
|
|
|
1087
|
-
// src/commands/
|
|
1088
|
-
import { Command as
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1604
|
+
// src/commands/bundle-code/cli.ts
|
|
1605
|
+
import { Command as Command5 } from "commander";
|
|
1606
|
+
|
|
1607
|
+
// src/commands/bundle-code/schemas.ts
|
|
1608
|
+
import { z as z5 } from "zod";
|
|
1609
|
+
import { OutputPropertySchema as OutputPropertySchema2 } from "@zapier/zapier-sdk";
|
|
1610
|
+
var BundleCodeSchema = z5.object({
|
|
1611
|
+
input: z5.string().min(1).describe("Input TypeScript file path to bundle"),
|
|
1612
|
+
output: OutputPropertySchema2.optional().describe(
|
|
1613
|
+
"Output file path (defaults to input with .js extension)"
|
|
1614
|
+
),
|
|
1615
|
+
string: z5.boolean().default(false).describe("Return bundled code as string instead of writing to file"),
|
|
1616
|
+
minify: z5.boolean().default(false).describe("Minify the bundled output"),
|
|
1617
|
+
target: z5.string().default("es2017").describe("ECMAScript target version"),
|
|
1618
|
+
cjs: z5.boolean().default(false).describe("Output CommonJS format instead of ESM")
|
|
1619
|
+
}).describe("Bundle TypeScript code into executable JavaScript");
|
|
1620
|
+
|
|
1621
|
+
// src/commands/bundle-code/index.ts
|
|
1622
|
+
import { buildSync } from "esbuild";
|
|
1623
|
+
import * as fs2 from "fs";
|
|
1624
|
+
import * as path2 from "path";
|
|
1625
|
+
var ZapierBundleError = class extends Error {
|
|
1626
|
+
constructor(message, details, originalError) {
|
|
1627
|
+
super(message);
|
|
1628
|
+
this.code = "ZAPIER_BUNDLE_ERROR";
|
|
1629
|
+
this.name = "ZapierBundleError";
|
|
1630
|
+
this.details = details;
|
|
1631
|
+
this.originalError = originalError;
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
async function bundleCode(options) {
|
|
1635
|
+
const {
|
|
1636
|
+
input,
|
|
1637
|
+
output,
|
|
1638
|
+
target = "es2020",
|
|
1639
|
+
cjs = false,
|
|
1640
|
+
minify = false,
|
|
1641
|
+
string: returnString = false
|
|
1642
|
+
} = options;
|
|
1643
|
+
const resolvedInput = path2.resolve(process.cwd(), input);
|
|
1644
|
+
try {
|
|
1645
|
+
const result = buildSync({
|
|
1646
|
+
entryPoints: [resolvedInput],
|
|
1647
|
+
bundle: true,
|
|
1648
|
+
platform: "node",
|
|
1649
|
+
target,
|
|
1650
|
+
format: cjs ? "cjs" : "esm",
|
|
1651
|
+
minify,
|
|
1652
|
+
write: false,
|
|
1653
|
+
external: [],
|
|
1654
|
+
// Bundle everything
|
|
1655
|
+
banner: {
|
|
1656
|
+
js: "#!/usr/bin/env node"
|
|
1657
|
+
}
|
|
1658
|
+
});
|
|
1659
|
+
if (result.errors.length > 0) {
|
|
1660
|
+
const errorMessages = result.errors.map((e) => e.text);
|
|
1661
|
+
throw new ZapierBundleError(
|
|
1662
|
+
`Bundle failed: ${errorMessages.join(", ")}`,
|
|
1663
|
+
errorMessages
|
|
1664
|
+
);
|
|
1665
|
+
}
|
|
1666
|
+
const bundledCode = result.outputFiles?.[0]?.text;
|
|
1667
|
+
if (!bundledCode) {
|
|
1668
|
+
throw new ZapierBundleError("No output generated");
|
|
1669
|
+
}
|
|
1670
|
+
let finalOutput = bundledCode;
|
|
1671
|
+
if (returnString) {
|
|
1672
|
+
finalOutput = JSON.stringify(bundledCode);
|
|
1673
|
+
}
|
|
1674
|
+
if (output) {
|
|
1675
|
+
fs2.mkdirSync(path2.dirname(output), { recursive: true });
|
|
1676
|
+
fs2.writeFileSync(output, finalOutput, "utf8");
|
|
1677
|
+
}
|
|
1678
|
+
return finalOutput;
|
|
1679
|
+
} catch (error) {
|
|
1680
|
+
if (error instanceof ZapierBundleError) {
|
|
1681
|
+
throw error;
|
|
1682
|
+
}
|
|
1683
|
+
throw new ZapierBundleError(
|
|
1684
|
+
`Bundle failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
1685
|
+
void 0,
|
|
1686
|
+
error instanceof Error ? error : void 0
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
// src/commands/bundle-code/cli.ts
|
|
1692
|
+
import chalk6 from "chalk";
|
|
1693
|
+
function createBundleCodeCommand() {
|
|
1694
|
+
const parameters = analyzeZodSchema2(BundleCodeSchema);
|
|
1695
|
+
const description = BundleCodeSchema.description || "Bundle TypeScript code into executable JavaScript";
|
|
1696
|
+
const command = new Command5("bundle-code").description(description);
|
|
1697
|
+
parameters.forEach((param) => {
|
|
1698
|
+
const kebabName = param.name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
1699
|
+
if (param.hasResolver && param.required) {
|
|
1700
|
+
command.argument(
|
|
1701
|
+
`[${kebabName}]`,
|
|
1702
|
+
param.description || `${kebabName} parameter`
|
|
1703
|
+
);
|
|
1704
|
+
} else if (param.required) {
|
|
1705
|
+
command.argument(
|
|
1706
|
+
`<${kebabName}>`,
|
|
1707
|
+
param.description || `${kebabName} parameter`
|
|
1708
|
+
);
|
|
1709
|
+
} else if (param.isPositional) {
|
|
1710
|
+
command.argument(
|
|
1711
|
+
`[${kebabName}]`,
|
|
1712
|
+
param.description || `${kebabName} parameter`
|
|
1713
|
+
);
|
|
1714
|
+
} else {
|
|
1715
|
+
const flags = [`--${kebabName}`];
|
|
1716
|
+
if (param.type === "boolean") {
|
|
1717
|
+
command.option(flags.join(", "), param.description);
|
|
1718
|
+
} else {
|
|
1719
|
+
const flagSignature = flags.join(", ") + ` <${param.type}>`;
|
|
1720
|
+
command.option(flagSignature, param.description, param.default);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1093
1723
|
});
|
|
1724
|
+
command.option("--json", "Output raw JSON instead of formatted results");
|
|
1725
|
+
command.action(async (...args) => {
|
|
1726
|
+
try {
|
|
1727
|
+
const commandObj = args[args.length - 1];
|
|
1728
|
+
const options = commandObj.opts();
|
|
1729
|
+
const rawParams = convertCliArgsToSdkParams2(
|
|
1730
|
+
parameters,
|
|
1731
|
+
args.slice(0, -1),
|
|
1732
|
+
options
|
|
1733
|
+
);
|
|
1734
|
+
if (!rawParams.input) {
|
|
1735
|
+
throw new Error("Input file path is required");
|
|
1736
|
+
}
|
|
1737
|
+
console.log(chalk6.blue(`\u{1F4E6} Bundling ${rawParams.input}...`));
|
|
1738
|
+
const result = await bundleCode(rawParams);
|
|
1739
|
+
if (options.json) {
|
|
1740
|
+
console.log(JSON.stringify({ result }, null, 2));
|
|
1741
|
+
} else if (rawParams.output && !rawParams.string) {
|
|
1742
|
+
console.log(chalk6.green("\u2705 Bundle created successfully!"));
|
|
1743
|
+
console.log(chalk6.gray(`Output written to: ${rawParams.output}`));
|
|
1744
|
+
} else if (rawParams.string) {
|
|
1745
|
+
console.log(chalk6.green("\u2705 Bundle generated as string!"));
|
|
1746
|
+
console.log("\n" + result);
|
|
1747
|
+
} else {
|
|
1748
|
+
console.log(chalk6.green("\u2705 Bundle completed!"));
|
|
1749
|
+
console.log("\n" + result);
|
|
1750
|
+
}
|
|
1751
|
+
} catch (error) {
|
|
1752
|
+
console.error(
|
|
1753
|
+
chalk6.red("Error:"),
|
|
1754
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
1755
|
+
);
|
|
1756
|
+
process.exit(1);
|
|
1757
|
+
}
|
|
1758
|
+
});
|
|
1759
|
+
return command;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
// src/commands/mcp.ts
|
|
1763
|
+
import { Command as Command6 } from "commander";
|
|
1764
|
+
import { startMcpServerAsProcess } from "@zapier/zapier-sdk-mcp";
|
|
1765
|
+
function createMcpCommand() {
|
|
1766
|
+
const command = new Command6("mcp");
|
|
1767
|
+
command.description("Start MCP server for Zapier SDK").option("--debug", "Enable debug logging").option("--port <port>", "Port to listen on (for future HTTP transport)").action(startMcpServerAsProcess);
|
|
1768
|
+
return command;
|
|
1094
1769
|
}
|
|
1095
1770
|
|
|
1096
1771
|
// src/cli.ts
|
|
1097
|
-
var program = new
|
|
1772
|
+
var program = new Command7();
|
|
1098
1773
|
program.name("zapier-sdk").description("CLI for Zapier SDK - Commands auto-generated from SDK schemas").version("1.0.0").option("--debug", "Enable debug logging");
|
|
1099
1774
|
var isDebugMode = process.env.DEBUG === "true" || process.argv.includes("--debug");
|
|
1100
|
-
var sdk =
|
|
1775
|
+
var sdk = createZapierSdk2({
|
|
1101
1776
|
debug: isDebugMode
|
|
1102
1777
|
});
|
|
1103
1778
|
program.addCommand(createLoginCommand());
|
|
1104
1779
|
program.addCommand(createLogoutCommand());
|
|
1105
|
-
program.addCommand(createWhoamiCommand());
|
|
1106
|
-
program.addCommand(createConfigPathCommand());
|
|
1107
1780
|
generateCliCommands(program, sdk);
|
|
1781
|
+
program.addCommand(createGenerateTypesCommand());
|
|
1782
|
+
program.addCommand(createBundleCodeCommand());
|
|
1783
|
+
program.addCommand(createConfigPathCommand());
|
|
1784
|
+
program.addCommand(createMcpCommand());
|
|
1108
1785
|
program.parse();
|