@zapier/zapier-sdk-cli 0.15.0 → 0.15.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 +15 -0
- package/dist/cli.cjs +197 -34
- package/dist/cli.mjs +197 -34
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/package.json +1 -1
- package/dist/src/plugins/buildManifest/index.js +1 -1
- package/dist/src/utils/parameter-resolver.d.ts +20 -0
- package/dist/src/utils/parameter-resolver.js +189 -29
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/plugins/buildManifest/index.test.ts +39 -15
- package/src/plugins/buildManifest/index.ts +1 -1
- package/src/utils/parameter-resolver.ts +275 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @zapier/zapier-sdk-cli
|
|
2
2
|
|
|
3
|
+
## 0.15.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- a4aee2e: Enhanced param resolver to fully resolve dynamic input fields and dynamic choices.
|
|
8
|
+
|
|
9
|
+
## 0.15.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 6657f05: Defined shape and support for configured actions in the .zapierrc manifest file
|
|
14
|
+
- Updated dependencies [6657f05]
|
|
15
|
+
- @zapier/zapier-sdk@0.15.3
|
|
16
|
+
- @zapier/zapier-sdk-mcp@0.3.27
|
|
17
|
+
|
|
3
18
|
## 0.15.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
package/dist/cli.cjs
CHANGED
|
@@ -396,7 +396,8 @@ var SchemaParameterResolver = class {
|
|
|
396
396
|
inputs,
|
|
397
397
|
processedFieldKeys,
|
|
398
398
|
[],
|
|
399
|
-
iteration
|
|
399
|
+
iteration,
|
|
400
|
+
updatedContext
|
|
400
401
|
);
|
|
401
402
|
if (fieldStats.newRequired === 0 && fieldStats.newOptional === 0) {
|
|
402
403
|
break;
|
|
@@ -419,7 +420,7 @@ var SchemaParameterResolver = class {
|
|
|
419
420
|
* Recursively processes fieldsets and their fields, maintaining natural structure
|
|
420
421
|
* and creating nested inputs as needed (e.g., fieldset "foo" becomes inputs.foo = [{}])
|
|
421
422
|
*/
|
|
422
|
-
async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1) {
|
|
423
|
+
async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1, context) {
|
|
423
424
|
let newRequiredCount = 0;
|
|
424
425
|
let newOptionalCount = 0;
|
|
425
426
|
let optionalSkipped = false;
|
|
@@ -444,7 +445,8 @@ var SchemaParameterResolver = class {
|
|
|
444
445
|
fieldsetTarget,
|
|
445
446
|
processedFieldKeys,
|
|
446
447
|
nestedPath,
|
|
447
|
-
iteration
|
|
448
|
+
iteration,
|
|
449
|
+
context
|
|
448
450
|
);
|
|
449
451
|
newRequiredCount += nestedStats.newRequired;
|
|
450
452
|
newOptionalCount += nestedStats.newOptional;
|
|
@@ -466,7 +468,7 @@ var SchemaParameterResolver = class {
|
|
|
466
468
|
)
|
|
467
469
|
);
|
|
468
470
|
}
|
|
469
|
-
await this.promptForField(typedItem, targetInputs);
|
|
471
|
+
await this.promptForField(typedItem, targetInputs, context);
|
|
470
472
|
processedFieldKeys.add(typedItem.key);
|
|
471
473
|
} else {
|
|
472
474
|
newOptionalCount++;
|
|
@@ -499,7 +501,7 @@ There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}option
|
|
|
499
501
|
console.log(chalk3__default.default.cyan(`
|
|
500
502
|
Optional fields${pathContext}:`));
|
|
501
503
|
for (const field of optionalFields) {
|
|
502
|
-
await this.promptForField(field, targetInputs);
|
|
504
|
+
await this.promptForField(field, targetInputs, context);
|
|
503
505
|
const typedField = field;
|
|
504
506
|
processedFieldKeys.add(typedField.key);
|
|
505
507
|
}
|
|
@@ -542,38 +544,171 @@ Optional fields${pathContext}:`));
|
|
|
542
544
|
}, obj);
|
|
543
545
|
parent[lastKey] = value;
|
|
544
546
|
}
|
|
545
|
-
|
|
547
|
+
/**
|
|
548
|
+
* Extract and normalize field metadata from raw field object
|
|
549
|
+
*/
|
|
550
|
+
extractFieldMetadata(field) {
|
|
546
551
|
const fieldObj = field;
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
552
|
+
const valueType = fieldObj.value_type || "string";
|
|
553
|
+
return {
|
|
554
|
+
key: fieldObj.key,
|
|
555
|
+
title: fieldObj.title || fieldObj.label || fieldObj.key,
|
|
556
|
+
description: fieldObj.description || fieldObj.helpText,
|
|
557
|
+
isRequired: fieldObj.is_required || false,
|
|
558
|
+
defaultValue: fieldObj.default_value ?? fieldObj.default,
|
|
559
|
+
valueType,
|
|
560
|
+
hasDropdown: fieldObj.format === "SELECT",
|
|
561
|
+
isMultiSelect: Boolean(
|
|
562
|
+
valueType === "array" || fieldObj.items && fieldObj.items.type !== void 0
|
|
563
|
+
)
|
|
551
564
|
};
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Fetch a page of choices for a dropdown field
|
|
568
|
+
*/
|
|
569
|
+
async fetchChoices(fieldMeta, inputs, context, cursor) {
|
|
570
|
+
try {
|
|
571
|
+
console.log(
|
|
572
|
+
chalk3__default.default.gray(
|
|
573
|
+
cursor ? ` Fetching more choices...` : ` Fetching choices for ${fieldMeta.title}...`
|
|
574
|
+
)
|
|
575
|
+
);
|
|
576
|
+
const page = await context.sdk.listInputFieldChoices({
|
|
577
|
+
appKey: context.resolvedParams.appKey,
|
|
578
|
+
actionKey: context.resolvedParams.actionKey,
|
|
579
|
+
actionType: context.resolvedParams.actionType,
|
|
580
|
+
authenticationId: context.resolvedParams.authenticationId,
|
|
581
|
+
inputFieldKey: fieldMeta.key,
|
|
582
|
+
inputs,
|
|
583
|
+
...cursor && { cursor }
|
|
584
|
+
});
|
|
585
|
+
const choices = page.data.map((choice) => ({
|
|
586
|
+
label: choice.label || choice.key || String(choice.value),
|
|
587
|
+
value: choice.value ?? choice.key
|
|
588
|
+
}));
|
|
589
|
+
if (choices.length === 0 && !cursor) {
|
|
590
|
+
console.log(
|
|
591
|
+
chalk3__default.default.yellow(` No choices available for ${fieldMeta.title}`)
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
return {
|
|
595
|
+
choices,
|
|
596
|
+
nextCursor: page.nextCursor
|
|
597
|
+
};
|
|
598
|
+
} catch (error) {
|
|
599
|
+
console.warn(
|
|
600
|
+
chalk3__default.default.yellow(` \u26A0\uFE0F Failed to fetch choices for ${fieldMeta.title}:`),
|
|
601
|
+
error
|
|
602
|
+
);
|
|
603
|
+
return { choices: [] };
|
|
555
604
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Prompt user with choices (handles both single and multi-select with pagination)
|
|
608
|
+
*/
|
|
609
|
+
async promptWithChoices({
|
|
610
|
+
fieldMeta,
|
|
611
|
+
choices: initialChoices,
|
|
612
|
+
nextCursor: initialCursor,
|
|
613
|
+
inputs,
|
|
614
|
+
context
|
|
615
|
+
}) {
|
|
616
|
+
const choices = [...initialChoices];
|
|
617
|
+
let nextCursor = initialCursor;
|
|
618
|
+
const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
|
|
619
|
+
while (true) {
|
|
620
|
+
const promptChoices = choices.map((choice) => ({
|
|
621
|
+
name: choice.label,
|
|
622
|
+
value: choice.value
|
|
623
|
+
}));
|
|
624
|
+
if (nextCursor) {
|
|
625
|
+
promptChoices.push({
|
|
626
|
+
name: chalk3__default.default.dim("(Load more...)"),
|
|
627
|
+
value: LOAD_MORE_SENTINEL
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
if (!fieldMeta.isRequired && !fieldMeta.isMultiSelect) {
|
|
631
|
+
promptChoices.push({ name: "(Skip)", value: void 0 });
|
|
632
|
+
}
|
|
633
|
+
const promptConfig = {
|
|
634
|
+
type: fieldMeta.isMultiSelect ? "checkbox" : "list",
|
|
635
|
+
name: fieldMeta.key,
|
|
636
|
+
message: `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`,
|
|
637
|
+
choices: promptChoices,
|
|
638
|
+
...fieldMeta.isMultiSelect && {
|
|
639
|
+
validate: (input) => {
|
|
640
|
+
if (fieldMeta.isRequired && (!input || input.length === 0)) {
|
|
641
|
+
return "At least one selection is required";
|
|
642
|
+
}
|
|
643
|
+
return true;
|
|
644
|
+
}
|
|
568
645
|
}
|
|
569
|
-
|
|
646
|
+
};
|
|
647
|
+
const answer = await inquirer__default.default.prompt([promptConfig]);
|
|
648
|
+
let selectedValue = answer[fieldMeta.key];
|
|
649
|
+
const wantsMore = fieldMeta.isMultiSelect ? Array.isArray(selectedValue) && selectedValue.includes(LOAD_MORE_SENTINEL) : selectedValue === LOAD_MORE_SENTINEL;
|
|
650
|
+
if (wantsMore && nextCursor && context) {
|
|
651
|
+
if (fieldMeta.isMultiSelect && Array.isArray(selectedValue)) {
|
|
652
|
+
selectedValue = selectedValue.filter((v) => v !== LOAD_MORE_SENTINEL);
|
|
653
|
+
}
|
|
654
|
+
const result = await this.fetchChoices(
|
|
655
|
+
fieldMeta,
|
|
656
|
+
inputs,
|
|
657
|
+
context,
|
|
658
|
+
nextCursor
|
|
659
|
+
);
|
|
660
|
+
choices.push(...result.choices);
|
|
661
|
+
nextCursor = result.nextCursor;
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
return selectedValue;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Prompt user for free-form input (text or boolean)
|
|
669
|
+
*/
|
|
670
|
+
async promptFreeForm(fieldMeta) {
|
|
671
|
+
const promptConfig = {
|
|
672
|
+
name: fieldMeta.key,
|
|
673
|
+
message: `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`
|
|
674
|
+
};
|
|
675
|
+
if (fieldMeta.valueType === "boolean") {
|
|
676
|
+
promptConfig.type = "confirm";
|
|
677
|
+
promptConfig.default = fieldMeta.defaultValue !== void 0 ? Boolean(fieldMeta.defaultValue) : void 0;
|
|
678
|
+
} else {
|
|
679
|
+
promptConfig.type = "input";
|
|
680
|
+
promptConfig.default = fieldMeta.defaultValue;
|
|
681
|
+
promptConfig.validate = (input) => {
|
|
682
|
+
if (fieldMeta.isRequired && !input) {
|
|
683
|
+
return "This field is required";
|
|
684
|
+
}
|
|
685
|
+
return true;
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
if (fieldMeta.description) {
|
|
689
|
+
promptConfig.prefix = chalk3__default.default.gray(`\u2139 ${fieldMeta.description}
|
|
690
|
+
`);
|
|
691
|
+
}
|
|
692
|
+
try {
|
|
693
|
+
const answer = await inquirer__default.default.prompt([promptConfig]);
|
|
694
|
+
return answer[fieldMeta.key];
|
|
695
|
+
} catch (error) {
|
|
696
|
+
if (this.isUserCancellation(error)) {
|
|
697
|
+
console.log(chalk3__default.default.yellow("\n\nOperation cancelled by user"));
|
|
698
|
+
throw new ZapierCliUserCancellationError();
|
|
699
|
+
}
|
|
700
|
+
throw error;
|
|
570
701
|
}
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Store field value in inputs object with validation
|
|
705
|
+
*/
|
|
706
|
+
storeFieldValue(inputs, key, value, isRequired) {
|
|
571
707
|
try {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
throw new Error(`Required field ${fieldObj.key} cannot be empty`);
|
|
708
|
+
if (value !== void 0 && value !== "") {
|
|
709
|
+
inputs[key] = value;
|
|
710
|
+
} else if (isRequired) {
|
|
711
|
+
throw new Error(`Required field ${key} cannot be empty`);
|
|
577
712
|
}
|
|
578
713
|
} catch (error) {
|
|
579
714
|
if (this.isUserCancellation(error)) {
|
|
@@ -583,6 +718,34 @@ Optional fields${pathContext}:`));
|
|
|
583
718
|
throw error;
|
|
584
719
|
}
|
|
585
720
|
}
|
|
721
|
+
async promptForField(field, inputs, context) {
|
|
722
|
+
const fieldMeta = this.extractFieldMetadata(field);
|
|
723
|
+
let choices = [];
|
|
724
|
+
let nextCursor;
|
|
725
|
+
if (fieldMeta.hasDropdown && context) {
|
|
726
|
+
const result = await this.fetchChoices(fieldMeta, inputs, context);
|
|
727
|
+
choices = result.choices;
|
|
728
|
+
nextCursor = result.nextCursor;
|
|
729
|
+
}
|
|
730
|
+
let selectedValue;
|
|
731
|
+
if (choices.length > 0) {
|
|
732
|
+
selectedValue = await this.promptWithChoices({
|
|
733
|
+
fieldMeta,
|
|
734
|
+
choices,
|
|
735
|
+
nextCursor,
|
|
736
|
+
inputs,
|
|
737
|
+
context
|
|
738
|
+
});
|
|
739
|
+
} else {
|
|
740
|
+
selectedValue = await this.promptFreeForm(fieldMeta);
|
|
741
|
+
}
|
|
742
|
+
this.storeFieldValue(
|
|
743
|
+
inputs,
|
|
744
|
+
fieldMeta.key,
|
|
745
|
+
selectedValue,
|
|
746
|
+
fieldMeta.isRequired
|
|
747
|
+
);
|
|
748
|
+
}
|
|
586
749
|
isUserCancellation(error) {
|
|
587
750
|
const errorObj = error;
|
|
588
751
|
return errorObj?.name === "ExitPromptError" || errorObj?.message?.includes("User force closed") || errorObj?.isTTYError === true;
|
|
@@ -1462,7 +1625,7 @@ var LoginSchema = zod.z.object({
|
|
|
1462
1625
|
|
|
1463
1626
|
// package.json
|
|
1464
1627
|
var package_default = {
|
|
1465
|
-
version: "0.15.
|
|
1628
|
+
version: "0.15.2"};
|
|
1466
1629
|
|
|
1467
1630
|
// src/telemetry/builders.ts
|
|
1468
1631
|
function createCliBaseEvent(context = {}) {
|
|
@@ -2677,7 +2840,7 @@ var buildManifestPlugin = ({ sdk: sdk2, context }) => {
|
|
|
2677
2840
|
manifestKey: manifestEntry.implementationName,
|
|
2678
2841
|
version: manifestEntry.version || ""
|
|
2679
2842
|
});
|
|
2680
|
-
const
|
|
2843
|
+
const { key: updatedManifestKey, manifest } = await context.updateManifestEntry({
|
|
2681
2844
|
appKey: app.key,
|
|
2682
2845
|
entry: manifestEntry,
|
|
2683
2846
|
configPath,
|
|
@@ -2734,7 +2897,7 @@ function createZapierCliSdk(options = {}) {
|
|
|
2734
2897
|
// package.json with { type: 'json' }
|
|
2735
2898
|
var package_default2 = {
|
|
2736
2899
|
name: "@zapier/zapier-sdk-cli",
|
|
2737
|
-
version: "0.15.
|
|
2900
|
+
version: "0.15.2"};
|
|
2738
2901
|
function detectPackageManager(cwd = process.cwd()) {
|
|
2739
2902
|
const ua = process.env.npm_config_user_agent;
|
|
2740
2903
|
if (ua) {
|
package/dist/cli.mjs
CHANGED
|
@@ -360,7 +360,8 @@ var SchemaParameterResolver = class {
|
|
|
360
360
|
inputs,
|
|
361
361
|
processedFieldKeys,
|
|
362
362
|
[],
|
|
363
|
-
iteration
|
|
363
|
+
iteration,
|
|
364
|
+
updatedContext
|
|
364
365
|
);
|
|
365
366
|
if (fieldStats.newRequired === 0 && fieldStats.newOptional === 0) {
|
|
366
367
|
break;
|
|
@@ -383,7 +384,7 @@ var SchemaParameterResolver = class {
|
|
|
383
384
|
* Recursively processes fieldsets and their fields, maintaining natural structure
|
|
384
385
|
* and creating nested inputs as needed (e.g., fieldset "foo" becomes inputs.foo = [{}])
|
|
385
386
|
*/
|
|
386
|
-
async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1) {
|
|
387
|
+
async processFieldItems(items, targetInputs, processedFieldKeys, fieldsetPath = [], iteration = 1, context) {
|
|
387
388
|
let newRequiredCount = 0;
|
|
388
389
|
let newOptionalCount = 0;
|
|
389
390
|
let optionalSkipped = false;
|
|
@@ -408,7 +409,8 @@ var SchemaParameterResolver = class {
|
|
|
408
409
|
fieldsetTarget,
|
|
409
410
|
processedFieldKeys,
|
|
410
411
|
nestedPath,
|
|
411
|
-
iteration
|
|
412
|
+
iteration,
|
|
413
|
+
context
|
|
412
414
|
);
|
|
413
415
|
newRequiredCount += nestedStats.newRequired;
|
|
414
416
|
newOptionalCount += nestedStats.newOptional;
|
|
@@ -430,7 +432,7 @@ var SchemaParameterResolver = class {
|
|
|
430
432
|
)
|
|
431
433
|
);
|
|
432
434
|
}
|
|
433
|
-
await this.promptForField(typedItem, targetInputs);
|
|
435
|
+
await this.promptForField(typedItem, targetInputs, context);
|
|
434
436
|
processedFieldKeys.add(typedItem.key);
|
|
435
437
|
} else {
|
|
436
438
|
newOptionalCount++;
|
|
@@ -463,7 +465,7 @@ There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}option
|
|
|
463
465
|
console.log(chalk3.cyan(`
|
|
464
466
|
Optional fields${pathContext}:`));
|
|
465
467
|
for (const field of optionalFields) {
|
|
466
|
-
await this.promptForField(field, targetInputs);
|
|
468
|
+
await this.promptForField(field, targetInputs, context);
|
|
467
469
|
const typedField = field;
|
|
468
470
|
processedFieldKeys.add(typedField.key);
|
|
469
471
|
}
|
|
@@ -506,38 +508,171 @@ Optional fields${pathContext}:`));
|
|
|
506
508
|
}, obj);
|
|
507
509
|
parent[lastKey] = value;
|
|
508
510
|
}
|
|
509
|
-
|
|
511
|
+
/**
|
|
512
|
+
* Extract and normalize field metadata from raw field object
|
|
513
|
+
*/
|
|
514
|
+
extractFieldMetadata(field) {
|
|
510
515
|
const fieldObj = field;
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
516
|
+
const valueType = fieldObj.value_type || "string";
|
|
517
|
+
return {
|
|
518
|
+
key: fieldObj.key,
|
|
519
|
+
title: fieldObj.title || fieldObj.label || fieldObj.key,
|
|
520
|
+
description: fieldObj.description || fieldObj.helpText,
|
|
521
|
+
isRequired: fieldObj.is_required || false,
|
|
522
|
+
defaultValue: fieldObj.default_value ?? fieldObj.default,
|
|
523
|
+
valueType,
|
|
524
|
+
hasDropdown: fieldObj.format === "SELECT",
|
|
525
|
+
isMultiSelect: Boolean(
|
|
526
|
+
valueType === "array" || fieldObj.items && fieldObj.items.type !== void 0
|
|
527
|
+
)
|
|
515
528
|
};
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Fetch a page of choices for a dropdown field
|
|
532
|
+
*/
|
|
533
|
+
async fetchChoices(fieldMeta, inputs, context, cursor) {
|
|
534
|
+
try {
|
|
535
|
+
console.log(
|
|
536
|
+
chalk3.gray(
|
|
537
|
+
cursor ? ` Fetching more choices...` : ` Fetching choices for ${fieldMeta.title}...`
|
|
538
|
+
)
|
|
539
|
+
);
|
|
540
|
+
const page = await context.sdk.listInputFieldChoices({
|
|
541
|
+
appKey: context.resolvedParams.appKey,
|
|
542
|
+
actionKey: context.resolvedParams.actionKey,
|
|
543
|
+
actionType: context.resolvedParams.actionType,
|
|
544
|
+
authenticationId: context.resolvedParams.authenticationId,
|
|
545
|
+
inputFieldKey: fieldMeta.key,
|
|
546
|
+
inputs,
|
|
547
|
+
...cursor && { cursor }
|
|
548
|
+
});
|
|
549
|
+
const choices = page.data.map((choice) => ({
|
|
550
|
+
label: choice.label || choice.key || String(choice.value),
|
|
551
|
+
value: choice.value ?? choice.key
|
|
552
|
+
}));
|
|
553
|
+
if (choices.length === 0 && !cursor) {
|
|
554
|
+
console.log(
|
|
555
|
+
chalk3.yellow(` No choices available for ${fieldMeta.title}`)
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
return {
|
|
559
|
+
choices,
|
|
560
|
+
nextCursor: page.nextCursor
|
|
561
|
+
};
|
|
562
|
+
} catch (error) {
|
|
563
|
+
console.warn(
|
|
564
|
+
chalk3.yellow(` \u26A0\uFE0F Failed to fetch choices for ${fieldMeta.title}:`),
|
|
565
|
+
error
|
|
566
|
+
);
|
|
567
|
+
return { choices: [] };
|
|
519
568
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Prompt user with choices (handles both single and multi-select with pagination)
|
|
572
|
+
*/
|
|
573
|
+
async promptWithChoices({
|
|
574
|
+
fieldMeta,
|
|
575
|
+
choices: initialChoices,
|
|
576
|
+
nextCursor: initialCursor,
|
|
577
|
+
inputs,
|
|
578
|
+
context
|
|
579
|
+
}) {
|
|
580
|
+
const choices = [...initialChoices];
|
|
581
|
+
let nextCursor = initialCursor;
|
|
582
|
+
const LOAD_MORE_SENTINEL = Symbol("LOAD_MORE");
|
|
583
|
+
while (true) {
|
|
584
|
+
const promptChoices = choices.map((choice) => ({
|
|
585
|
+
name: choice.label,
|
|
586
|
+
value: choice.value
|
|
587
|
+
}));
|
|
588
|
+
if (nextCursor) {
|
|
589
|
+
promptChoices.push({
|
|
590
|
+
name: chalk3.dim("(Load more...)"),
|
|
591
|
+
value: LOAD_MORE_SENTINEL
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
if (!fieldMeta.isRequired && !fieldMeta.isMultiSelect) {
|
|
595
|
+
promptChoices.push({ name: "(Skip)", value: void 0 });
|
|
596
|
+
}
|
|
597
|
+
const promptConfig = {
|
|
598
|
+
type: fieldMeta.isMultiSelect ? "checkbox" : "list",
|
|
599
|
+
name: fieldMeta.key,
|
|
600
|
+
message: `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`,
|
|
601
|
+
choices: promptChoices,
|
|
602
|
+
...fieldMeta.isMultiSelect && {
|
|
603
|
+
validate: (input) => {
|
|
604
|
+
if (fieldMeta.isRequired && (!input || input.length === 0)) {
|
|
605
|
+
return "At least one selection is required";
|
|
606
|
+
}
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
532
609
|
}
|
|
533
|
-
|
|
610
|
+
};
|
|
611
|
+
const answer = await inquirer.prompt([promptConfig]);
|
|
612
|
+
let selectedValue = answer[fieldMeta.key];
|
|
613
|
+
const wantsMore = fieldMeta.isMultiSelect ? Array.isArray(selectedValue) && selectedValue.includes(LOAD_MORE_SENTINEL) : selectedValue === LOAD_MORE_SENTINEL;
|
|
614
|
+
if (wantsMore && nextCursor && context) {
|
|
615
|
+
if (fieldMeta.isMultiSelect && Array.isArray(selectedValue)) {
|
|
616
|
+
selectedValue = selectedValue.filter((v) => v !== LOAD_MORE_SENTINEL);
|
|
617
|
+
}
|
|
618
|
+
const result = await this.fetchChoices(
|
|
619
|
+
fieldMeta,
|
|
620
|
+
inputs,
|
|
621
|
+
context,
|
|
622
|
+
nextCursor
|
|
623
|
+
);
|
|
624
|
+
choices.push(...result.choices);
|
|
625
|
+
nextCursor = result.nextCursor;
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
return selectedValue;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Prompt user for free-form input (text or boolean)
|
|
633
|
+
*/
|
|
634
|
+
async promptFreeForm(fieldMeta) {
|
|
635
|
+
const promptConfig = {
|
|
636
|
+
name: fieldMeta.key,
|
|
637
|
+
message: `${fieldMeta.title}${fieldMeta.isRequired ? " (required)" : " (optional)"}:`
|
|
638
|
+
};
|
|
639
|
+
if (fieldMeta.valueType === "boolean") {
|
|
640
|
+
promptConfig.type = "confirm";
|
|
641
|
+
promptConfig.default = fieldMeta.defaultValue !== void 0 ? Boolean(fieldMeta.defaultValue) : void 0;
|
|
642
|
+
} else {
|
|
643
|
+
promptConfig.type = "input";
|
|
644
|
+
promptConfig.default = fieldMeta.defaultValue;
|
|
645
|
+
promptConfig.validate = (input) => {
|
|
646
|
+
if (fieldMeta.isRequired && !input) {
|
|
647
|
+
return "This field is required";
|
|
648
|
+
}
|
|
649
|
+
return true;
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
if (fieldMeta.description) {
|
|
653
|
+
promptConfig.prefix = chalk3.gray(`\u2139 ${fieldMeta.description}
|
|
654
|
+
`);
|
|
655
|
+
}
|
|
656
|
+
try {
|
|
657
|
+
const answer = await inquirer.prompt([promptConfig]);
|
|
658
|
+
return answer[fieldMeta.key];
|
|
659
|
+
} catch (error) {
|
|
660
|
+
if (this.isUserCancellation(error)) {
|
|
661
|
+
console.log(chalk3.yellow("\n\nOperation cancelled by user"));
|
|
662
|
+
throw new ZapierCliUserCancellationError();
|
|
663
|
+
}
|
|
664
|
+
throw error;
|
|
534
665
|
}
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Store field value in inputs object with validation
|
|
669
|
+
*/
|
|
670
|
+
storeFieldValue(inputs, key, value, isRequired) {
|
|
535
671
|
try {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
throw new Error(`Required field ${fieldObj.key} cannot be empty`);
|
|
672
|
+
if (value !== void 0 && value !== "") {
|
|
673
|
+
inputs[key] = value;
|
|
674
|
+
} else if (isRequired) {
|
|
675
|
+
throw new Error(`Required field ${key} cannot be empty`);
|
|
541
676
|
}
|
|
542
677
|
} catch (error) {
|
|
543
678
|
if (this.isUserCancellation(error)) {
|
|
@@ -547,6 +682,34 @@ Optional fields${pathContext}:`));
|
|
|
547
682
|
throw error;
|
|
548
683
|
}
|
|
549
684
|
}
|
|
685
|
+
async promptForField(field, inputs, context) {
|
|
686
|
+
const fieldMeta = this.extractFieldMetadata(field);
|
|
687
|
+
let choices = [];
|
|
688
|
+
let nextCursor;
|
|
689
|
+
if (fieldMeta.hasDropdown && context) {
|
|
690
|
+
const result = await this.fetchChoices(fieldMeta, inputs, context);
|
|
691
|
+
choices = result.choices;
|
|
692
|
+
nextCursor = result.nextCursor;
|
|
693
|
+
}
|
|
694
|
+
let selectedValue;
|
|
695
|
+
if (choices.length > 0) {
|
|
696
|
+
selectedValue = await this.promptWithChoices({
|
|
697
|
+
fieldMeta,
|
|
698
|
+
choices,
|
|
699
|
+
nextCursor,
|
|
700
|
+
inputs,
|
|
701
|
+
context
|
|
702
|
+
});
|
|
703
|
+
} else {
|
|
704
|
+
selectedValue = await this.promptFreeForm(fieldMeta);
|
|
705
|
+
}
|
|
706
|
+
this.storeFieldValue(
|
|
707
|
+
inputs,
|
|
708
|
+
fieldMeta.key,
|
|
709
|
+
selectedValue,
|
|
710
|
+
fieldMeta.isRequired
|
|
711
|
+
);
|
|
712
|
+
}
|
|
550
713
|
isUserCancellation(error) {
|
|
551
714
|
const errorObj = error;
|
|
552
715
|
return errorObj?.name === "ExitPromptError" || errorObj?.message?.includes("User force closed") || errorObj?.isTTYError === true;
|
|
@@ -1426,7 +1589,7 @@ var LoginSchema = z.object({
|
|
|
1426
1589
|
|
|
1427
1590
|
// package.json
|
|
1428
1591
|
var package_default = {
|
|
1429
|
-
version: "0.15.
|
|
1592
|
+
version: "0.15.2"};
|
|
1430
1593
|
|
|
1431
1594
|
// src/telemetry/builders.ts
|
|
1432
1595
|
function createCliBaseEvent(context = {}) {
|
|
@@ -2641,7 +2804,7 @@ var buildManifestPlugin = ({ sdk: sdk2, context }) => {
|
|
|
2641
2804
|
manifestKey: manifestEntry.implementationName,
|
|
2642
2805
|
version: manifestEntry.version || ""
|
|
2643
2806
|
});
|
|
2644
|
-
const
|
|
2807
|
+
const { key: updatedManifestKey, manifest } = await context.updateManifestEntry({
|
|
2645
2808
|
appKey: app.key,
|
|
2646
2809
|
entry: manifestEntry,
|
|
2647
2810
|
configPath,
|
|
@@ -2698,7 +2861,7 @@ function createZapierCliSdk(options = {}) {
|
|
|
2698
2861
|
// package.json with { type: 'json' }
|
|
2699
2862
|
var package_default2 = {
|
|
2700
2863
|
name: "@zapier/zapier-sdk-cli",
|
|
2701
|
-
version: "0.15.
|
|
2864
|
+
version: "0.15.2"};
|
|
2702
2865
|
function detectPackageManager(cwd = process.cwd()) {
|
|
2703
2866
|
const ua = process.env.npm_config_user_agent;
|
|
2704
2867
|
if (ua) {
|
package/dist/index.cjs
CHANGED
|
@@ -291,7 +291,7 @@ var LoginSchema = zod.z.object({
|
|
|
291
291
|
|
|
292
292
|
// package.json
|
|
293
293
|
var package_default = {
|
|
294
|
-
version: "0.15.
|
|
294
|
+
version: "0.15.2"};
|
|
295
295
|
|
|
296
296
|
// src/telemetry/builders.ts
|
|
297
297
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1506,7 +1506,7 @@ var buildManifestPlugin = ({ sdk, context }) => {
|
|
|
1506
1506
|
manifestKey: manifestEntry.implementationName,
|
|
1507
1507
|
version: manifestEntry.version || ""
|
|
1508
1508
|
});
|
|
1509
|
-
const
|
|
1509
|
+
const { key: updatedManifestKey, manifest } = await context.updateManifestEntry({
|
|
1510
1510
|
appKey: app.key,
|
|
1511
1511
|
entry: manifestEntry,
|
|
1512
1512
|
configPath,
|
package/dist/index.mjs
CHANGED
|
@@ -260,7 +260,7 @@ var LoginSchema = z.object({
|
|
|
260
260
|
|
|
261
261
|
// package.json
|
|
262
262
|
var package_default = {
|
|
263
|
-
version: "0.15.
|
|
263
|
+
version: "0.15.2"};
|
|
264
264
|
|
|
265
265
|
// src/telemetry/builders.ts
|
|
266
266
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1475,7 +1475,7 @@ var buildManifestPlugin = ({ sdk, context }) => {
|
|
|
1475
1475
|
manifestKey: manifestEntry.implementationName,
|
|
1476
1476
|
version: manifestEntry.version || ""
|
|
1477
1477
|
});
|
|
1478
|
-
const
|
|
1478
|
+
const { key: updatedManifestKey, manifest } = await context.updateManifestEntry({
|
|
1479
1479
|
appKey: app.key,
|
|
1480
1480
|
entry: manifestEntry,
|
|
1481
1481
|
configPath,
|
package/dist/package.json
CHANGED
|
@@ -32,7 +32,7 @@ export const buildManifestPlugin = ({ sdk, context }) => {
|
|
|
32
32
|
manifestKey: manifestEntry.implementationName,
|
|
33
33
|
version: manifestEntry.version || "",
|
|
34
34
|
});
|
|
35
|
-
const
|
|
35
|
+
const { key: updatedManifestKey, manifest } = await context.updateManifestEntry({
|
|
36
36
|
appKey: app.key,
|
|
37
37
|
entry: manifestEntry,
|
|
38
38
|
configPath,
|