@zapier/zapier-sdk-cli 0.6.4 → 0.6.5
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 +6 -0
- package/dist/cli.cjs +20 -16
- package/dist/cli.mjs +20 -16
- package/dist/package.json +1 -1
- package/dist/src/utils/cli-generator.js +8 -8
- package/dist/src/utils/schema-formatter.d.ts +1 -1
- package/dist/src/utils/schema-formatter.js +8 -8
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/utils/cli-generator.test.ts +93 -0
- package/src/utils/cli-generator.ts +14 -9
- package/src/utils/schema-formatter.ts +13 -7
package/package.json
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
// We need to create a test for the formatItemsGeneric function that's defined in cli-generator.ts
|
|
5
|
+
// Since it's not exported, we'll create a simple test that verifies the numbering logic
|
|
6
|
+
|
|
7
|
+
interface TestItem {
|
|
8
|
+
name?: string;
|
|
9
|
+
key?: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe("CLI Generator Pagination Numbering", () => {
|
|
14
|
+
let mockConsoleLog: ReturnType<typeof vi.spyOn>;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
mockConsoleLog = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
mockConsoleLog.mockRestore();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Since formatItemsGeneric is not exported, let's create a regression test
|
|
25
|
+
// that tests the key functionality we care about: continuous numbering
|
|
26
|
+
it("should prevent pagination numbering regression by testing chalk formatting", () => {
|
|
27
|
+
// Simulate what formatItemsGeneric does for pagination numbering
|
|
28
|
+
const simulateFormatting = (items: TestItem[], startingNumber: number) => {
|
|
29
|
+
const calls: string[] = [];
|
|
30
|
+
items.forEach((item, index) => {
|
|
31
|
+
const name = item.name || item.key || item.id || "Item";
|
|
32
|
+
const formatted = `${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`;
|
|
33
|
+
calls.push(formatted);
|
|
34
|
+
});
|
|
35
|
+
return calls;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Test first page (items 1-3)
|
|
39
|
+
const page1Items = [
|
|
40
|
+
{ name: "App 1", key: "app1" },
|
|
41
|
+
{ name: "App 2", key: "app2" },
|
|
42
|
+
{ name: "App 3", key: "app3" },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const page2Items = [
|
|
46
|
+
{ name: "App 4", key: "app4" },
|
|
47
|
+
{ name: "App 5", key: "app5" },
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// Format first page starting from 0
|
|
51
|
+
const page1Output = simulateFormatting(page1Items, 0);
|
|
52
|
+
|
|
53
|
+
// Format second page starting from 3 (3 items shown already)
|
|
54
|
+
const page2Output = simulateFormatting(page2Items, 3);
|
|
55
|
+
|
|
56
|
+
// Check that page 1 contains 1., 2., 3.
|
|
57
|
+
expect(page1Output.some((line) => line.includes("1."))).toBe(true);
|
|
58
|
+
expect(page1Output.some((line) => line.includes("2."))).toBe(true);
|
|
59
|
+
expect(page1Output.some((line) => line.includes("3."))).toBe(true);
|
|
60
|
+
|
|
61
|
+
// Check that page 2 contains 4., 5. (continuing from page 1)
|
|
62
|
+
expect(page2Output.some((line) => line.includes("4."))).toBe(true);
|
|
63
|
+
expect(page2Output.some((line) => line.includes("5."))).toBe(true);
|
|
64
|
+
|
|
65
|
+
// Most importantly: page 2 should NOT restart at 1.
|
|
66
|
+
expect(page2Output.some((line) => line.includes("1."))).toBe(false);
|
|
67
|
+
expect(page2Output.some((line) => line.includes("2."))).toBe(false);
|
|
68
|
+
expect(page2Output.some((line) => line.includes("3."))).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should handle edge case of starting number 0", () => {
|
|
72
|
+
const simulateFormatting = (
|
|
73
|
+
items: TestItem[],
|
|
74
|
+
startingNumber: number = 0,
|
|
75
|
+
) => {
|
|
76
|
+
const calls: string[] = [];
|
|
77
|
+
items.forEach((item, index) => {
|
|
78
|
+
const name = item.name || item.key || item.id || "Item";
|
|
79
|
+
const formatted = `${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`;
|
|
80
|
+
calls.push(formatted);
|
|
81
|
+
});
|
|
82
|
+
return calls;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const items = [{ name: "First Item" }, { name: "Second Item" }];
|
|
86
|
+
|
|
87
|
+
// Default startingNumber should be 0, resulting in 1. and 2.
|
|
88
|
+
const output = simulateFormatting(items, 0);
|
|
89
|
+
|
|
90
|
+
expect(output.some((line) => line.includes("1."))).toBe(true);
|
|
91
|
+
expect(output.some((line) => line.includes("2."))).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -307,12 +307,12 @@ function createCommandConfig(
|
|
|
307
307
|
!shouldUseJson &&
|
|
308
308
|
!hasUserSpecifiedMaxItems
|
|
309
309
|
) {
|
|
310
|
-
// Get the async
|
|
310
|
+
// Get the async iterable directly from the SDK method call (don't await it! that breaks the next page behavior)
|
|
311
311
|
const sdkObj = sdk as unknown as Record<
|
|
312
312
|
string,
|
|
313
|
-
(params: unknown) => Promise<unknown>
|
|
313
|
+
(params: unknown) => Promise<unknown> & AsyncIterable<unknown>
|
|
314
314
|
>;
|
|
315
|
-
const sdkIterator =
|
|
315
|
+
const sdkIterator = sdkObj[sdkMethodName](resolvedParams);
|
|
316
316
|
await handlePaginatedListWithAsyncIteration(
|
|
317
317
|
sdkMethodName,
|
|
318
318
|
sdkIterator,
|
|
@@ -577,9 +577,9 @@ async function handlePaginatedListWithAsyncIteration(
|
|
|
577
577
|
|
|
578
578
|
// Format and display items using schema
|
|
579
579
|
if (schema) {
|
|
580
|
-
formatItemsFromSchema(schema as z.ZodType, items);
|
|
580
|
+
formatItemsFromSchema(schema as z.ZodType, items, totalShown);
|
|
581
581
|
} else {
|
|
582
|
-
formatItemsGeneric(items);
|
|
582
|
+
formatItemsGeneric(items, totalShown);
|
|
583
583
|
}
|
|
584
584
|
|
|
585
585
|
totalShown += items.length;
|
|
@@ -620,9 +620,9 @@ async function handlePaginatedListWithAsyncIteration(
|
|
|
620
620
|
}
|
|
621
621
|
|
|
622
622
|
if (schema) {
|
|
623
|
-
formatItemsFromSchema(schema as z.ZodType, items);
|
|
623
|
+
formatItemsFromSchema(schema as z.ZodType, items, 0);
|
|
624
624
|
} else {
|
|
625
|
-
formatItemsGeneric(items);
|
|
625
|
+
formatItemsGeneric(items, 0);
|
|
626
626
|
}
|
|
627
627
|
|
|
628
628
|
console.log(chalk.green(`\n✅ Showing ${items.length} ${itemName}`));
|
|
@@ -683,12 +683,17 @@ function formatNonPaginatedResults(
|
|
|
683
683
|
}
|
|
684
684
|
}
|
|
685
685
|
|
|
686
|
-
function formatItemsGeneric(
|
|
686
|
+
function formatItemsGeneric(
|
|
687
|
+
items: unknown[],
|
|
688
|
+
startingNumber: number = 0,
|
|
689
|
+
): void {
|
|
687
690
|
// Fallback formatting for items without schema metadata
|
|
688
691
|
items.forEach((item, index) => {
|
|
689
692
|
const itemObj = item as Record<string, unknown>;
|
|
690
693
|
const name = itemObj?.name || itemObj?.key || itemObj?.id || "Item";
|
|
691
|
-
console.log(
|
|
694
|
+
console.log(
|
|
695
|
+
`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(String(name))}`,
|
|
696
|
+
);
|
|
692
697
|
if (itemObj?.description) {
|
|
693
698
|
console.log(` ${chalk.dim(String(itemObj.description))}`);
|
|
694
699
|
}
|
|
@@ -32,38 +32,39 @@ function getOutputSchema(schema: unknown): unknown {
|
|
|
32
32
|
export function formatItemsFromSchema(
|
|
33
33
|
inputSchema: z.ZodType,
|
|
34
34
|
items: unknown[],
|
|
35
|
+
startingNumber: number = 0,
|
|
35
36
|
): void {
|
|
36
37
|
// Get the output schema and its format metadata
|
|
37
38
|
const outputSchema = getOutputSchema(inputSchema);
|
|
38
39
|
if (!outputSchema) {
|
|
39
40
|
// Fallback to generic formatting if no output schema
|
|
40
|
-
formatItemsGeneric(items);
|
|
41
|
+
formatItemsGeneric(items, startingNumber);
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
const formatMeta = getFormatMetadata(outputSchema);
|
|
45
46
|
if (!formatMeta) {
|
|
46
47
|
// Fallback to generic formatting if no format metadata
|
|
47
|
-
formatItemsGeneric(items);
|
|
48
|
+
formatItemsGeneric(items, startingNumber);
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
// Format each item using the schema metadata
|
|
52
53
|
items.forEach((item, index) => {
|
|
53
|
-
formatSingleItem(item, index, formatMeta);
|
|
54
|
+
formatSingleItem(item, startingNumber + index, formatMeta);
|
|
54
55
|
});
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
function formatSingleItem(
|
|
58
59
|
item: unknown,
|
|
59
|
-
|
|
60
|
+
itemNumber: number,
|
|
60
61
|
formatMeta: FormatMetadata,
|
|
61
62
|
): void {
|
|
62
63
|
// Get the formatted item from the format function
|
|
63
64
|
const formatted = formatMeta.format(item);
|
|
64
65
|
|
|
65
66
|
// Build the main title line
|
|
66
|
-
let titleLine = `${chalk.gray(`${
|
|
67
|
+
let titleLine = `${chalk.gray(`${itemNumber + 1}.`)} ${chalk.cyan(formatted.title)}`;
|
|
67
68
|
if (formatted.subtitle) {
|
|
68
69
|
titleLine += ` ${chalk.gray(formatted.subtitle)}`;
|
|
69
70
|
}
|
|
@@ -94,7 +95,10 @@ function applyStyle(value: string, style: string): string {
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
function formatItemsGeneric(
|
|
98
|
+
function formatItemsGeneric(
|
|
99
|
+
items: unknown[],
|
|
100
|
+
startingNumber: number = 0,
|
|
101
|
+
): void {
|
|
98
102
|
// Fallback formatting for items without schema metadata
|
|
99
103
|
items.forEach((item, index) => {
|
|
100
104
|
const itemObj = item as {
|
|
@@ -106,7 +110,9 @@ function formatItemsGeneric(items: unknown[]): void {
|
|
|
106
110
|
};
|
|
107
111
|
const name =
|
|
108
112
|
itemObj.title || itemObj.name || itemObj.key || itemObj.id || "Item";
|
|
109
|
-
console.log(
|
|
113
|
+
console.log(
|
|
114
|
+
`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(name)}`,
|
|
115
|
+
);
|
|
110
116
|
if (itemObj.description) {
|
|
111
117
|
console.log(` ${chalk.dim(itemObj.description)}`);
|
|
112
118
|
}
|