@zapier/zapier-sdk-cli 0.8.4 → 0.10.0
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 +32 -0
- package/README.md +35 -51
- package/dist/cli.cjs +950 -433
- package/dist/cli.mjs +951 -434
- package/dist/index.cjs +729 -336
- package/dist/index.mjs +730 -337
- package/dist/package.json +1 -1
- package/dist/src/plugins/add/ast-generator.d.ts +37 -0
- package/dist/src/plugins/add/ast-generator.js +403 -0
- package/dist/src/plugins/add/index.d.ts +13 -0
- package/dist/src/plugins/add/index.js +120 -0
- package/dist/src/plugins/add/schemas.d.ts +18 -0
- package/dist/src/plugins/add/schemas.js +19 -0
- package/dist/src/plugins/getLoginConfigPath/index.d.ts +15 -0
- package/dist/src/plugins/getLoginConfigPath/index.js +19 -0
- package/dist/src/plugins/getLoginConfigPath/schemas.d.ts +3 -0
- package/dist/src/plugins/getLoginConfigPath/schemas.js +5 -0
- package/dist/src/plugins/index.d.ts +2 -2
- package/dist/src/plugins/index.js +2 -2
- package/dist/src/sdk.js +3 -3
- package/dist/src/utils/cli-generator-utils.d.ts +2 -1
- package/dist/src/utils/cli-generator-utils.js +11 -5
- package/dist/src/utils/cli-generator.js +65 -65
- package/dist/src/utils/parameter-resolver.d.ts +4 -1
- package/dist/src/utils/parameter-resolver.js +92 -15
- package/dist/src/utils/schema-formatter.d.ts +5 -1
- package/dist/src/utils/schema-formatter.js +48 -18
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/plugins/add/ast-generator.ts +777 -0
- package/src/plugins/add/index.test.ts +58 -0
- package/src/plugins/add/index.ts +187 -0
- package/src/plugins/add/schemas.ts +26 -0
- package/src/plugins/getLoginConfigPath/index.ts +45 -0
- package/src/plugins/getLoginConfigPath/schemas.ts +10 -0
- package/src/plugins/index.ts +2 -2
- package/src/sdk.ts +4 -4
- package/src/utils/cli-generator-utils.ts +17 -5
- package/src/utils/cli-generator.ts +90 -79
- package/src/utils/parameter-resolver.ts +155 -21
- package/src/utils/schema-formatter.ts +68 -33
- package/tsup.config.ts +1 -1
- package/dist/src/plugins/generateTypes/index.d.ts +0 -21
- package/dist/src/plugins/generateTypes/index.js +0 -312
- package/dist/src/plugins/generateTypes/schemas.d.ts +0 -18
- package/dist/src/plugins/generateTypes/schemas.js +0 -14
- package/dist/src/plugins/getConfigPath/index.d.ts +0 -15
- package/dist/src/plugins/getConfigPath/index.js +0 -19
- package/dist/src/plugins/getConfigPath/schemas.d.ts +0 -3
- package/dist/src/plugins/getConfigPath/schemas.js +0 -5
- package/src/plugins/generateTypes/index.ts +0 -444
- package/src/plugins/generateTypes/schemas.ts +0 -23
- package/src/plugins/getConfigPath/index.ts +0 -42
- package/src/plugins/getConfigPath/schemas.ts +0 -8
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import type { z } from "zod";
|
|
3
|
+
import util from "util";
|
|
3
4
|
// These functions are internal to SDK, implementing basic formatting fallback
|
|
4
5
|
// TODO: Consider exposing these utilities or implementing proper CLI formatting
|
|
5
6
|
|
|
6
7
|
interface FormattedItem {
|
|
7
8
|
title: string;
|
|
8
|
-
|
|
9
|
+
id?: string;
|
|
10
|
+
key?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
data?: unknown; // Optional: if provided, use formatJsonOutput instead of details
|
|
9
13
|
details: Array<{
|
|
10
14
|
text: string;
|
|
11
15
|
style: "normal" | "dim" | "accent" | "warning" | "success";
|
|
@@ -25,17 +29,34 @@ function getOutputSchema(schema: unknown): unknown {
|
|
|
25
29
|
return (schema as { _def?: { outputSchema?: unknown } })?._def?.outputSchema;
|
|
26
30
|
}
|
|
27
31
|
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// JSON Formatting
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
export function formatJsonOutput(data: unknown): void {
|
|
37
|
+
// Don't print anything for undefined results (commands that just perform actions)
|
|
38
|
+
if (data === undefined) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Use util.inspect for colored output
|
|
43
|
+
console.log(
|
|
44
|
+
util.inspect(data, { colors: true, depth: null, breakLength: 80 }),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
28
48
|
// ============================================================================
|
|
29
49
|
// Generic Schema-Driven Formatter
|
|
30
50
|
// ============================================================================
|
|
31
51
|
|
|
32
52
|
export function formatItemsFromSchema(
|
|
33
|
-
inputSchema: z.ZodType,
|
|
53
|
+
functionInfo: { inputSchema: z.ZodType; outputSchema?: z.ZodType },
|
|
34
54
|
items: unknown[],
|
|
35
55
|
startingNumber: number = 0,
|
|
36
56
|
): void {
|
|
37
|
-
// Get the output schema
|
|
38
|
-
const outputSchema =
|
|
57
|
+
// Get the output schema from function info or fall back to input schema output schema
|
|
58
|
+
const outputSchema =
|
|
59
|
+
functionInfo.outputSchema || getOutputSchema(functionInfo.inputSchema);
|
|
39
60
|
if (!outputSchema) {
|
|
40
61
|
// Fallback to generic formatting if no output schema
|
|
41
62
|
formatItemsGeneric(items, startingNumber);
|
|
@@ -51,25 +72,35 @@ export function formatItemsFromSchema(
|
|
|
51
72
|
|
|
52
73
|
// Format each item using the schema metadata
|
|
53
74
|
items.forEach((item, index) => {
|
|
54
|
-
|
|
75
|
+
const formatted = formatMeta.format(item);
|
|
76
|
+
formatSingleItem(formatted, startingNumber + index);
|
|
55
77
|
});
|
|
56
78
|
}
|
|
57
79
|
|
|
58
|
-
function formatSingleItem(
|
|
59
|
-
|
|
60
|
-
itemNumber: number,
|
|
61
|
-
formatMeta: FormatMetadata,
|
|
62
|
-
): void {
|
|
63
|
-
// Get the formatted item from the format function
|
|
64
|
-
const formatted = formatMeta.format(item);
|
|
65
|
-
|
|
66
|
-
// Build the main title line
|
|
80
|
+
function formatSingleItem(formatted: FormattedItem, itemNumber: number): void {
|
|
81
|
+
// Build the main title line with optional subtitle
|
|
67
82
|
let titleLine = `${chalk.gray(`${itemNumber + 1}.`)} ${chalk.cyan(formatted.title)}`;
|
|
68
|
-
|
|
69
|
-
|
|
83
|
+
|
|
84
|
+
// Generate subtitle from id or key
|
|
85
|
+
if (formatted.id) {
|
|
86
|
+
titleLine += ` ${chalk.gray(`(ID: ${formatted.id})`)}`;
|
|
87
|
+
} else if (formatted.key) {
|
|
88
|
+
titleLine += ` ${chalk.gray(`(${formatted.key})`)}`;
|
|
70
89
|
}
|
|
71
90
|
console.log(titleLine);
|
|
72
91
|
|
|
92
|
+
// Show description if available
|
|
93
|
+
if (formatted.description) {
|
|
94
|
+
console.log(` ${chalk.dim(formatted.description)}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// If data is provided, use JSON formatting instead of details
|
|
98
|
+
if (formatted.data !== undefined) {
|
|
99
|
+
formatJsonOutput(formatted.data);
|
|
100
|
+
console.log(); // Empty line between items
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
73
104
|
// Format detail lines
|
|
74
105
|
for (const detail of formatted.details) {
|
|
75
106
|
const styledText = applyStyle(detail.text, detail.style);
|
|
@@ -95,27 +126,31 @@ function applyStyle(value: string, style: string): string {
|
|
|
95
126
|
}
|
|
96
127
|
}
|
|
97
128
|
|
|
129
|
+
function convertGenericItemToFormattedItem(item: unknown): FormattedItem {
|
|
130
|
+
const itemObj = item as {
|
|
131
|
+
title?: string;
|
|
132
|
+
name?: string;
|
|
133
|
+
key?: string;
|
|
134
|
+
id?: string;
|
|
135
|
+
description?: string;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
title: itemObj.title || itemObj.name || itemObj.key || itemObj.id || "Item",
|
|
140
|
+
id: itemObj.id,
|
|
141
|
+
key: itemObj.key,
|
|
142
|
+
description: itemObj.description,
|
|
143
|
+
details: [],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
98
147
|
function formatItemsGeneric(
|
|
99
148
|
items: unknown[],
|
|
100
149
|
startingNumber: number = 0,
|
|
101
150
|
): void {
|
|
102
|
-
//
|
|
151
|
+
// Convert generic items to FormattedItem and use formatSingleItem
|
|
103
152
|
items.forEach((item, index) => {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
name?: string;
|
|
107
|
-
key?: string;
|
|
108
|
-
id?: string;
|
|
109
|
-
description?: string;
|
|
110
|
-
};
|
|
111
|
-
const name =
|
|
112
|
-
itemObj.title || itemObj.name || itemObj.key || itemObj.id || "Item";
|
|
113
|
-
console.log(
|
|
114
|
-
`${chalk.gray(`${startingNumber + index + 1}.`)} ${chalk.cyan(name)}`,
|
|
115
|
-
);
|
|
116
|
-
if (itemObj.description) {
|
|
117
|
-
console.log(` ${chalk.dim(itemObj.description)}`);
|
|
118
|
-
}
|
|
119
|
-
console.log();
|
|
153
|
+
const formatted = convertGenericItemToFormattedItem(item);
|
|
154
|
+
formatSingleItem(formatted, startingNumber + index);
|
|
120
155
|
});
|
|
121
156
|
}
|
package/tsup.config.ts
CHANGED
|
@@ -17,7 +17,7 @@ export default defineConfig({
|
|
|
17
17
|
};
|
|
18
18
|
},
|
|
19
19
|
// Make the optional CLI login package external so it doesn't cause build issues
|
|
20
|
-
external: ["@zapier/zapier-sdk-cli-login"],
|
|
20
|
+
external: ["@zapier/zapier-sdk-cli-login", "typescript"],
|
|
21
21
|
// Use the build-specific tsconfig for tsup
|
|
22
22
|
tsconfig: "tsconfig.build.json",
|
|
23
23
|
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { Plugin, GetSdkType, ListActionsPluginProvides, ListInputFieldsPluginProvides, ManifestPluginProvides } from "@zapier/zapier-sdk";
|
|
2
|
-
import { GenerateTypesSchema, type GenerateTypesOptions } from "./schemas";
|
|
3
|
-
export interface GenerateTypesPluginProvides {
|
|
4
|
-
generateTypes: (options: GenerateTypesOptions) => Promise<string>;
|
|
5
|
-
context: {
|
|
6
|
-
meta: {
|
|
7
|
-
generateTypes: {
|
|
8
|
-
inputSchema: typeof GenerateTypesSchema;
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export declare const generateTypesPlugin: Plugin<GetSdkType<ListActionsPluginProvides & ListInputFieldsPluginProvides & ManifestPluginProvides>, // requires these SDK methods
|
|
14
|
-
{}, // requires no context
|
|
15
|
-
GenerateTypesPluginProvides>;
|
|
16
|
-
/**
|
|
17
|
-
* Generate TypeScript types for a specific app (CLI version)
|
|
18
|
-
*/
|
|
19
|
-
export declare function generateTypes(options: GenerateTypesOptions & {
|
|
20
|
-
sdk: GetSdkType<ListActionsPluginProvides & ListInputFieldsPluginProvides & ManifestPluginProvides>;
|
|
21
|
-
}): Promise<string>;
|
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
import { GenerateTypesSchema } from "./schemas";
|
|
2
|
-
import { createFunction } from "@zapier/zapier-sdk";
|
|
3
|
-
import * as fs from "fs";
|
|
4
|
-
import * as path from "path";
|
|
5
|
-
export const generateTypesPlugin = ({ sdk }) => {
|
|
6
|
-
const generateTypesWithSdk = createFunction(async function generateTypesWithSdk(options) {
|
|
7
|
-
return await generateTypes({ ...options, sdk });
|
|
8
|
-
}, GenerateTypesSchema);
|
|
9
|
-
return {
|
|
10
|
-
generateTypes: generateTypesWithSdk,
|
|
11
|
-
context: {
|
|
12
|
-
meta: {
|
|
13
|
-
generateTypes: {
|
|
14
|
-
categories: ["utility"],
|
|
15
|
-
inputSchema: GenerateTypesSchema,
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Generate the fetch method signature for app proxies
|
|
23
|
-
*/
|
|
24
|
-
function generateFetchMethodSignature() {
|
|
25
|
-
return ` /** Make authenticated HTTP requests through Zapier's Relay service */
|
|
26
|
-
fetch: (options: Omit<z.infer<typeof RelayFetchSchema>, 'authenticationId'>) => Promise<Response>`;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Generate TypeScript types for a specific app (CLI version)
|
|
30
|
-
*/
|
|
31
|
-
export async function generateTypes(options) {
|
|
32
|
-
const { appKey, authenticationId, output = `./types/${appKey}.d.ts`, sdk, } = options;
|
|
33
|
-
// Parse app identifier (support app@version format)
|
|
34
|
-
const { app, version } = parseAppIdentifier(appKey);
|
|
35
|
-
// Fetch all actions for the app
|
|
36
|
-
const actionsResult = await sdk.listActions({
|
|
37
|
-
appKey: app,
|
|
38
|
-
});
|
|
39
|
-
const actions = actionsResult.data;
|
|
40
|
-
if (actions.length === 0) {
|
|
41
|
-
const typeDefinitions = generateEmptyTypesFile(app, version);
|
|
42
|
-
if (output) {
|
|
43
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
44
|
-
fs.writeFileSync(output, typeDefinitions, "utf8");
|
|
45
|
-
}
|
|
46
|
-
return typeDefinitions;
|
|
47
|
-
}
|
|
48
|
-
// Fetch input fields for each action
|
|
49
|
-
const actionsWithFields = [];
|
|
50
|
-
if (authenticationId) {
|
|
51
|
-
for (const action of actions) {
|
|
52
|
-
try {
|
|
53
|
-
// Check to see if the appKey is in the manifest
|
|
54
|
-
const manifestEntry = sdk.getContext().getManifestEntry(appKey);
|
|
55
|
-
const fieldsResult = await sdk.listInputFields({
|
|
56
|
-
// If the appKey is in the manifest, use the appKey so that the types are consistent with the manifest's version, otherwise use the action.app_key
|
|
57
|
-
appKey: manifestEntry ? appKey : action.app_key,
|
|
58
|
-
actionKey: action.key,
|
|
59
|
-
actionType: action.action_type,
|
|
60
|
-
authenticationId: authenticationId,
|
|
61
|
-
});
|
|
62
|
-
const fields = fieldsResult.data.map((field) => {
|
|
63
|
-
const fieldObj = field;
|
|
64
|
-
return {
|
|
65
|
-
...fieldObj,
|
|
66
|
-
required: fieldObj.is_required || fieldObj.required || false,
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
actionsWithFields.push({
|
|
70
|
-
...action,
|
|
71
|
-
inputFields: fields,
|
|
72
|
-
name: action.title || action.key,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
// If we can't get fields for an action, include it without fields
|
|
77
|
-
actionsWithFields.push({
|
|
78
|
-
...action,
|
|
79
|
-
inputFields: [],
|
|
80
|
-
name: action.title || action.key,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
// Convert actions to have empty input fields (will generate generic types)
|
|
87
|
-
actions.forEach((action) => {
|
|
88
|
-
actionsWithFields.push({
|
|
89
|
-
...action,
|
|
90
|
-
inputFields: [],
|
|
91
|
-
name: action.title || action.key,
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
// Generate TypeScript types
|
|
96
|
-
const typeDefinitions = generateTypeDefinitions(app, actionsWithFields, version);
|
|
97
|
-
// Write to file if output path specified
|
|
98
|
-
if (output) {
|
|
99
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
100
|
-
fs.writeFileSync(output, typeDefinitions, "utf8");
|
|
101
|
-
}
|
|
102
|
-
return typeDefinitions;
|
|
103
|
-
}
|
|
104
|
-
function parseAppIdentifier(identifier) {
|
|
105
|
-
const parts = identifier.split("@");
|
|
106
|
-
return {
|
|
107
|
-
app: parts[0],
|
|
108
|
-
version: parts[1],
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
function generateTypeDefinitions(appKey, actions, version) {
|
|
112
|
-
// Handle empty actions
|
|
113
|
-
if (actions.length === 0) {
|
|
114
|
-
return generateEmptyTypesFile(appKey, version);
|
|
115
|
-
}
|
|
116
|
-
// Group actions by type
|
|
117
|
-
const actionsByType = actions.reduce((acc, action) => {
|
|
118
|
-
if (!acc[action.action_type]) {
|
|
119
|
-
acc[action.action_type] = [];
|
|
120
|
-
}
|
|
121
|
-
acc[action.action_type].push(action);
|
|
122
|
-
return acc;
|
|
123
|
-
}, {});
|
|
124
|
-
const appName = capitalize(appKey);
|
|
125
|
-
const versionComment = version
|
|
126
|
-
? ` * Generated for ${appKey}@${version}`
|
|
127
|
-
: ` * Generated for ${appKey}`;
|
|
128
|
-
let output = `/* eslint-disable @typescript-eslint/naming-convention */
|
|
129
|
-
/**
|
|
130
|
-
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
131
|
-
${versionComment}
|
|
132
|
-
* Generated on: ${new Date().toISOString()}
|
|
133
|
-
*
|
|
134
|
-
* Usage:
|
|
135
|
-
* import type { ${appName}Sdk } from './path/to/this/file'
|
|
136
|
-
* const sdk = createZapierSdk() as unknown as ${appName}Sdk
|
|
137
|
-
*
|
|
138
|
-
* // Direct usage (per-call auth):
|
|
139
|
-
* await sdk.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
|
|
140
|
-
*
|
|
141
|
-
* // Factory usage (pinned auth):
|
|
142
|
-
* const my${appName} = sdk.apps.${appKey}({ authenticationId: 123 })
|
|
143
|
-
* await my${appName}.search.user_by_email({ inputs: { email } })
|
|
144
|
-
*/
|
|
145
|
-
|
|
146
|
-
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
147
|
-
import { z } from 'zod'
|
|
148
|
-
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
149
|
-
|
|
150
|
-
`;
|
|
151
|
-
// Generate input types for each action
|
|
152
|
-
actions.forEach((action) => {
|
|
153
|
-
if (action.inputFields.length > 0) {
|
|
154
|
-
const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(sanitizeActionName(action.key))}Inputs`;
|
|
155
|
-
output += `interface ${inputTypeName} {\n`;
|
|
156
|
-
action.inputFields.forEach((field) => {
|
|
157
|
-
const isOptional = !field.required;
|
|
158
|
-
const fieldType = mapFieldTypeToTypeScript(field);
|
|
159
|
-
const description = field.helpText
|
|
160
|
-
? ` /** ${escapeComment(field.helpText)} */\n`
|
|
161
|
-
: "";
|
|
162
|
-
output += `${description} ${sanitizeFieldName(field.key)}${isOptional ? "?" : ""}: ${fieldType}\n`;
|
|
163
|
-
});
|
|
164
|
-
output += `}\n\n`;
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
// Generate action type interfaces for each action type
|
|
168
|
-
Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
|
|
169
|
-
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
170
|
-
output += `interface ${typeName} {\n`;
|
|
171
|
-
typeActions.forEach((action) => {
|
|
172
|
-
const actionName = sanitizeActionName(action.key);
|
|
173
|
-
const description = action.description
|
|
174
|
-
? ` /** ${escapeComment(action.description)} */\n`
|
|
175
|
-
: "";
|
|
176
|
-
// Generate type-safe action method signature
|
|
177
|
-
if (action.inputFields.length > 0) {
|
|
178
|
-
const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(sanitizeActionName(action.key))}Inputs`;
|
|
179
|
-
output += `${description} ${actionName}: (options: { inputs: ${inputTypeName} } & Omit<ActionExecutionOptions, 'inputs'>) => Promise<ActionExecutionResult>\n`;
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
// No specific input fields available - use generic Record<string, any> for inputs
|
|
183
|
-
output += `${description} ${actionName}: (options?: { inputs?: Record<string, any> } & ActionExecutionOptions) => Promise<ActionExecutionResult>\n`;
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
output += `}\n\n`;
|
|
187
|
-
});
|
|
188
|
-
// Generate the main app SDK interface with factory pattern support
|
|
189
|
-
// Generate the app proxy interface (actions grouped by type)
|
|
190
|
-
output += `interface ${appName}AppProxy {\n`;
|
|
191
|
-
Object.keys(actionsByType).forEach((actionType) => {
|
|
192
|
-
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
193
|
-
output += ` ${actionType}: ${typeName}\n`;
|
|
194
|
-
});
|
|
195
|
-
// Always include fetch method for authenticated HTTP requests
|
|
196
|
-
output += generateFetchMethodSignature() + "\n";
|
|
197
|
-
output += `}\n\n`;
|
|
198
|
-
// Generate the factory function interface
|
|
199
|
-
output += `interface ${appName}AppFactory {\n`;
|
|
200
|
-
output += ` (options: { authenticationId: number }): ${appName}AppProxy\n`;
|
|
201
|
-
output += `}\n\n`;
|
|
202
|
-
// Combine factory and direct access
|
|
203
|
-
output += `type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy\n\n`;
|
|
204
|
-
// Generate the main SDK interface
|
|
205
|
-
output += `export interface ${appName}Sdk {\n`;
|
|
206
|
-
output += ` apps: {\n`;
|
|
207
|
-
output += ` ${appKey}: ${appName}AppWithFactory\n`;
|
|
208
|
-
output += ` }\n`;
|
|
209
|
-
output += `}\n`;
|
|
210
|
-
return output;
|
|
211
|
-
}
|
|
212
|
-
function generateEmptyTypesFile(appKey, version) {
|
|
213
|
-
const appName = capitalize(appKey);
|
|
214
|
-
const versionComment = version
|
|
215
|
-
? ` * Generated for ${appKey}@${version}`
|
|
216
|
-
: ` * Generated for ${appKey}`;
|
|
217
|
-
return `/* eslint-disable @typescript-eslint/naming-convention */
|
|
218
|
-
/**
|
|
219
|
-
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
220
|
-
${versionComment}
|
|
221
|
-
* Generated on: ${new Date().toISOString()}
|
|
222
|
-
*
|
|
223
|
-
* No actions found for this app.
|
|
224
|
-
*/
|
|
225
|
-
|
|
226
|
-
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
227
|
-
import { z } from 'zod'
|
|
228
|
-
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
229
|
-
|
|
230
|
-
interface ${appName}AppProxy {
|
|
231
|
-
// No actions available
|
|
232
|
-
${generateFetchMethodSignature()}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
interface ${appName}AppFactory {
|
|
236
|
-
(options: { authenticationId: number }): ${appName}AppProxy
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
|
|
240
|
-
|
|
241
|
-
export interface ${appName}Sdk {
|
|
242
|
-
apps: {
|
|
243
|
-
${appKey}: ${appName}AppWithFactory
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
`;
|
|
247
|
-
}
|
|
248
|
-
function capitalize(str) {
|
|
249
|
-
return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
|
|
250
|
-
}
|
|
251
|
-
function sanitizeActionName(actionKey) {
|
|
252
|
-
// Ensure the action name is a valid TypeScript identifier
|
|
253
|
-
let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
254
|
-
// If it starts with a number, prepend an underscore
|
|
255
|
-
if (/^[0-9]/.test(sanitized)) {
|
|
256
|
-
sanitized = "_" + sanitized;
|
|
257
|
-
}
|
|
258
|
-
return sanitized;
|
|
259
|
-
}
|
|
260
|
-
function sanitizeFieldName(fieldKey) {
|
|
261
|
-
// Ensure the field name is a valid TypeScript identifier
|
|
262
|
-
let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
263
|
-
// If it starts with a number, prepend an underscore
|
|
264
|
-
if (/^[0-9]/.test(sanitized)) {
|
|
265
|
-
sanitized = "_" + sanitized;
|
|
266
|
-
}
|
|
267
|
-
return sanitized;
|
|
268
|
-
}
|
|
269
|
-
function escapeComment(comment) {
|
|
270
|
-
// Escape comment text to prevent breaking the JSDoc comment
|
|
271
|
-
return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
272
|
-
}
|
|
273
|
-
function mapFieldTypeToTypeScript(field) {
|
|
274
|
-
// Handle choices (enum-like fields)
|
|
275
|
-
if (field.choices && field.choices.length > 0) {
|
|
276
|
-
const choiceValues = field.choices
|
|
277
|
-
.filter((choice) => choice.value !== undefined &&
|
|
278
|
-
choice.value !== null &&
|
|
279
|
-
choice.value !== "")
|
|
280
|
-
.map((choice) => typeof choice.value === "string" ? `"${choice.value}"` : choice.value);
|
|
281
|
-
if (choiceValues.length > 0) {
|
|
282
|
-
return choiceValues.join(" | ");
|
|
283
|
-
}
|
|
284
|
-
// If all choices were filtered out, fall through to default type handling
|
|
285
|
-
}
|
|
286
|
-
// Map Zapier field types to TypeScript types
|
|
287
|
-
switch (field.type?.toLowerCase()) {
|
|
288
|
-
case "string":
|
|
289
|
-
case "text":
|
|
290
|
-
case "email":
|
|
291
|
-
case "url":
|
|
292
|
-
case "password":
|
|
293
|
-
return "string";
|
|
294
|
-
case "integer":
|
|
295
|
-
case "number":
|
|
296
|
-
return "number";
|
|
297
|
-
case "boolean":
|
|
298
|
-
return "boolean";
|
|
299
|
-
case "datetime":
|
|
300
|
-
case "date":
|
|
301
|
-
return "string"; // ISO date strings
|
|
302
|
-
case "file":
|
|
303
|
-
return "string"; // File URL or content
|
|
304
|
-
case "array":
|
|
305
|
-
return "any[]";
|
|
306
|
-
case "object":
|
|
307
|
-
return "Record<string, any>";
|
|
308
|
-
default:
|
|
309
|
-
// Default to string for unknown types, with union for common cases
|
|
310
|
-
return "string | number | boolean";
|
|
311
|
-
}
|
|
312
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
export declare const GenerateTypesSchema: z.ZodObject<{
|
|
3
|
-
appKey: z.ZodString;
|
|
4
|
-
authenticationId: z.ZodOptional<z.ZodNumber>;
|
|
5
|
-
output: z.ZodOptional<z.ZodString>;
|
|
6
|
-
lockFilePath: z.ZodOptional<z.ZodString>;
|
|
7
|
-
}, "strip", z.ZodTypeAny, {
|
|
8
|
-
appKey: string;
|
|
9
|
-
authenticationId?: number | undefined;
|
|
10
|
-
output?: string | undefined;
|
|
11
|
-
lockFilePath?: string | undefined;
|
|
12
|
-
}, {
|
|
13
|
-
appKey: string;
|
|
14
|
-
authenticationId?: number | undefined;
|
|
15
|
-
output?: string | undefined;
|
|
16
|
-
lockFilePath?: string | undefined;
|
|
17
|
-
}>;
|
|
18
|
-
export type GenerateTypesOptions = z.infer<typeof GenerateTypesSchema>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { AppKeyPropertySchema, AuthenticationIdPropertySchema, OutputPropertySchema, } from "@zapier/zapier-sdk";
|
|
3
|
-
// Generate types schema - mirrors the original from SDK but for CLI use
|
|
4
|
-
export const GenerateTypesSchema = z
|
|
5
|
-
.object({
|
|
6
|
-
appKey: AppKeyPropertySchema.describe("App key to generate SDK code for"),
|
|
7
|
-
authenticationId: AuthenticationIdPropertySchema.optional(),
|
|
8
|
-
output: OutputPropertySchema.optional().describe("Output file path (defaults to generated/<appKey>.ts)"),
|
|
9
|
-
lockFilePath: z
|
|
10
|
-
.string()
|
|
11
|
-
.optional()
|
|
12
|
-
.describe("Path to the .zapierrc lock file (defaults to .zapierrc)"),
|
|
13
|
-
})
|
|
14
|
-
.describe("Generate TypeScript SDK code for a specific app");
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "@zapier/zapier-sdk";
|
|
2
|
-
import { GetConfigPathSchema, type GetConfigPathOptions } from "./schemas";
|
|
3
|
-
export interface GetConfigPathPluginProvides {
|
|
4
|
-
getConfigPath: (options?: GetConfigPathOptions) => Promise<string>;
|
|
5
|
-
context: {
|
|
6
|
-
meta: {
|
|
7
|
-
getConfigPath: {
|
|
8
|
-
inputSchema: typeof GetConfigPathSchema;
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export declare const getConfigPathPlugin: Plugin<{}, // requires no existing SDK methods
|
|
14
|
-
{}, // requires no context
|
|
15
|
-
GetConfigPathPluginProvides>;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { GetConfigPathSchema } from "./schemas";
|
|
2
|
-
import { createFunction } from "@zapier/zapier-sdk";
|
|
3
|
-
import { getConfigPath } from "@zapier/zapier-sdk-cli-login";
|
|
4
|
-
export const getConfigPathPlugin = () => {
|
|
5
|
-
const getConfigPathWithSdk = createFunction(async function getConfigPathWithSdk(_options) {
|
|
6
|
-
return getConfigPath();
|
|
7
|
-
}, GetConfigPathSchema);
|
|
8
|
-
return {
|
|
9
|
-
getConfigPath: getConfigPathWithSdk,
|
|
10
|
-
context: {
|
|
11
|
-
meta: {
|
|
12
|
-
getConfigPath: {
|
|
13
|
-
categories: ["utility"],
|
|
14
|
-
inputSchema: GetConfigPathSchema,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
};
|