@zapier/zapier-sdk-cli 0.13.9 → 0.13.11
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 +16 -0
- package/dist/cli.cjs +121 -104
- package/dist/cli.mjs +124 -107
- package/dist/index.cjs +99 -100
- package/dist/index.d.mts +0 -8
- package/dist/index.d.ts +0 -8
- package/dist/index.mjs +102 -103
- package/dist/package.json +1 -1
- package/dist/src/cli.js +23 -3
- package/dist/src/plugins/add/index.js +0 -8
- package/dist/src/plugins/buildManifest/index.js +12 -12
- package/dist/src/plugins/buildManifest/schemas.d.ts +0 -4
- package/dist/src/plugins/generateAppTypes/index.js +47 -59
- package/dist/src/plugins/generateAppTypes/schemas.d.ts +0 -4
- package/dist/src/plugins/login/index.js +17 -5
- package/dist/src/utils/auth/login.d.ts +7 -1
- package/dist/src/utils/auth/login.js +10 -7
- package/dist/src/utils/constants.d.ts +1 -1
- package/dist/src/utils/constants.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/cli.test.ts +10 -0
- package/src/cli.ts +35 -3
- package/src/plugins/add/index.ts +0 -9
- package/src/plugins/buildManifest/index.test.ts +96 -53
- package/src/plugins/buildManifest/index.ts +17 -14
- package/src/plugins/buildManifest/schemas.ts +0 -4
- package/src/plugins/generateAppTypes/index.test.ts +679 -0
- package/src/plugins/generateAppTypes/index.ts +53 -61
- package/src/plugins/generateAppTypes/schemas.ts +0 -4
- package/src/plugins/login/index.ts +33 -14
- package/src/utils/auth/login.ts +27 -8
- package/src/utils/constants.ts +1 -2
|
@@ -8,7 +8,11 @@ import type {
|
|
|
8
8
|
ManifestPluginProvides,
|
|
9
9
|
AppItem,
|
|
10
10
|
} from "@zapier/zapier-sdk";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
createFunction,
|
|
13
|
+
ZapierValidationError,
|
|
14
|
+
ZapierUnknownError,
|
|
15
|
+
} from "@zapier/zapier-sdk";
|
|
12
16
|
import {
|
|
13
17
|
GenerateAppTypesSchema,
|
|
14
18
|
type GenerateAppTypesOptions,
|
|
@@ -17,7 +21,8 @@ import {
|
|
|
17
21
|
import { AstTypeGenerator } from "../../generators/ast-generator";
|
|
18
22
|
import { getManifestKey } from "../../utils/manifest-helpers";
|
|
19
23
|
import { mkdir, writeFile } from "fs/promises";
|
|
20
|
-
import { join } from "path";
|
|
24
|
+
import { join, resolve } from "path";
|
|
25
|
+
import { detectTypesOutputDirectory } from "../../utils/directory-detection";
|
|
21
26
|
|
|
22
27
|
export interface GenerateAppTypesPluginProvides {
|
|
23
28
|
generateAppTypes: (
|
|
@@ -50,20 +55,14 @@ export const generateAppTypesPlugin: Plugin<
|
|
|
50
55
|
appKeys,
|
|
51
56
|
authenticationIds,
|
|
52
57
|
skipWrite = false,
|
|
53
|
-
typesOutputDirectory,
|
|
58
|
+
typesOutputDirectory = await detectTypesOutputDirectory(),
|
|
54
59
|
onProgress,
|
|
55
60
|
} = options;
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
if (!skipWrite && !typesOutputDirectory) {
|
|
59
|
-
throw new Error(
|
|
60
|
-
"typesOutputDirectory is required when skipWrite is false",
|
|
61
|
-
);
|
|
62
|
-
}
|
|
62
|
+
const resolvedTypesOutput = resolve(typesOutputDirectory);
|
|
63
63
|
|
|
64
64
|
const result: GenerateAppTypesResult = {
|
|
65
65
|
typeDefinitions: {},
|
|
66
|
-
errors: [],
|
|
67
66
|
};
|
|
68
67
|
|
|
69
68
|
// Get apps using listApps (which respects existing manifest for version locking)
|
|
@@ -100,8 +99,8 @@ export const generateAppTypesPlugin: Plugin<
|
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
// Ensure output directory exists if we're writing files
|
|
103
|
-
if (!skipWrite &&
|
|
104
|
-
await mkdir(
|
|
102
|
+
if (!skipWrite && resolvedTypesOutput) {
|
|
103
|
+
await mkdir(resolvedTypesOutput, { recursive: true });
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
// Initialize writtenFiles if we're writing to disk
|
|
@@ -119,17 +118,18 @@ export const generateAppTypesPlugin: Plugin<
|
|
|
119
118
|
|
|
120
119
|
try {
|
|
121
120
|
if (!app.version) {
|
|
122
|
-
const
|
|
123
|
-
result.errors.push({
|
|
124
|
-
appKey: app.key,
|
|
125
|
-
error,
|
|
126
|
-
});
|
|
121
|
+
const errorMessage = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
|
|
127
122
|
onProgress?.({
|
|
128
123
|
type: "app_processing_error",
|
|
129
124
|
appKey: app.key,
|
|
130
|
-
error,
|
|
125
|
+
error: errorMessage,
|
|
126
|
+
});
|
|
127
|
+
throw new ZapierValidationError(errorMessage, {
|
|
128
|
+
details: {
|
|
129
|
+
appKey: app.key,
|
|
130
|
+
implementationId: app.implementation_id,
|
|
131
|
+
},
|
|
131
132
|
});
|
|
132
|
-
continue;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
// Find matching authentication for this app if authentications were provided
|
|
@@ -158,63 +158,55 @@ export const generateAppTypesPlugin: Plugin<
|
|
|
158
158
|
const manifestKey = getManifestKey(app);
|
|
159
159
|
|
|
160
160
|
// Generate type definitions
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
result.typeDefinitions[manifestKey] = typeDefinitionString;
|
|
161
|
+
const generator = new AstTypeGenerator();
|
|
162
|
+
const typeDefinitionString = await generator.generateTypes({
|
|
163
|
+
app,
|
|
164
|
+
authenticationId,
|
|
165
|
+
sdk,
|
|
166
|
+
});
|
|
170
167
|
|
|
171
|
-
|
|
172
|
-
type: "type_generated",
|
|
173
|
-
manifestKey,
|
|
174
|
-
sizeBytes: typeDefinitionString.length,
|
|
175
|
-
});
|
|
168
|
+
result.typeDefinitions[manifestKey] = typeDefinitionString;
|
|
176
169
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
170
|
+
onProgress?.({
|
|
171
|
+
type: "type_generated",
|
|
172
|
+
manifestKey,
|
|
173
|
+
sizeBytes: typeDefinitionString.length,
|
|
174
|
+
});
|
|
181
175
|
|
|
182
|
-
|
|
176
|
+
// Write to file if skipWrite is false
|
|
177
|
+
if (!skipWrite && resolvedTypesOutput && result.writtenFiles) {
|
|
178
|
+
const filePath = join(resolvedTypesOutput, `${manifestKey}.d.ts`);
|
|
179
|
+
await writeFile(filePath, typeDefinitionString, "utf8");
|
|
183
180
|
|
|
184
|
-
|
|
185
|
-
type: "file_written",
|
|
186
|
-
manifestKey,
|
|
187
|
-
filePath,
|
|
188
|
-
});
|
|
189
|
-
}
|
|
181
|
+
result.writtenFiles[manifestKey] = filePath;
|
|
190
182
|
|
|
191
183
|
onProgress?.({
|
|
192
|
-
type: "
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
} catch (error) {
|
|
196
|
-
const errorMessage = `Failed to generate types: ${error}`;
|
|
197
|
-
result.errors.push({
|
|
198
|
-
appKey: app.key,
|
|
199
|
-
error: errorMessage,
|
|
200
|
-
});
|
|
201
|
-
onProgress?.({
|
|
202
|
-
type: "app_processing_error",
|
|
203
|
-
appKey: app.key,
|
|
204
|
-
error: errorMessage,
|
|
184
|
+
type: "file_written",
|
|
185
|
+
manifestKey,
|
|
186
|
+
filePath,
|
|
205
187
|
});
|
|
206
188
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
189
|
+
|
|
190
|
+
onProgress?.({
|
|
191
|
+
type: "app_processing_complete",
|
|
210
192
|
appKey: app.key,
|
|
211
|
-
error: errorMessage,
|
|
212
193
|
});
|
|
194
|
+
} catch (error) {
|
|
195
|
+
const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
|
|
196
|
+
|
|
213
197
|
onProgress?.({
|
|
214
198
|
type: "app_processing_error",
|
|
215
199
|
appKey: app.key,
|
|
216
200
|
error: errorMessage,
|
|
217
201
|
});
|
|
202
|
+
|
|
203
|
+
if (error instanceof ZapierValidationError) {
|
|
204
|
+
throw error; // Preserve the specific error type
|
|
205
|
+
} else {
|
|
206
|
+
throw new ZapierUnknownError(errorMessage, {
|
|
207
|
+
cause: error, // Works for both Error and non-Error
|
|
208
|
+
});
|
|
209
|
+
}
|
|
218
210
|
}
|
|
219
211
|
}
|
|
220
212
|
|
|
@@ -58,8 +58,4 @@ export type AppTypesProgressEvent =
|
|
|
58
58
|
export interface GenerateAppTypesResult {
|
|
59
59
|
typeDefinitions: Record<string, string>; // manifestKey -> type definition string
|
|
60
60
|
writtenFiles?: Record<string, string>; // manifestKey -> file path (only when skipWrite is false)
|
|
61
|
-
errors: Array<{
|
|
62
|
-
appKey: string;
|
|
63
|
-
error: string;
|
|
64
|
-
}>;
|
|
65
61
|
}
|
|
@@ -29,22 +29,36 @@ interface LoginPluginProvides {
|
|
|
29
29
|
const CLI_COMMAND_EXECUTED_EVENT_SUBJECT =
|
|
30
30
|
"platform.sdk.CliCommandExecutedEvent";
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
// Internal type for loginWithSdk that includes SDK URL options
|
|
33
|
+
interface LoginWithSdkOptions extends LoginOptions {
|
|
34
|
+
baseUrl?: string;
|
|
35
|
+
authBaseUrl?: string;
|
|
36
|
+
authClientId?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const loginWithSdk = createFunction(
|
|
40
|
+
async (options: LoginWithSdkOptions): Promise<void> => {
|
|
41
|
+
const timeoutSeconds = options.timeout
|
|
42
|
+
? parseInt(options.timeout, 10)
|
|
43
|
+
: 300;
|
|
44
|
+
if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
45
|
+
throw new Error("Timeout must be a positive number");
|
|
46
|
+
}
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
await login({
|
|
49
|
+
timeoutMs: timeoutSeconds * 1000,
|
|
50
|
+
baseUrl: options.baseUrl,
|
|
51
|
+
authBaseUrl: options.authBaseUrl,
|
|
52
|
+
authClientId: options.authClientId,
|
|
53
|
+
});
|
|
54
|
+
const user = await getLoggedInUser();
|
|
42
55
|
|
|
43
|
-
|
|
56
|
+
console.log(`✅ Successfully logged in as ${user.email}`);
|
|
44
57
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
58
|
+
// Force immediate exit to prevent hanging (especially in development with tsx)
|
|
59
|
+
setTimeout(() => process.exit(0), 100);
|
|
60
|
+
},
|
|
61
|
+
);
|
|
48
62
|
|
|
49
63
|
export const loginPlugin: Plugin<
|
|
50
64
|
{},
|
|
@@ -58,7 +72,12 @@ export const loginPlugin: Plugin<
|
|
|
58
72
|
let errorMessage: string | null = null;
|
|
59
73
|
|
|
60
74
|
try {
|
|
61
|
-
await loginWithSdk(
|
|
75
|
+
await loginWithSdk({
|
|
76
|
+
...options,
|
|
77
|
+
baseUrl: context.options?.baseUrl,
|
|
78
|
+
authBaseUrl: context.options?.authBaseUrl,
|
|
79
|
+
authClientId: context.options?.authClientId,
|
|
80
|
+
});
|
|
62
81
|
success = true;
|
|
63
82
|
} catch (error) {
|
|
64
83
|
success = false;
|
package/src/utils/auth/login.ts
CHANGED
|
@@ -6,16 +6,20 @@ import type { Socket } from "net";
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
AUTH_MODE_HEADER,
|
|
9
|
-
|
|
9
|
+
ZAPIER_AUTH_CLIENT_ID,
|
|
10
10
|
LOGIN_PORTS,
|
|
11
11
|
LOGIN_TIMEOUT_MS,
|
|
12
|
-
ZAPIER_BASE,
|
|
13
12
|
} from "../constants";
|
|
14
13
|
import { spinPromise } from "../spinner";
|
|
15
14
|
import log from "../log";
|
|
16
15
|
import api from "../api/client";
|
|
17
16
|
import getCallablePromise from "../getCallablePromise";
|
|
18
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
updateLogin,
|
|
19
|
+
logout,
|
|
20
|
+
getAuthTokenUrl,
|
|
21
|
+
getAuthAuthorizeUrl,
|
|
22
|
+
} from "@zapier/zapier-sdk-cli-login";
|
|
19
23
|
|
|
20
24
|
const findAvailablePort = (): Promise<number> => {
|
|
21
25
|
return new Promise((resolve, reject) => {
|
|
@@ -62,7 +66,22 @@ const generateRandomString = () => {
|
|
|
62
66
|
).join("");
|
|
63
67
|
};
|
|
64
68
|
|
|
65
|
-
|
|
69
|
+
interface LoginOptions {
|
|
70
|
+
timeoutMs?: number;
|
|
71
|
+
baseUrl?: string;
|
|
72
|
+
authBaseUrl?: string;
|
|
73
|
+
authClientId?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const login = async ({
|
|
77
|
+
timeoutMs = LOGIN_TIMEOUT_MS,
|
|
78
|
+
baseUrl,
|
|
79
|
+
authBaseUrl,
|
|
80
|
+
authClientId,
|
|
81
|
+
}: LoginOptions): Promise<string> => {
|
|
82
|
+
const authOptions = { baseUrl, authBaseUrl };
|
|
83
|
+
const tokenUrl = getAuthTokenUrl(authOptions);
|
|
84
|
+
const authorizeUrl = getAuthAuthorizeUrl(authOptions);
|
|
66
85
|
// Force logout
|
|
67
86
|
logout();
|
|
68
87
|
|
|
@@ -106,9 +125,9 @@ const login = async (timeoutMs: number = LOGIN_TIMEOUT_MS): Promise<string> => {
|
|
|
106
125
|
const { code_verifier: codeVerifier, code_challenge: codeChallenge } =
|
|
107
126
|
await pkceChallenge();
|
|
108
127
|
|
|
109
|
-
const authUrl = `${
|
|
128
|
+
const authUrl = `${authorizeUrl}?${new URLSearchParams({
|
|
110
129
|
response_type: "code",
|
|
111
|
-
client_id:
|
|
130
|
+
client_id: authClientId || ZAPIER_AUTH_CLIENT_ID,
|
|
112
131
|
redirect_uri: redirectUri,
|
|
113
132
|
scope: "internal offline_access",
|
|
114
133
|
state: generateRandomString(),
|
|
@@ -165,12 +184,12 @@ const login = async (timeoutMs: number = LOGIN_TIMEOUT_MS): Promise<string> => {
|
|
|
165
184
|
refresh_token: string;
|
|
166
185
|
expires_in: number;
|
|
167
186
|
}>(
|
|
168
|
-
|
|
187
|
+
tokenUrl,
|
|
169
188
|
{
|
|
170
189
|
grant_type: "authorization_code",
|
|
171
190
|
code: await promisedCode,
|
|
172
191
|
redirect_uri: redirectUri,
|
|
173
|
-
client_id:
|
|
192
|
+
client_id: authClientId || ZAPIER_AUTH_CLIENT_ID,
|
|
174
193
|
code_verifier: codeVerifier,
|
|
175
194
|
},
|
|
176
195
|
{
|