@zapier/zapier-sdk-cli 0.35.1 → 0.36.1
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 +21 -0
- package/README.md +232 -0
- package/dist/cli.cjs +337 -168
- package/dist/cli.mjs +335 -167
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/package.json +7 -1
- package/dist/src/utils/cli-generator.js +46 -12
- package/dist/src/utils/parameter-resolver.d.ts +11 -0
- package/dist/src/utils/parameter-resolver.js +262 -157
- package/dist/src/utils/schema-formatter.d.ts +6 -1
- package/dist/src/utils/schema-formatter.js +45 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -4
package/dist/cli.cjs
CHANGED
|
@@ -6,13 +6,14 @@ var zod = require('zod');
|
|
|
6
6
|
var zapierSdk = require('@zapier/zapier-sdk');
|
|
7
7
|
var inquirer = require('inquirer');
|
|
8
8
|
var chalk7 = require('chalk');
|
|
9
|
+
var ora = require('ora');
|
|
9
10
|
var util = require('util');
|
|
11
|
+
var wrapAnsi = require('wrap-ansi');
|
|
10
12
|
var cliLogin = require('@zapier/zapier-sdk-cli-login');
|
|
11
13
|
var open = require('open');
|
|
12
14
|
var crypto = require('crypto');
|
|
13
15
|
var express = require('express');
|
|
14
16
|
var pkceChallenge = require('pkce-challenge');
|
|
15
|
-
var ora = require('ora');
|
|
16
17
|
var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
|
|
17
18
|
var esbuild = require('esbuild');
|
|
18
19
|
var fs = require('fs');
|
|
@@ -49,13 +50,14 @@ function _interopNamespace(e) {
|
|
|
49
50
|
|
|
50
51
|
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
51
52
|
var chalk7__default = /*#__PURE__*/_interopDefault(chalk7);
|
|
53
|
+
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
52
54
|
var util__default = /*#__PURE__*/_interopDefault(util);
|
|
55
|
+
var wrapAnsi__default = /*#__PURE__*/_interopDefault(wrapAnsi);
|
|
53
56
|
var cliLogin__namespace = /*#__PURE__*/_interopNamespace(cliLogin);
|
|
54
57
|
var open__default = /*#__PURE__*/_interopDefault(open);
|
|
55
58
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
56
59
|
var express__default = /*#__PURE__*/_interopDefault(express);
|
|
57
60
|
var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
|
|
58
|
-
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
59
61
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
60
62
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
61
63
|
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
@@ -143,9 +145,31 @@ function getLocalResolutionOrderForParams(paramNames, resolvers) {
|
|
|
143
145
|
return order;
|
|
144
146
|
}
|
|
145
147
|
var SchemaParameterResolver = class {
|
|
148
|
+
constructor() {
|
|
149
|
+
this.debug = false;
|
|
150
|
+
this.spinner = null;
|
|
151
|
+
}
|
|
152
|
+
debugLog(message) {
|
|
153
|
+
if (this.debug) {
|
|
154
|
+
this.stopSpinner();
|
|
155
|
+
console.log(chalk7__default.default.gray(`[Zapier CLI] ${message}`));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
startSpinner() {
|
|
159
|
+
if (!this.debug && !this.spinner) {
|
|
160
|
+
this.spinner = ora__default.default({ text: "", spinner: "dots" }).start();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
stopSpinner() {
|
|
164
|
+
if (this.spinner) {
|
|
165
|
+
this.spinner.stop();
|
|
166
|
+
this.spinner = null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
146
169
|
async resolveParameters(schema, providedParams, sdk2, functionName, options) {
|
|
147
170
|
return zapierSdk.runWithTelemetryContext(async () => {
|
|
148
|
-
|
|
171
|
+
this.debug = options?.debug ?? false;
|
|
172
|
+
const interactiveMode = (options?.interactiveMode ?? true) && !!process.stdin.isTTY;
|
|
149
173
|
const parseResult = schema.safeParse(providedParams);
|
|
150
174
|
const allParams = this.extractParametersFromSchema(schema);
|
|
151
175
|
const resolvableParams = allParams.filter(
|
|
@@ -155,27 +179,18 @@ var SchemaParameterResolver = class {
|
|
|
155
179
|
const hasValue = this.getNestedValue(providedParams, param.path) !== void 0;
|
|
156
180
|
return !hasValue;
|
|
157
181
|
});
|
|
158
|
-
const
|
|
182
|
+
const required = missingResolvable.filter((param) => {
|
|
159
183
|
if (param.isRequired) return true;
|
|
160
|
-
if (param.name === "inputs")
|
|
161
|
-
return interactiveMode;
|
|
162
|
-
}
|
|
184
|
+
if (param.name === "inputs") return interactiveMode;
|
|
163
185
|
return false;
|
|
164
186
|
});
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
if (param.name === "connectionId") {
|
|
168
|
-
return true;
|
|
169
|
-
}
|
|
170
|
-
return false;
|
|
171
|
-
});
|
|
172
|
-
const trulyOptional = missingResolvable.filter(
|
|
173
|
-
(param) => !functionallyRequired.includes(param) && !alwaysPrompt.includes(param)
|
|
187
|
+
const optional = missingResolvable.filter(
|
|
188
|
+
(param) => !required.includes(param)
|
|
174
189
|
);
|
|
175
|
-
if (parseResult.success &&
|
|
190
|
+
if (parseResult.success && required.length === 0 && optional.length === 0) {
|
|
176
191
|
return parseResult.data;
|
|
177
192
|
}
|
|
178
|
-
if (
|
|
193
|
+
if (required.length === 0 && optional.length === 0) {
|
|
179
194
|
if (!parseResult.success) {
|
|
180
195
|
throw new ZapierCliValidationError(formatZodError(parseResult.error));
|
|
181
196
|
}
|
|
@@ -189,19 +204,16 @@ var SchemaParameterResolver = class {
|
|
|
189
204
|
functionName
|
|
190
205
|
};
|
|
191
206
|
const localResolvers = this.getLocalResolvers(sdk2, functionName);
|
|
192
|
-
if (
|
|
193
|
-
const requiredParamNames =
|
|
207
|
+
if (required.length > 0) {
|
|
208
|
+
const requiredParamNames = required.map((p) => p.name);
|
|
194
209
|
const requiredResolutionOrder = getLocalResolutionOrderForParams(
|
|
195
210
|
requiredParamNames,
|
|
196
211
|
localResolvers
|
|
197
212
|
);
|
|
198
213
|
const orderedRequiredParams = requiredResolutionOrder.map((paramName) => {
|
|
199
|
-
let param =
|
|
200
|
-
if (!param) {
|
|
201
|
-
param = alwaysPrompt.find((p) => p.name === paramName);
|
|
202
|
-
}
|
|
214
|
+
let param = required.find((p) => p.name === paramName);
|
|
203
215
|
if (!param) {
|
|
204
|
-
param =
|
|
216
|
+
param = optional.find((p) => p.name === paramName);
|
|
205
217
|
}
|
|
206
218
|
return param;
|
|
207
219
|
}).filter((param) => param !== void 0);
|
|
@@ -234,33 +246,31 @@ var SchemaParameterResolver = class {
|
|
|
234
246
|
const resolvedParamNames = new Set(
|
|
235
247
|
orderedRequiredParams.map((p) => p.name)
|
|
236
248
|
);
|
|
237
|
-
|
|
238
|
-
0,
|
|
239
|
-
alwaysPrompt.length,
|
|
240
|
-
...alwaysPrompt.filter((p) => !resolvedParamNames.has(p.name))
|
|
241
|
-
);
|
|
242
|
-
trulyOptional.splice(
|
|
249
|
+
optional.splice(
|
|
243
250
|
0,
|
|
244
|
-
|
|
245
|
-
...
|
|
251
|
+
optional.length,
|
|
252
|
+
...optional.filter((p) => !resolvedParamNames.has(p.name))
|
|
246
253
|
);
|
|
247
254
|
}
|
|
248
|
-
if (interactiveMode &&
|
|
249
|
-
const
|
|
250
|
-
const
|
|
251
|
-
|
|
255
|
+
if (interactiveMode && optional.length > 0) {
|
|
256
|
+
const optionalParamNames = optional.map((p) => p.name);
|
|
257
|
+
const optionalResolutionOrder = getLocalResolutionOrderForParams(
|
|
258
|
+
optionalParamNames,
|
|
252
259
|
localResolvers
|
|
253
260
|
);
|
|
254
|
-
const
|
|
255
|
-
for (const param of
|
|
261
|
+
const orderedOptionalParams = optionalResolutionOrder.map((paramName) => optional.find((p) => p.name === paramName)).filter((param) => param !== void 0);
|
|
262
|
+
for (const param of orderedOptionalParams) {
|
|
256
263
|
try {
|
|
257
264
|
const value = await this.resolveParameter(
|
|
258
265
|
param,
|
|
259
266
|
context,
|
|
260
|
-
functionName
|
|
267
|
+
functionName,
|
|
268
|
+
{ isOptional: true }
|
|
261
269
|
);
|
|
262
|
-
|
|
263
|
-
|
|
270
|
+
if (value !== void 0) {
|
|
271
|
+
this.setNestedValue(resolvedParams, param.path, value);
|
|
272
|
+
context.resolvedParams = resolvedParams;
|
|
273
|
+
}
|
|
264
274
|
} catch (error) {
|
|
265
275
|
if (this.isUserCancellation(error)) {
|
|
266
276
|
console.log(chalk7__default.default.yellow("\n\nOperation cancelled by user"));
|
|
@@ -270,44 +280,6 @@ var SchemaParameterResolver = class {
|
|
|
270
280
|
}
|
|
271
281
|
}
|
|
272
282
|
}
|
|
273
|
-
if (interactiveMode && trulyOptional.length > 0) {
|
|
274
|
-
const optionalNames = trulyOptional.map((p) => p.name).join(", ");
|
|
275
|
-
const shouldResolveOptional = await inquirer__default.default.prompt([
|
|
276
|
-
{
|
|
277
|
-
type: "confirm",
|
|
278
|
-
name: "resolveOptional",
|
|
279
|
-
message: `Would you like to be prompted for optional parameters (${optionalNames})?`,
|
|
280
|
-
default: false
|
|
281
|
-
}
|
|
282
|
-
]);
|
|
283
|
-
if (shouldResolveOptional.resolveOptional) {
|
|
284
|
-
const optionalParamNames = trulyOptional.map((p) => p.name);
|
|
285
|
-
const optionalResolutionOrder = getLocalResolutionOrderForParams(
|
|
286
|
-
optionalParamNames,
|
|
287
|
-
localResolvers
|
|
288
|
-
);
|
|
289
|
-
const orderedOptionalParams = optionalResolutionOrder.map((paramName) => trulyOptional.find((p) => p.name === paramName)).filter(
|
|
290
|
-
(param) => param !== void 0
|
|
291
|
-
);
|
|
292
|
-
for (const param of orderedOptionalParams) {
|
|
293
|
-
try {
|
|
294
|
-
const value = await this.resolveParameter(
|
|
295
|
-
param,
|
|
296
|
-
context,
|
|
297
|
-
functionName
|
|
298
|
-
);
|
|
299
|
-
this.setNestedValue(resolvedParams, param.path, value);
|
|
300
|
-
context.resolvedParams = resolvedParams;
|
|
301
|
-
} catch (error) {
|
|
302
|
-
if (this.isUserCancellation(error)) {
|
|
303
|
-
console.log(chalk7__default.default.yellow("\n\nOperation cancelled by user"));
|
|
304
|
-
throw new ZapierCliUserCancellationError();
|
|
305
|
-
}
|
|
306
|
-
throw error;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
283
|
const finalResult = schema.safeParse(resolvedParams);
|
|
312
284
|
if (!finalResult.success) {
|
|
313
285
|
throw new ZapierCliValidationError(
|
|
@@ -402,7 +374,7 @@ var SchemaParameterResolver = class {
|
|
|
402
374
|
throw new ZapierCliMissingParametersError(missingParams);
|
|
403
375
|
}
|
|
404
376
|
}
|
|
405
|
-
async resolveParameter(param, context, functionName) {
|
|
377
|
+
async resolveParameter(param, context, functionName, options) {
|
|
406
378
|
const resolver = this.getResolver(
|
|
407
379
|
param.name,
|
|
408
380
|
context.sdk,
|
|
@@ -411,53 +383,102 @@ var SchemaParameterResolver = class {
|
|
|
411
383
|
if (!resolver) {
|
|
412
384
|
throw new Error(`No resolver found for parameter: ${param.name}`);
|
|
413
385
|
}
|
|
414
|
-
|
|
415
|
-
|
|
386
|
+
return this.resolveWithResolver(resolver, param, context, {
|
|
387
|
+
isOptional: options?.isOptional
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
async resolveWithResolver(resolver, param, context, options = {}) {
|
|
391
|
+
const { arrayIndex, isOptional } = options;
|
|
392
|
+
const inArrayContext = arrayIndex != null;
|
|
393
|
+
const promptLabel = inArrayContext ? `${param.name}[${arrayIndex}]` : param.name;
|
|
394
|
+
const promptName = inArrayContext ? "value" : param.name;
|
|
395
|
+
this.debugLog(`Resolving ${promptLabel}${isOptional ? " (optional)" : ""}`);
|
|
416
396
|
if (resolver.type === "static") {
|
|
417
397
|
const staticResolver = resolver;
|
|
418
398
|
const promptConfig = {
|
|
419
399
|
type: staticResolver.inputType === "password" ? "password" : "input",
|
|
420
|
-
name:
|
|
421
|
-
message: `Enter ${
|
|
400
|
+
name: promptName,
|
|
401
|
+
message: `Enter ${promptLabel}${isOptional ? " (optional)" : ""}:`,
|
|
422
402
|
...staticResolver.placeholder && {
|
|
423
403
|
default: staticResolver.placeholder
|
|
424
404
|
}
|
|
425
405
|
};
|
|
406
|
+
this.stopSpinner();
|
|
426
407
|
const answers = await inquirer__default.default.prompt([promptConfig]);
|
|
427
|
-
|
|
408
|
+
const value = answers[promptName];
|
|
409
|
+
if (isOptional && (value === void 0 || value === "")) {
|
|
410
|
+
return void 0;
|
|
411
|
+
}
|
|
412
|
+
return value;
|
|
428
413
|
} else if (resolver.type === "dynamic") {
|
|
429
414
|
const dynamicResolver = resolver;
|
|
415
|
+
this.startSpinner();
|
|
430
416
|
const autoResolution = await this.tryAutoResolve(
|
|
431
417
|
dynamicResolver,
|
|
432
418
|
context
|
|
433
419
|
);
|
|
434
420
|
if (autoResolution != null) {
|
|
421
|
+
this.stopSpinner();
|
|
435
422
|
return autoResolution.resolvedValue;
|
|
436
423
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
const items = await dynamicResolver.fetch(
|
|
424
|
+
this.debugLog(`Fetching options for ${promptLabel}`);
|
|
425
|
+
const fetchResult = await dynamicResolver.fetch(
|
|
441
426
|
context.sdk,
|
|
442
427
|
context.resolvedParams
|
|
443
428
|
);
|
|
444
|
-
const
|
|
429
|
+
const items = Array.isArray(fetchResult) ? fetchResult : fetchResult?.data ?? [];
|
|
445
430
|
const promptConfig = dynamicResolver.prompt(
|
|
446
|
-
|
|
431
|
+
items,
|
|
447
432
|
context.resolvedParams
|
|
448
433
|
);
|
|
434
|
+
promptConfig.name = promptName;
|
|
435
|
+
this.stopSpinner();
|
|
436
|
+
if (isOptional && promptConfig.choices) {
|
|
437
|
+
const SKIP_SENTINEL = Symbol("SKIP");
|
|
438
|
+
promptConfig.choices = [
|
|
439
|
+
{ name: chalk7__default.default.dim("(Skip)"), value: SKIP_SENTINEL },
|
|
440
|
+
...promptConfig.choices
|
|
441
|
+
];
|
|
442
|
+
const answers2 = await inquirer__default.default.prompt([promptConfig]);
|
|
443
|
+
const value = answers2[promptName];
|
|
444
|
+
if (value === SKIP_SENTINEL) {
|
|
445
|
+
return void 0;
|
|
446
|
+
}
|
|
447
|
+
return value;
|
|
448
|
+
}
|
|
449
449
|
const answers = await inquirer__default.default.prompt([promptConfig]);
|
|
450
|
-
return answers[
|
|
450
|
+
return answers[promptName];
|
|
451
451
|
} else if (resolver.type === "fields") {
|
|
452
|
+
if (isOptional && !inArrayContext) {
|
|
453
|
+
this.stopSpinner();
|
|
454
|
+
const { confirm } = await inquirer__default.default.prompt([
|
|
455
|
+
{
|
|
456
|
+
type: "confirm",
|
|
457
|
+
name: "confirm",
|
|
458
|
+
message: `Add ${promptLabel}?`,
|
|
459
|
+
default: false
|
|
460
|
+
}
|
|
461
|
+
]);
|
|
462
|
+
if (!confirm) {
|
|
463
|
+
return void 0;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
452
466
|
return await this.resolveFieldsRecursively(
|
|
467
|
+
resolver,
|
|
468
|
+
context,
|
|
469
|
+
param,
|
|
470
|
+
{ inArrayContext }
|
|
471
|
+
);
|
|
472
|
+
} else if (resolver.type === "array") {
|
|
473
|
+
return await this.resolveArrayRecursively(
|
|
453
474
|
resolver,
|
|
454
475
|
context,
|
|
455
476
|
param
|
|
456
477
|
);
|
|
457
478
|
}
|
|
458
|
-
throw new Error(`Unknown resolver type for ${
|
|
479
|
+
throw new Error(`Unknown resolver type for ${promptLabel}`);
|
|
459
480
|
}
|
|
460
|
-
async resolveFieldsRecursively(resolver, context, param) {
|
|
481
|
+
async resolveFieldsRecursively(resolver, context, param, options = {}) {
|
|
461
482
|
const inputs = {};
|
|
462
483
|
let processedFieldKeys = /* @__PURE__ */ new Set();
|
|
463
484
|
let iteration = 0;
|
|
@@ -471,15 +492,15 @@ var SchemaParameterResolver = class {
|
|
|
471
492
|
inputs
|
|
472
493
|
}
|
|
473
494
|
};
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
`Fetching input fields for ${param.name}${iteration > 1 ? ` (iteration ${iteration})` : ""}...`
|
|
477
|
-
)
|
|
495
|
+
this.debugLog(
|
|
496
|
+
`Fetching input fields for ${param.name}${iteration > 1 ? ` (iteration ${iteration})` : ""}`
|
|
478
497
|
);
|
|
498
|
+
this.startSpinner();
|
|
479
499
|
const rootFieldItems = await resolver.fetch(
|
|
480
500
|
updatedContext.sdk,
|
|
481
501
|
updatedContext.resolvedParams
|
|
482
502
|
);
|
|
503
|
+
this.stopSpinner();
|
|
483
504
|
if (!rootFieldItems || rootFieldItems.length === 0) {
|
|
484
505
|
if (iteration === 1) {
|
|
485
506
|
console.log(
|
|
@@ -494,7 +515,8 @@ var SchemaParameterResolver = class {
|
|
|
494
515
|
processedFieldKeys,
|
|
495
516
|
[],
|
|
496
517
|
iteration,
|
|
497
|
-
updatedContext
|
|
518
|
+
updatedContext,
|
|
519
|
+
{ inArrayContext: options.inArrayContext }
|
|
498
520
|
);
|
|
499
521
|
if (fieldStats.newRequired === 0 && fieldStats.newOptional === 0) {
|
|
500
522
|
break;
|
|
@@ -511,13 +533,60 @@ var SchemaParameterResolver = class {
|
|
|
511
533
|
)
|
|
512
534
|
);
|
|
513
535
|
}
|
|
536
|
+
if (resolver.transform) {
|
|
537
|
+
return resolver.transform(inputs);
|
|
538
|
+
}
|
|
514
539
|
return inputs;
|
|
515
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Resolves an array parameter by repeatedly prompting for items until user says no
|
|
543
|
+
*/
|
|
544
|
+
async resolveArrayRecursively(resolver, context, param) {
|
|
545
|
+
const items = [];
|
|
546
|
+
const minItems = resolver.minItems ?? 0;
|
|
547
|
+
const maxItems = resolver.maxItems ?? Infinity;
|
|
548
|
+
while (items.length < maxItems) {
|
|
549
|
+
const currentIndex = items.length;
|
|
550
|
+
if (currentIndex >= minItems) {
|
|
551
|
+
this.stopSpinner();
|
|
552
|
+
const confirmAnswer = await inquirer__default.default.prompt([
|
|
553
|
+
{
|
|
554
|
+
type: "confirm",
|
|
555
|
+
name: "addItem",
|
|
556
|
+
message: `Add ${param.name}[${currentIndex}]?`,
|
|
557
|
+
default: false
|
|
558
|
+
}
|
|
559
|
+
]);
|
|
560
|
+
if (!confirmAnswer.addItem) {
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
const innerResolver = await resolver.fetch(
|
|
565
|
+
context.sdk,
|
|
566
|
+
context.resolvedParams
|
|
567
|
+
);
|
|
568
|
+
const itemValue = await this.resolveWithResolver(
|
|
569
|
+
innerResolver,
|
|
570
|
+
param,
|
|
571
|
+
context,
|
|
572
|
+
{ arrayIndex: currentIndex }
|
|
573
|
+
);
|
|
574
|
+
items.push(itemValue);
|
|
575
|
+
context.resolvedParams = {
|
|
576
|
+
...context.resolvedParams,
|
|
577
|
+
[param.name]: items
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
if (items.length >= maxItems) {
|
|
581
|
+
console.log(chalk7__default.default.gray(`Maximum of ${maxItems} items reached.`));
|
|
582
|
+
}
|
|
583
|
+
return items;
|
|
584
|
+
}
|
|
516
585
|
/**
|
|
517
586
|
* Recursively processes fieldsets and their fields, maintaining natural structure
|
|
518
587
|
* and creating nested inputs as needed (e.g., fieldset "foo" becomes inputs.foo = [{}])
|
|
519
588
|
*/
|
|
520
|
-
async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1, context) {
|
|
589
|
+
async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1, context, options = {}) {
|
|
521
590
|
let newRequiredCount = 0;
|
|
522
591
|
let newOptionalCount = 0;
|
|
523
592
|
let optionalSkipped = false;
|
|
@@ -543,7 +612,8 @@ var SchemaParameterResolver = class {
|
|
|
543
612
|
processedFieldKeys,
|
|
544
613
|
nestedPath,
|
|
545
614
|
iteration,
|
|
546
|
-
context
|
|
615
|
+
context,
|
|
616
|
+
options
|
|
547
617
|
);
|
|
548
618
|
newRequiredCount += nestedStats.newRequired;
|
|
549
619
|
newOptionalCount += nestedStats.newOptional;
|
|
@@ -557,15 +627,22 @@ var SchemaParameterResolver = class {
|
|
|
557
627
|
const isRequired = typedItem.is_required || false;
|
|
558
628
|
if (isRequired) {
|
|
559
629
|
newRequiredCount++;
|
|
560
|
-
if (
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
630
|
+
if (typedItem.resolver && context) {
|
|
631
|
+
const param = {
|
|
632
|
+
name: typedItem.key,
|
|
633
|
+
path: [typedItem.key],
|
|
634
|
+
schema: zod.z.unknown(),
|
|
635
|
+
isRequired: true
|
|
636
|
+
};
|
|
637
|
+
targetInputs[typedItem.key] = await this.resolveWithResolver(
|
|
638
|
+
typedItem.resolver,
|
|
639
|
+
param,
|
|
640
|
+
context,
|
|
641
|
+
{ isOptional: false }
|
|
566
642
|
);
|
|
643
|
+
} else {
|
|
644
|
+
await this.promptForField(typedItem, targetInputs, context);
|
|
567
645
|
}
|
|
568
|
-
await this.promptForField(typedItem, targetInputs, context);
|
|
569
646
|
processedFieldKeys.add(typedItem.key);
|
|
570
647
|
} else {
|
|
571
648
|
newOptionalCount++;
|
|
@@ -579,42 +656,50 @@ var SchemaParameterResolver = class {
|
|
|
579
656
|
});
|
|
580
657
|
if (optionalFields.length > 0) {
|
|
581
658
|
const pathContext = fieldsetPath.length > 0 ? ` in ${fieldsetPath.join(" > ")}` : "";
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
659
|
+
if (options.inArrayContext) {
|
|
660
|
+
for (const field of optionalFields) {
|
|
661
|
+
await this.promptForField(field, targetInputs, context);
|
|
662
|
+
const typedField = field;
|
|
663
|
+
processedFieldKeys.add(typedField.key);
|
|
664
|
+
}
|
|
665
|
+
} else {
|
|
666
|
+
console.log(
|
|
667
|
+
chalk7__default.default.gray(
|
|
668
|
+
`
|
|
585
669
|
There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}optional field(s) available${pathContext}.`
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
670
|
+
)
|
|
671
|
+
);
|
|
672
|
+
try {
|
|
673
|
+
const shouldConfigureOptional = await inquirer__default.default.prompt([
|
|
674
|
+
{
|
|
675
|
+
type: "confirm",
|
|
676
|
+
name: "configure",
|
|
677
|
+
message: `Would you like to configure ${iteration === 1 ? "" : "these additional "}optional fields${pathContext}?`,
|
|
678
|
+
default: false
|
|
679
|
+
}
|
|
680
|
+
]);
|
|
681
|
+
if (shouldConfigureOptional.configure) {
|
|
682
|
+
console.log(chalk7__default.default.cyan(`
|
|
599
683
|
Optional fields${pathContext}:`));
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
684
|
+
for (const field of optionalFields) {
|
|
685
|
+
await this.promptForField(field, targetInputs, context);
|
|
686
|
+
const typedField = field;
|
|
687
|
+
processedFieldKeys.add(typedField.key);
|
|
688
|
+
}
|
|
689
|
+
} else {
|
|
690
|
+
optionalSkipped = true;
|
|
691
|
+
optionalFields.forEach((field) => {
|
|
692
|
+
const typedField = field;
|
|
693
|
+
processedFieldKeys.add(typedField.key);
|
|
694
|
+
});
|
|
604
695
|
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
}
|
|
612
|
-
} catch (error) {
|
|
613
|
-
if (this.isUserCancellation(error)) {
|
|
614
|
-
console.log(chalk7__default.default.yellow("\n\nOperation cancelled by user"));
|
|
615
|
-
throw new ZapierCliUserCancellationError();
|
|
696
|
+
} catch (error) {
|
|
697
|
+
if (this.isUserCancellation(error)) {
|
|
698
|
+
console.log(chalk7__default.default.yellow("\n\nOperation cancelled by user"));
|
|
699
|
+
throw new ZapierCliUserCancellationError();
|
|
700
|
+
}
|
|
701
|
+
throw error;
|
|
616
702
|
}
|
|
617
|
-
throw error;
|
|
618
703
|
}
|
|
619
704
|
}
|
|
620
705
|
}
|
|
@@ -654,10 +739,11 @@ Optional fields${pathContext}:`));
|
|
|
654
739
|
isRequired: fieldObj.is_required || false,
|
|
655
740
|
defaultValue: fieldObj.default_value ?? fieldObj.default,
|
|
656
741
|
valueType,
|
|
657
|
-
hasDropdown: fieldObj.format === "SELECT",
|
|
742
|
+
hasDropdown: fieldObj.format === "SELECT" || Boolean(fieldObj.choices),
|
|
658
743
|
isMultiSelect: Boolean(
|
|
659
744
|
valueType === "array" || fieldObj.items && fieldObj.items.type !== void 0
|
|
660
|
-
)
|
|
745
|
+
),
|
|
746
|
+
inlineChoices: fieldObj.choices
|
|
661
747
|
};
|
|
662
748
|
}
|
|
663
749
|
/**
|
|
@@ -665,11 +751,10 @@ Optional fields${pathContext}:`));
|
|
|
665
751
|
*/
|
|
666
752
|
async fetchChoices(fieldMeta, inputs, context, cursor) {
|
|
667
753
|
try {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
cursor ? ` Fetching more choices...` : ` Fetching choices for ${fieldMeta.title}...`
|
|
671
|
-
)
|
|
754
|
+
this.debugLog(
|
|
755
|
+
cursor ? `Fetching more choices for ${fieldMeta.title}` : `Fetching choices for ${fieldMeta.title}`
|
|
672
756
|
);
|
|
757
|
+
this.startSpinner();
|
|
673
758
|
const page = await context.sdk.listInputFieldChoices({
|
|
674
759
|
appKey: context.resolvedParams.appKey,
|
|
675
760
|
actionKey: context.resolvedParams.actionKey,
|
|
@@ -679,13 +764,14 @@ Optional fields${pathContext}:`));
|
|
|
679
764
|
inputs,
|
|
680
765
|
...cursor && { cursor }
|
|
681
766
|
});
|
|
767
|
+
this.stopSpinner();
|
|
682
768
|
const choices = page.data.map((choice) => ({
|
|
683
769
|
label: choice.label || choice.key || String(choice.value),
|
|
684
770
|
value: choice.value ?? choice.key
|
|
685
771
|
}));
|
|
686
772
|
if (choices.length === 0 && !cursor) {
|
|
687
773
|
console.log(
|
|
688
|
-
chalk7__default.default.yellow(`
|
|
774
|
+
chalk7__default.default.yellow(`No choices available for ${fieldMeta.title}`)
|
|
689
775
|
);
|
|
690
776
|
}
|
|
691
777
|
return {
|
|
@@ -693,8 +779,9 @@ Optional fields${pathContext}:`));
|
|
|
693
779
|
nextCursor: page.nextCursor
|
|
694
780
|
};
|
|
695
781
|
} catch (error) {
|
|
782
|
+
this.stopSpinner();
|
|
696
783
|
console.warn(
|
|
697
|
-
chalk7__default.default.yellow(`
|
|
784
|
+
chalk7__default.default.yellow(`Failed to fetch choices for ${fieldMeta.title}:`),
|
|
698
785
|
error
|
|
699
786
|
);
|
|
700
787
|
return { choices: [] };
|
|
@@ -710,6 +797,7 @@ Optional fields${pathContext}:`));
|
|
|
710
797
|
inputs,
|
|
711
798
|
context
|
|
712
799
|
}) {
|
|
800
|
+
this.stopSpinner();
|
|
713
801
|
const choices = [...initialChoices];
|
|
714
802
|
let nextCursor = initialCursor;
|
|
715
803
|
const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
|
|
@@ -772,6 +860,27 @@ Optional fields${pathContext}:`));
|
|
|
772
860
|
if (fieldMeta.valueType === "boolean") {
|
|
773
861
|
promptConfig.type = "confirm";
|
|
774
862
|
promptConfig.default = fieldMeta.defaultValue !== void 0 ? Boolean(fieldMeta.defaultValue) : void 0;
|
|
863
|
+
} else if (fieldMeta.valueType === "array") {
|
|
864
|
+
promptConfig.type = "input";
|
|
865
|
+
promptConfig.default = fieldMeta.defaultValue;
|
|
866
|
+
promptConfig.message = `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"} (JSON array or comma-separated):`;
|
|
867
|
+
promptConfig.validate = (input) => {
|
|
868
|
+
if (fieldMeta.isRequired && !input) {
|
|
869
|
+
return "This field is required";
|
|
870
|
+
}
|
|
871
|
+
return true;
|
|
872
|
+
};
|
|
873
|
+
promptConfig.filter = (input) => {
|
|
874
|
+
if (!input) return input;
|
|
875
|
+
const trimmed = input.trim();
|
|
876
|
+
if (trimmed.startsWith("[")) {
|
|
877
|
+
try {
|
|
878
|
+
return JSON.parse(trimmed);
|
|
879
|
+
} catch {
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
return trimmed.split(",").map((s) => s.trim());
|
|
883
|
+
};
|
|
775
884
|
} else {
|
|
776
885
|
promptConfig.type = "input";
|
|
777
886
|
promptConfig.default = fieldMeta.defaultValue;
|
|
@@ -819,7 +928,9 @@ Optional fields${pathContext}:`));
|
|
|
819
928
|
const fieldMeta = this.extractFieldMetadata(field);
|
|
820
929
|
let choices = [];
|
|
821
930
|
let nextCursor;
|
|
822
|
-
if (fieldMeta.
|
|
931
|
+
if (fieldMeta.inlineChoices) {
|
|
932
|
+
choices = fieldMeta.inlineChoices;
|
|
933
|
+
} else if (fieldMeta.hasDropdown && context) {
|
|
823
934
|
const result = await this.fetchChoices(fieldMeta, inputs, context);
|
|
824
935
|
choices = result.choices;
|
|
825
936
|
nextCursor = result.nextCursor;
|
|
@@ -913,7 +1024,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
|
|
|
913
1024
|
|
|
914
1025
|
// package.json
|
|
915
1026
|
var package_default = {
|
|
916
|
-
version: "0.
|
|
1027
|
+
version: "0.36.1"};
|
|
917
1028
|
|
|
918
1029
|
// src/telemetry/builders.ts
|
|
919
1030
|
function createCliBaseEvent(context = {}) {
|
|
@@ -981,7 +1092,7 @@ function formatJsonOutput(data) {
|
|
|
981
1092
|
util__default.default.inspect(data, { colors: true, depth: null, breakLength: 80 })
|
|
982
1093
|
);
|
|
983
1094
|
}
|
|
984
|
-
function formatItemsFromSchema(functionInfo, items, startingNumber = 0) {
|
|
1095
|
+
async function formatItemsFromSchema(functionInfo, items, startingNumber = 0, options) {
|
|
985
1096
|
const outputSchema = functionInfo.outputSchema || getOutputSchema(functionInfo.inputSchema);
|
|
986
1097
|
if (!outputSchema) {
|
|
987
1098
|
formatItemsGeneric(items, startingNumber);
|
|
@@ -1022,11 +1133,39 @@ function formatSingleItem(formatted, itemNumber) {
|
|
|
1022
1133
|
return;
|
|
1023
1134
|
}
|
|
1024
1135
|
for (const detail of formatted.details) {
|
|
1025
|
-
|
|
1026
|
-
|
|
1136
|
+
if (detail.label) {
|
|
1137
|
+
const isMultiline = detail.text.includes("\n");
|
|
1138
|
+
if (isMultiline) {
|
|
1139
|
+
console.log(` ${chalk7__default.default.gray(detail.label + ":")}`);
|
|
1140
|
+
const displayText = formatDetailText(
|
|
1141
|
+
detail.text,
|
|
1142
|
+
DETAIL_INDENT + " "
|
|
1143
|
+
);
|
|
1144
|
+
const styledText = applyStyle(displayText, detail.style);
|
|
1145
|
+
console.log(`${DETAIL_INDENT} ${styledText}`);
|
|
1146
|
+
} else {
|
|
1147
|
+
const styledValue = applyStyle(detail.text, detail.style);
|
|
1148
|
+
console.log(` ${chalk7__default.default.gray(detail.label + ":")} ${styledValue}`);
|
|
1149
|
+
}
|
|
1150
|
+
} else {
|
|
1151
|
+
const displayText = formatDetailText(detail.text, DETAIL_INDENT);
|
|
1152
|
+
const styledText = applyStyle(displayText, detail.style);
|
|
1153
|
+
console.log(` ${styledText}`);
|
|
1154
|
+
}
|
|
1027
1155
|
}
|
|
1028
1156
|
console.log();
|
|
1029
1157
|
}
|
|
1158
|
+
var DETAIL_INDENT = " ";
|
|
1159
|
+
var DETAIL_MAX_LINES = 5;
|
|
1160
|
+
function formatDetailText(text, indent = DETAIL_INDENT) {
|
|
1161
|
+
const columns = Math.max((process.stdout.columns || 80) - indent.length, 40);
|
|
1162
|
+
const wrapped = wrapAnsi__default.default(text, columns, { hard: true, trim: false });
|
|
1163
|
+
const lines = wrapped.split("\n");
|
|
1164
|
+
if (lines.length <= DETAIL_MAX_LINES) {
|
|
1165
|
+
return lines.join("\n" + indent);
|
|
1166
|
+
}
|
|
1167
|
+
return lines.slice(0, DETAIL_MAX_LINES).join("\n" + indent) + "\n" + indent + "\u2026";
|
|
1168
|
+
}
|
|
1030
1169
|
function applyStyle(value, style) {
|
|
1031
1170
|
switch (style) {
|
|
1032
1171
|
case "dim":
|
|
@@ -1373,15 +1512,16 @@ var CONFIRM_MESSAGES = {
|
|
|
1373
1512
|
messageBefore: "You are about to create a sensitive secret that will be displayed as plain text.\nOnce created, you cannot retrieve it again.",
|
|
1374
1513
|
messageAfter: "Please treat this secret like a password and store it securely!"
|
|
1375
1514
|
},
|
|
1376
|
-
delete: {
|
|
1377
|
-
messageBefore:
|
|
1378
|
-
}
|
|
1515
|
+
delete: (itemType) => ({
|
|
1516
|
+
messageBefore: `You are about to delete the ${itemType || "item"}.`
|
|
1517
|
+
})
|
|
1379
1518
|
};
|
|
1380
|
-
async function promptConfirm(confirmType) {
|
|
1519
|
+
async function promptConfirm(confirmType, itemType) {
|
|
1381
1520
|
if (!confirmType || !CONFIRM_MESSAGES[confirmType]) {
|
|
1382
1521
|
return { confirmed: true };
|
|
1383
1522
|
}
|
|
1384
|
-
const
|
|
1523
|
+
const configOrFn = CONFIRM_MESSAGES[confirmType];
|
|
1524
|
+
const { messageBefore, messageAfter } = typeof configOrFn === "function" ? configOrFn(itemType) : configOrFn;
|
|
1385
1525
|
console.log(chalk7__default.default.yellow(`
|
|
1386
1526
|
${messageBefore}
|
|
1387
1527
|
`));
|
|
@@ -1465,6 +1605,7 @@ function analyzeZodField(name, schema, functionInfo) {
|
|
|
1465
1605
|
}
|
|
1466
1606
|
}
|
|
1467
1607
|
let paramType = "string";
|
|
1608
|
+
let elementType;
|
|
1468
1609
|
let choices;
|
|
1469
1610
|
if (baseSchema instanceof zod.z.ZodString) {
|
|
1470
1611
|
paramType = "string";
|
|
@@ -1474,6 +1615,14 @@ function analyzeZodField(name, schema, functionInfo) {
|
|
|
1474
1615
|
paramType = "boolean";
|
|
1475
1616
|
} else if (baseSchema instanceof zod.z.ZodArray) {
|
|
1476
1617
|
paramType = "array";
|
|
1618
|
+
const elementSchema = baseSchema._zod.def.element;
|
|
1619
|
+
if (elementSchema instanceof zod.z.ZodObject || elementSchema instanceof zod.z.ZodRecord) {
|
|
1620
|
+
elementType = "object";
|
|
1621
|
+
} else if (elementSchema instanceof zod.z.ZodNumber) {
|
|
1622
|
+
elementType = "number";
|
|
1623
|
+
} else if (elementSchema instanceof zod.z.ZodBoolean) {
|
|
1624
|
+
elementType = "boolean";
|
|
1625
|
+
}
|
|
1477
1626
|
} else if (baseSchema instanceof zod.z.ZodEnum) {
|
|
1478
1627
|
paramType = "string";
|
|
1479
1628
|
choices = baseSchema.options;
|
|
@@ -1492,7 +1641,8 @@ function analyzeZodField(name, schema, functionInfo) {
|
|
|
1492
1641
|
default: defaultValue,
|
|
1493
1642
|
choices,
|
|
1494
1643
|
hasResolver: paramHasResolver,
|
|
1495
|
-
isPositional: zapierSdk.isPositional(schema)
|
|
1644
|
+
isPositional: zapierSdk.isPositional(schema),
|
|
1645
|
+
elementType
|
|
1496
1646
|
};
|
|
1497
1647
|
}
|
|
1498
1648
|
function analyzeInputParameters(inputParameters, functionInfo) {
|
|
@@ -1679,7 +1829,10 @@ function createCommandConfig(cliCommandName, functionInfo, sdk2) {
|
|
|
1679
1829
|
rawParams,
|
|
1680
1830
|
sdk2,
|
|
1681
1831
|
functionInfo.name,
|
|
1682
|
-
{
|
|
1832
|
+
{
|
|
1833
|
+
interactiveMode,
|
|
1834
|
+
debug: !!options2.debug || process.env.DEBUG === "true" || process.argv.includes("--debug")
|
|
1835
|
+
}
|
|
1683
1836
|
);
|
|
1684
1837
|
} else {
|
|
1685
1838
|
resolvedParams = rawParams;
|
|
@@ -1687,7 +1840,10 @@ function createCommandConfig(cliCommandName, functionInfo, sdk2) {
|
|
|
1687
1840
|
const confirm = functionInfo.confirm;
|
|
1688
1841
|
let confirmMessageAfter;
|
|
1689
1842
|
if (confirm && interactiveMode) {
|
|
1690
|
-
const confirmResult = await promptConfirm(
|
|
1843
|
+
const confirmResult = await promptConfirm(
|
|
1844
|
+
confirm,
|
|
1845
|
+
functionInfo.itemType
|
|
1846
|
+
);
|
|
1691
1847
|
if (!confirmResult.confirmed) {
|
|
1692
1848
|
console.log(chalk7__default.default.yellow("Operation cancelled."));
|
|
1693
1849
|
return;
|
|
@@ -1876,7 +2032,8 @@ function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
|
1876
2032
|
if ((param.required || param.isPositional) && argIndex < positionalArgs.length) {
|
|
1877
2033
|
sdkParams[param.name] = convertValue(
|
|
1878
2034
|
positionalArgs[argIndex],
|
|
1879
|
-
param.type
|
|
2035
|
+
param.type,
|
|
2036
|
+
param.elementType
|
|
1880
2037
|
);
|
|
1881
2038
|
argIndex++;
|
|
1882
2039
|
}
|
|
@@ -1888,12 +2045,12 @@ function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
|
1888
2045
|
if (param.type === "array" && Array.isArray(value) && value.length === 0) {
|
|
1889
2046
|
return;
|
|
1890
2047
|
}
|
|
1891
|
-
sdkParams[camelKey] = convertValue(value, param.type);
|
|
2048
|
+
sdkParams[camelKey] = convertValue(value, param.type, param.elementType);
|
|
1892
2049
|
}
|
|
1893
2050
|
});
|
|
1894
2051
|
return sdkParams;
|
|
1895
2052
|
}
|
|
1896
|
-
function convertValue(value, type) {
|
|
2053
|
+
function convertValue(value, type, elementType) {
|
|
1897
2054
|
if (value === void 0) {
|
|
1898
2055
|
return void 0;
|
|
1899
2056
|
}
|
|
@@ -1902,8 +2059,20 @@ function convertValue(value, type) {
|
|
|
1902
2059
|
return Number(value);
|
|
1903
2060
|
case "boolean":
|
|
1904
2061
|
return Boolean(value);
|
|
1905
|
-
case "array":
|
|
1906
|
-
|
|
2062
|
+
case "array": {
|
|
2063
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
2064
|
+
if (elementType !== "object") return arr;
|
|
2065
|
+
return arr.flatMap((item) => {
|
|
2066
|
+
if (typeof item === "string" && (item.startsWith("{") || item.startsWith("["))) {
|
|
2067
|
+
try {
|
|
2068
|
+
return JSON.parse(item);
|
|
2069
|
+
} catch {
|
|
2070
|
+
return item;
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
return item;
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
1907
2076
|
case "string":
|
|
1908
2077
|
return value;
|
|
1909
2078
|
case "object":
|
|
@@ -4389,7 +4558,7 @@ function createZapierCliSdk(options = {}) {
|
|
|
4389
4558
|
// package.json with { type: 'json' }
|
|
4390
4559
|
var package_default2 = {
|
|
4391
4560
|
name: "@zapier/zapier-sdk-cli",
|
|
4392
|
-
version: "0.
|
|
4561
|
+
version: "0.36.1"};
|
|
4393
4562
|
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
4394
4563
|
var CACHE_RESET_INTERVAL_MS = (() => {
|
|
4395
4564
|
const { ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS = `${ONE_DAY_MS}` } = process.env;
|