@zapier/zapier-sdk-cli 0.15.1 → 0.15.3
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 +205 -34
- package/dist/cli.mjs +205 -34
- package/dist/index.cjs +10 -2
- package/dist/index.mjs +10 -2
- package/dist/package.json +1 -1
- package/dist/src/plugins/login/index.js +11 -0
- 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/login/index.ts +11 -0
- 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.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f7e552e: Add synchronous customuser_id and account_id retrieval to event emission plugin
|
|
8
|
+
- Updated dependencies [f7e552e]
|
|
9
|
+
- @zapier/zapier-sdk@0.15.4
|
|
10
|
+
- @zapier/zapier-sdk-mcp@0.3.28
|
|
11
|
+
|
|
12
|
+
## 0.15.2
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- a4aee2e: Enhanced param resolver to fully resolve dynamic input fields and dynamic choices.
|
|
17
|
+
|
|
3
18
|
## 0.15.1
|
|
4
19
|
|
|
5
20
|
### Patch 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
|
+
`);
|
|
570
691
|
}
|
|
571
692
|
try {
|
|
572
|
-
const answer = await inquirer__default.default.prompt([
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
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;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Store field value in inputs object with validation
|
|
705
|
+
*/
|
|
706
|
+
storeFieldValue(inputs, key, value, isRequired) {
|
|
707
|
+
try {
|
|
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.3"};
|
|
1466
1629
|
|
|
1467
1630
|
// src/telemetry/builders.ts
|
|
1468
1631
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1541,6 +1704,8 @@ var loginPlugin = ({ context }) => {
|
|
|
1541
1704
|
const startTime = Date.now();
|
|
1542
1705
|
let success = false;
|
|
1543
1706
|
let errorMessage = null;
|
|
1707
|
+
let accountId = null;
|
|
1708
|
+
let customUserId = null;
|
|
1544
1709
|
try {
|
|
1545
1710
|
await loginWithSdk({
|
|
1546
1711
|
...options,
|
|
@@ -1549,6 +1714,10 @@ var loginPlugin = ({ context }) => {
|
|
|
1549
1714
|
authClientId: context.options?.authClientId
|
|
1550
1715
|
});
|
|
1551
1716
|
success = true;
|
|
1717
|
+
try {
|
|
1718
|
+
({ accountId, customUserId } = await zapierSdkCliLogin.getLoggedInUser());
|
|
1719
|
+
} catch {
|
|
1720
|
+
}
|
|
1552
1721
|
} catch (error) {
|
|
1553
1722
|
success = false;
|
|
1554
1723
|
errorMessage = error instanceof Error ? error.message : "Login failed";
|
|
@@ -1572,7 +1741,9 @@ var loginPlugin = ({ context }) => {
|
|
|
1572
1741
|
session_id: context.session_id,
|
|
1573
1742
|
selected_api: context.selected_api,
|
|
1574
1743
|
app_id: context.app_id,
|
|
1575
|
-
app_version_id: context.app_version_id
|
|
1744
|
+
app_version_id: context.app_version_id,
|
|
1745
|
+
customuser_id: customUserId,
|
|
1746
|
+
account_id: accountId
|
|
1576
1747
|
},
|
|
1577
1748
|
cliVersion: package_default.version
|
|
1578
1749
|
});
|
|
@@ -2734,7 +2905,7 @@ function createZapierCliSdk(options = {}) {
|
|
|
2734
2905
|
// package.json with { type: 'json' }
|
|
2735
2906
|
var package_default2 = {
|
|
2736
2907
|
name: "@zapier/zapier-sdk-cli",
|
|
2737
|
-
version: "0.15.
|
|
2908
|
+
version: "0.15.3"};
|
|
2738
2909
|
function detectPackageManager(cwd = process.cwd()) {
|
|
2739
2910
|
const ua = process.env.npm_config_user_agent;
|
|
2740
2911
|
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
|
+
`);
|
|
534
655
|
}
|
|
535
656
|
try {
|
|
536
|
-
const answer = await inquirer.prompt([
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Store field value in inputs object with validation
|
|
669
|
+
*/
|
|
670
|
+
storeFieldValue(inputs, key, value, isRequired) {
|
|
671
|
+
try {
|
|
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.3"};
|
|
1430
1593
|
|
|
1431
1594
|
// src/telemetry/builders.ts
|
|
1432
1595
|
function createCliBaseEvent(context = {}) {
|
|
@@ -1505,6 +1668,8 @@ var loginPlugin = ({ context }) => {
|
|
|
1505
1668
|
const startTime = Date.now();
|
|
1506
1669
|
let success = false;
|
|
1507
1670
|
let errorMessage = null;
|
|
1671
|
+
let accountId = null;
|
|
1672
|
+
let customUserId = null;
|
|
1508
1673
|
try {
|
|
1509
1674
|
await loginWithSdk({
|
|
1510
1675
|
...options,
|
|
@@ -1513,6 +1678,10 @@ var loginPlugin = ({ context }) => {
|
|
|
1513
1678
|
authClientId: context.options?.authClientId
|
|
1514
1679
|
});
|
|
1515
1680
|
success = true;
|
|
1681
|
+
try {
|
|
1682
|
+
({ accountId, customUserId } = await getLoggedInUser());
|
|
1683
|
+
} catch {
|
|
1684
|
+
}
|
|
1516
1685
|
} catch (error) {
|
|
1517
1686
|
success = false;
|
|
1518
1687
|
errorMessage = error instanceof Error ? error.message : "Login failed";
|
|
@@ -1536,7 +1705,9 @@ var loginPlugin = ({ context }) => {
|
|
|
1536
1705
|
session_id: context.session_id,
|
|
1537
1706
|
selected_api: context.selected_api,
|
|
1538
1707
|
app_id: context.app_id,
|
|
1539
|
-
app_version_id: context.app_version_id
|
|
1708
|
+
app_version_id: context.app_version_id,
|
|
1709
|
+
customuser_id: customUserId,
|
|
1710
|
+
account_id: accountId
|
|
1540
1711
|
},
|
|
1541
1712
|
cliVersion: package_default.version
|
|
1542
1713
|
});
|
|
@@ -2698,7 +2869,7 @@ function createZapierCliSdk(options = {}) {
|
|
|
2698
2869
|
// package.json with { type: 'json' }
|
|
2699
2870
|
var package_default2 = {
|
|
2700
2871
|
name: "@zapier/zapier-sdk-cli",
|
|
2701
|
-
version: "0.15.
|
|
2872
|
+
version: "0.15.3"};
|
|
2702
2873
|
function detectPackageManager(cwd = process.cwd()) {
|
|
2703
2874
|
const ua = process.env.npm_config_user_agent;
|
|
2704
2875
|
if (ua) {
|