@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/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
- import { createFunction, OutputPropertySchema, DEFAULT_CONFIG_PATH, getOsInfo, getPlatformVersions, getCiPlatform, isCi, createZapierSdkWithoutRegistry, registryPlugin, getReleaseId, getCurrentTimestamp, generateEventId, toSnakeCase } from '@zapier/zapier-sdk';
1
+ import { createFunction, OutputPropertySchema, DEFAULT_CONFIG_PATH, getOsInfo, getPlatformVersions, getCiPlatform, isCi, createZapierSdkWithoutRegistry, registryPlugin, getReleaseId, getCurrentTimestamp, generateEventId, ZapierValidationError, ZapierUnknownError, toSnakeCase } from '@zapier/zapier-sdk';
2
2
  import open from 'open';
3
3
  import crypto from 'crypto';
4
4
  import express from 'express';
5
5
  import pkceChallenge from 'pkce-challenge';
6
- import { getLoggedInUser, logout, ZAPIER_BASE, LOGIN_CLIENT_ID, AUTH_MODE_HEADER, updateLogin, getConfigPath } from '@zapier/zapier-sdk-cli-login';
6
+ import { getLoggedInUser, logout, getAuthTokenUrl, getAuthAuthorizeUrl, ZAPIER_AUTH_CLIENT_ID, AUTH_MODE_HEADER, updateLogin, getConfigPath } from '@zapier/zapier-sdk-cli-login';
7
7
  import ora from 'ora';
8
8
  import chalk from 'chalk';
9
9
  import { z } from 'zod';
@@ -11,7 +11,7 @@ import { startMcpServerAsProcess } from '@zapier/zapier-sdk-mcp';
11
11
  import { buildSync } from 'esbuild';
12
12
  import * as fs from 'fs';
13
13
  import * as path from 'path';
14
- import { join, resolve } from 'path';
14
+ import { resolve, join } from 'path';
15
15
  import { mkdir, writeFile, access } from 'fs/promises';
16
16
  import * as ts from 'typescript';
17
17
 
@@ -76,28 +76,28 @@ var client_default = api;
76
76
 
77
77
  // src/utils/getCallablePromise.ts
78
78
  var getCallablePromise = () => {
79
- let resolve3 = () => {
79
+ let resolve4 = () => {
80
80
  };
81
81
  let reject = () => {
82
82
  };
83
83
  const promise = new Promise((_resolve, _reject) => {
84
- resolve3 = _resolve;
84
+ resolve4 = _resolve;
85
85
  reject = _reject;
86
86
  });
87
87
  return {
88
88
  promise,
89
- resolve: resolve3,
89
+ resolve: resolve4,
90
90
  reject
91
91
  };
92
92
  };
93
93
  var getCallablePromise_default = getCallablePromise;
94
94
  var findAvailablePort = () => {
95
- return new Promise((resolve3, reject) => {
95
+ return new Promise((resolve4, reject) => {
96
96
  let portIndex = 0;
97
97
  const tryPort = (port) => {
98
98
  const server = express().listen(port, () => {
99
99
  server.close();
100
- resolve3(port);
100
+ resolve4(port);
101
101
  });
102
102
  server.on("error", (err) => {
103
103
  if (err.code === "EADDRINUSE") {
@@ -130,7 +130,15 @@ var generateRandomString = () => {
130
130
  (dec) => ("0" + dec.toString(16)).substring(-2)
131
131
  ).join("");
132
132
  };
133
- var login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
133
+ var login = async ({
134
+ timeoutMs = LOGIN_TIMEOUT_MS,
135
+ baseUrl,
136
+ authBaseUrl,
137
+ authClientId
138
+ }) => {
139
+ const authOptions = { baseUrl, authBaseUrl };
140
+ const tokenUrl = getAuthTokenUrl(authOptions);
141
+ const authorizeUrl = getAuthAuthorizeUrl(authOptions);
134
142
  logout();
135
143
  const availablePort = await findAvailablePort();
136
144
  const redirectUri = `http://localhost:${availablePort}/oauth`;
@@ -156,9 +164,9 @@ var login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
156
164
  process.on("SIGINT", cleanup);
157
165
  process.on("SIGTERM", cleanup);
158
166
  const { code_verifier: codeVerifier, code_challenge: codeChallenge } = await pkceChallenge();
159
- const authUrl = `${ZAPIER_BASE}/oauth/authorize/?${new URLSearchParams({
167
+ const authUrl = `${authorizeUrl}?${new URLSearchParams({
160
168
  response_type: "code",
161
- client_id: LOGIN_CLIENT_ID,
169
+ client_id: authClientId || ZAPIER_AUTH_CLIENT_ID,
162
170
  redirect_uri: redirectUri,
163
171
  scope: "internal offline_access",
164
172
  state: generateRandomString(),
@@ -187,26 +195,26 @@ var login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
187
195
  } finally {
188
196
  process.off("SIGINT", cleanup);
189
197
  process.off("SIGTERM", cleanup);
190
- await new Promise((resolve3) => {
198
+ await new Promise((resolve4) => {
191
199
  const timeout = setTimeout(() => {
192
200
  log_default.info("Server close timed out, forcing connection shutdown...");
193
201
  connections.forEach((conn) => conn.destroy());
194
- resolve3();
202
+ resolve4();
195
203
  }, 1e3);
196
204
  server.close(() => {
197
205
  clearTimeout(timeout);
198
- resolve3();
206
+ resolve4();
199
207
  });
200
208
  });
201
209
  }
202
210
  log_default.info("Exchanging authorization code for tokens...");
203
211
  const { data } = await client_default.post(
204
- `${ZAPIER_BASE}/oauth/token/`,
212
+ tokenUrl,
205
213
  {
206
214
  grant_type: "authorization_code",
207
215
  code: await promisedCode,
208
216
  redirect_uri: redirectUri,
209
- client_id: LOGIN_CLIENT_ID,
217
+ client_id: authClientId || ZAPIER_AUTH_CLIENT_ID,
210
218
  code_verifier: codeVerifier
211
219
  },
212
220
  {
@@ -227,7 +235,7 @@ var LoginSchema = z.object({
227
235
 
228
236
  // package.json
229
237
  var package_default = {
230
- version: "0.13.9"};
238
+ version: "0.13.11"};
231
239
 
232
240
  // src/telemetry/builders.ts
233
241
  function createCliBaseEvent(context = {}) {
@@ -285,23 +293,35 @@ function buildCliCommandExecutedEvent({
285
293
 
286
294
  // src/plugins/login/index.ts
287
295
  var CLI_COMMAND_EXECUTED_EVENT_SUBJECT = "platform.sdk.CliCommandExecutedEvent";
288
- var loginWithSdk = createFunction(async function loginWithSdk2(options) {
289
- const timeoutSeconds = options.timeout ? parseInt(options.timeout, 10) : 300;
290
- if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
291
- throw new Error("Timeout must be a positive number");
296
+ var loginWithSdk = createFunction(
297
+ async (options) => {
298
+ const timeoutSeconds = options.timeout ? parseInt(options.timeout, 10) : 300;
299
+ if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
300
+ throw new Error("Timeout must be a positive number");
301
+ }
302
+ await login_default({
303
+ timeoutMs: timeoutSeconds * 1e3,
304
+ baseUrl: options.baseUrl,
305
+ authBaseUrl: options.authBaseUrl,
306
+ authClientId: options.authClientId
307
+ });
308
+ const user = await getLoggedInUser();
309
+ console.log(`\u2705 Successfully logged in as ${user.email}`);
310
+ setTimeout(() => process.exit(0), 100);
292
311
  }
293
- await login_default(timeoutSeconds * 1e3);
294
- const user = await getLoggedInUser();
295
- console.log(`\u2705 Successfully logged in as ${user.email}`);
296
- setTimeout(() => process.exit(0), 100);
297
- }, LoginSchema);
312
+ );
298
313
  var loginPlugin = ({ context }) => {
299
314
  const loginWithTelemetry = async (options) => {
300
315
  const startTime = Date.now();
301
316
  let success = false;
302
317
  let errorMessage = null;
303
318
  try {
304
- await loginWithSdk(options);
319
+ await loginWithSdk({
320
+ ...options,
321
+ baseUrl: context.options?.baseUrl,
322
+ authBaseUrl: context.options?.authBaseUrl,
323
+ authClientId: context.options?.authClientId
324
+ });
305
325
  success = true;
306
326
  } catch (error) {
307
327
  success = false;
@@ -618,14 +638,6 @@ var addPlugin = ({ sdk }) => {
618
638
  if (successfulApps.length > 0) {
619
639
  console.log(`\u2705 Added ${successfulApps.length} app(s) to manifest`);
620
640
  }
621
- const allErrors = [...manifestResult.errors, ...typesResult.errors];
622
- if (allErrors.length > 0) {
623
- console.warn(`
624
- \u26A0\uFE0F ${allErrors.length} error(s) occurred:`);
625
- allErrors.forEach(({ appKey, error }) => {
626
- console.warn(` - ${appKey}: ${error}`);
627
- });
628
- }
629
641
  }, AddSchema);
630
642
  return {
631
643
  add,
@@ -1245,17 +1257,12 @@ var generateAppTypesPlugin = ({ sdk }) => {
1245
1257
  appKeys,
1246
1258
  authenticationIds,
1247
1259
  skipWrite = false,
1248
- typesOutputDirectory,
1260
+ typesOutputDirectory = await detectTypesOutputDirectory(),
1249
1261
  onProgress
1250
1262
  } = options;
1251
- if (!skipWrite && !typesOutputDirectory) {
1252
- throw new Error(
1253
- "typesOutputDirectory is required when skipWrite is false"
1254
- );
1255
- }
1263
+ const resolvedTypesOutput = resolve(typesOutputDirectory);
1256
1264
  const result = {
1257
- typeDefinitions: {},
1258
- errors: []
1265
+ typeDefinitions: {}
1259
1266
  };
1260
1267
  onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
1261
1268
  const appsIterator = sdk.listApps({ appKeys }).items();
@@ -1283,8 +1290,8 @@ var generateAppTypesPlugin = ({ sdk }) => {
1283
1290
  count: authentications.length
1284
1291
  });
1285
1292
  }
1286
- if (!skipWrite && typesOutputDirectory) {
1287
- await mkdir(typesOutputDirectory, { recursive: true });
1293
+ if (!skipWrite && resolvedTypesOutput) {
1294
+ await mkdir(resolvedTypesOutput, { recursive: true });
1288
1295
  }
1289
1296
  if (!skipWrite) {
1290
1297
  result.writtenFiles = {};
@@ -1297,17 +1304,18 @@ var generateAppTypesPlugin = ({ sdk }) => {
1297
1304
  });
1298
1305
  try {
1299
1306
  if (!app.version) {
1300
- const error = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
1301
- result.errors.push({
1302
- appKey: app.key,
1303
- error
1304
- });
1307
+ const errorMessage = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
1305
1308
  onProgress?.({
1306
1309
  type: "app_processing_error",
1307
1310
  appKey: app.key,
1308
- error
1311
+ error: errorMessage
1312
+ });
1313
+ throw new ZapierValidationError(errorMessage, {
1314
+ details: {
1315
+ appKey: app.key,
1316
+ implementationId: app.implementation_id
1317
+ }
1309
1318
  });
1310
- continue;
1311
1319
  }
1312
1320
  let authenticationId;
1313
1321
  if (authentications.length > 0) {
@@ -1330,56 +1338,47 @@ var generateAppTypesPlugin = ({ sdk }) => {
1330
1338
  }
1331
1339
  }
1332
1340
  const manifestKey = getManifestKey(app);
1333
- try {
1334
- const generator = new AstTypeGenerator();
1335
- const typeDefinitionString = await generator.generateTypes({
1336
- app,
1337
- authenticationId,
1338
- sdk
1339
- });
1340
- result.typeDefinitions[manifestKey] = typeDefinitionString;
1341
+ const generator = new AstTypeGenerator();
1342
+ const typeDefinitionString = await generator.generateTypes({
1343
+ app,
1344
+ authenticationId,
1345
+ sdk
1346
+ });
1347
+ result.typeDefinitions[manifestKey] = typeDefinitionString;
1348
+ onProgress?.({
1349
+ type: "type_generated",
1350
+ manifestKey,
1351
+ sizeBytes: typeDefinitionString.length
1352
+ });
1353
+ if (!skipWrite && resolvedTypesOutput && result.writtenFiles) {
1354
+ const filePath = join(resolvedTypesOutput, `${manifestKey}.d.ts`);
1355
+ await writeFile(filePath, typeDefinitionString, "utf8");
1356
+ result.writtenFiles[manifestKey] = filePath;
1341
1357
  onProgress?.({
1342
- type: "type_generated",
1358
+ type: "file_written",
1343
1359
  manifestKey,
1344
- sizeBytes: typeDefinitionString.length
1345
- });
1346
- if (!skipWrite && typesOutputDirectory && result.writtenFiles) {
1347
- const filePath = join(typesOutputDirectory, `${manifestKey}.d.ts`);
1348
- await writeFile(filePath, typeDefinitionString, "utf8");
1349
- result.writtenFiles[manifestKey] = filePath;
1350
- onProgress?.({
1351
- type: "file_written",
1352
- manifestKey,
1353
- filePath
1354
- });
1355
- }
1356
- onProgress?.({
1357
- type: "app_processing_complete",
1358
- appKey: app.key
1359
- });
1360
- } catch (error) {
1361
- const errorMessage = `Failed to generate types: ${error}`;
1362
- result.errors.push({
1363
- appKey: app.key,
1364
- error: errorMessage
1365
- });
1366
- onProgress?.({
1367
- type: "app_processing_error",
1368
- appKey: app.key,
1369
- error: errorMessage
1360
+ filePath
1370
1361
  });
1371
1362
  }
1372
- } catch (error) {
1373
- const errorMessage = `Failed to process app: ${error}`;
1374
- result.errors.push({
1375
- appKey: app.key,
1376
- error: errorMessage
1363
+ onProgress?.({
1364
+ type: "app_processing_complete",
1365
+ appKey: app.key
1377
1366
  });
1367
+ } catch (error) {
1368
+ const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
1378
1369
  onProgress?.({
1379
1370
  type: "app_processing_error",
1380
1371
  appKey: app.key,
1381
1372
  error: errorMessage
1382
1373
  });
1374
+ if (error instanceof ZapierValidationError) {
1375
+ throw error;
1376
+ } else {
1377
+ throw new ZapierUnknownError(errorMessage, {
1378
+ cause: error
1379
+ // Works for both Error and non-Error
1380
+ });
1381
+ }
1383
1382
  }
1384
1383
  }
1385
1384
  return result;
@@ -1414,9 +1413,6 @@ var BuildManifestSchema = z.object({
1414
1413
  var buildManifestPlugin = ({ sdk, context }) => {
1415
1414
  const buildManifest = createFunction(async function buildManifest2(options) {
1416
1415
  const { appKeys, skipWrite = false, configPath, onProgress } = options;
1417
- const result = {
1418
- errors: []
1419
- };
1420
1416
  onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
1421
1417
  const appsIterator = sdk.listApps({ appKeys }).items();
1422
1418
  const apps = [];
@@ -1426,7 +1422,7 @@ var buildManifestPlugin = ({ sdk, context }) => {
1426
1422
  }
1427
1423
  onProgress?.({ type: "apps_lookup_complete", count: apps.length });
1428
1424
  if (apps.length === 0) {
1429
- return result;
1425
+ return {};
1430
1426
  }
1431
1427
  let updatedManifest;
1432
1428
  for (const app of apps) {
@@ -1459,20 +1455,23 @@ var buildManifestPlugin = ({ sdk, context }) => {
1459
1455
  });
1460
1456
  onProgress?.({ type: "app_processing_complete", appKey: app.key });
1461
1457
  } catch (error) {
1462
- const errorMessage = `Failed to process app: ${error}`;
1463
- result.errors.push({
1464
- appKey: app.key,
1465
- error: errorMessage
1466
- });
1458
+ const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
1467
1459
  onProgress?.({
1468
1460
  type: "app_processing_error",
1469
1461
  appKey: app.key,
1470
1462
  error: errorMessage
1471
1463
  });
1464
+ if (error instanceof ZapierValidationError) {
1465
+ throw error;
1466
+ } else {
1467
+ throw new ZapierUnknownError(errorMessage, {
1468
+ cause: error
1469
+ // Works for both Error and non-Error
1470
+ });
1471
+ }
1472
1472
  }
1473
1473
  }
1474
- result.manifest = updatedManifest;
1475
- return result;
1474
+ return { manifest: updatedManifest };
1476
1475
  }, BuildManifestSchema);
1477
1476
  return {
1478
1477
  buildManifest,
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk-cli",
3
- "version": "0.13.9",
3
+ "version": "0.13.11",
4
4
  "description": "Command line interface for Zapier SDK",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
package/dist/src/cli.js CHANGED
@@ -8,12 +8,32 @@ program
8
8
  .name("zapier-sdk")
9
9
  .description("CLI for Zapier SDK")
10
10
  .version(packageJson.version, "-v, --version", "display version number")
11
- .option("--debug", "Enable debug logging");
12
- // Check for debug flag early
11
+ .option("--debug", "Enable debug logging")
12
+ .option("--base-url <url>", "Base URL for Zapier API endpoints")
13
+ .option("--auth-base-url <url>", "Base URL for Zapier authentication endpoints")
14
+ .option("--auth-client-id <id>", "OAuth client ID for Zapier authentication")
15
+ .option("--tracking-base-url <url>", "Base URL for Zapier tracking endpoints");
16
+ // Check for debug flag early (support both flag and env var)
13
17
  const isDebugMode = process.env.DEBUG === "true" || process.argv.includes("--debug");
14
- // Create CLI SDK instance with all plugins
18
+ // Extract URL options from process.argv for early SDK creation
19
+ // We need to create the SDK before parsing to generate commands from schemas
20
+ const baseUrlIndex = process.argv.indexOf("--base-url");
21
+ const authBaseUrlIndex = process.argv.indexOf("--auth-base-url");
22
+ const authClientIdIndex = process.argv.indexOf("--auth-client-id");
23
+ const trackingBaseUrlIndex = process.argv.indexOf("--tracking-base-url");
24
+ const baseUrl = baseUrlIndex !== -1 ? process.argv[baseUrlIndex + 1] : undefined;
25
+ const authBaseUrl = authBaseUrlIndex !== -1 ? process.argv[authBaseUrlIndex + 1] : undefined;
26
+ const authClientId = authClientIdIndex !== -1 ? process.argv[authClientIdIndex + 1] : undefined;
27
+ const trackingBaseUrl = trackingBaseUrlIndex !== -1
28
+ ? process.argv[trackingBaseUrlIndex + 1]
29
+ : undefined;
30
+ // Create CLI SDK instance with all plugins and URL options
15
31
  const sdk = createZapierCliSdk({
16
32
  debug: isDebugMode,
33
+ baseUrl,
34
+ authBaseUrl,
35
+ authClientId,
36
+ trackingBaseUrl,
17
37
  });
18
38
  // Auth commands now handled by plugins
19
39
  // Generate CLI commands from SDK schemas (including CLI plugins)
@@ -88,14 +88,6 @@ export const addPlugin = ({ sdk }) => {
88
88
  if (successfulApps.length > 0) {
89
89
  console.log(`✅ Added ${successfulApps.length} app(s) to manifest`);
90
90
  }
91
- // Report any errors
92
- const allErrors = [...manifestResult.errors, ...typesResult.errors];
93
- if (allErrors.length > 0) {
94
- console.warn(`\n⚠️ ${allErrors.length} error(s) occurred:`);
95
- allErrors.forEach(({ appKey, error }) => {
96
- console.warn(` - ${appKey}: ${error}`);
97
- });
98
- }
99
91
  }, AddSchema);
100
92
  return {
101
93
  add,
@@ -1,12 +1,9 @@
1
- import { createFunction } from "@zapier/zapier-sdk";
1
+ import { createFunction, ZapierValidationError, ZapierUnknownError, } from "@zapier/zapier-sdk";
2
2
  import { BuildManifestSchema, } from "./schemas";
3
3
  import { createManifestEntry } from "../../utils/manifest-helpers";
4
4
  export const buildManifestPlugin = ({ sdk, context }) => {
5
5
  const buildManifest = createFunction(async function buildManifest(options) {
6
6
  const { appKeys, skipWrite = false, configPath, onProgress } = options;
7
- const result = {
8
- errors: [],
9
- };
10
7
  // Get apps using listApps (which respects existing manifest for version locking)
11
8
  onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
12
9
  const appsIterator = sdk.listApps({ appKeys }).items();
@@ -17,7 +14,7 @@ export const buildManifestPlugin = ({ sdk, context }) => {
17
14
  }
18
15
  onProgress?.({ type: "apps_lookup_complete", count: apps.length });
19
16
  if (apps.length === 0) {
20
- return result;
17
+ return {};
21
18
  }
22
19
  let updatedManifest;
23
20
  // Process each app
@@ -52,20 +49,23 @@ export const buildManifestPlugin = ({ sdk, context }) => {
52
49
  onProgress?.({ type: "app_processing_complete", appKey: app.key });
53
50
  }
54
51
  catch (error) {
55
- const errorMessage = `Failed to process app: ${error}`;
56
- result.errors.push({
57
- appKey: app.key,
58
- error: errorMessage,
59
- });
52
+ const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
60
53
  onProgress?.({
61
54
  type: "app_processing_error",
62
55
  appKey: app.key,
63
56
  error: errorMessage,
64
57
  });
58
+ if (error instanceof ZapierValidationError) {
59
+ throw error; // Preserve the specific error type
60
+ }
61
+ else {
62
+ throw new ZapierUnknownError(errorMessage, {
63
+ cause: error, // Works for both Error and non-Error
64
+ });
65
+ }
65
66
  }
66
67
  }
67
- result.manifest = updatedManifest;
68
- return result;
68
+ return { manifest: updatedManifest };
69
69
  }, BuildManifestSchema);
70
70
  return {
71
71
  buildManifest,
@@ -49,8 +49,4 @@ export type ManifestBuildProgressEvent = {
49
49
  };
50
50
  export interface BuildManifestResult {
51
51
  manifest?: Manifest;
52
- errors: Array<{
53
- appKey: string;
54
- error: string;
55
- }>;
56
52
  }
@@ -1,19 +1,16 @@
1
- import { createFunction } from "@zapier/zapier-sdk";
1
+ import { createFunction, ZapierValidationError, ZapierUnknownError, } from "@zapier/zapier-sdk";
2
2
  import { GenerateAppTypesSchema, } from "./schemas";
3
3
  import { AstTypeGenerator } from "../../generators/ast-generator";
4
4
  import { getManifestKey } from "../../utils/manifest-helpers";
5
5
  import { mkdir, writeFile } from "fs/promises";
6
- import { join } from "path";
6
+ import { join, resolve } from "path";
7
+ import { detectTypesOutputDirectory } from "../../utils/directory-detection";
7
8
  export const generateAppTypesPlugin = ({ sdk }) => {
8
9
  const generateAppTypes = createFunction(async function generateAppTypes(options) {
9
- const { appKeys, authenticationIds, skipWrite = false, typesOutputDirectory, onProgress, } = options;
10
- // Validate that typesOutputDirectory is provided when skipWrite is false
11
- if (!skipWrite && !typesOutputDirectory) {
12
- throw new Error("typesOutputDirectory is required when skipWrite is false");
13
- }
10
+ const { appKeys, authenticationIds, skipWrite = false, typesOutputDirectory = await detectTypesOutputDirectory(), onProgress, } = options;
11
+ const resolvedTypesOutput = resolve(typesOutputDirectory);
14
12
  const result = {
15
13
  typeDefinitions: {},
16
- errors: [],
17
14
  };
18
15
  // Get apps using listApps (which respects existing manifest for version locking)
19
16
  onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
@@ -46,8 +43,8 @@ export const generateAppTypesPlugin = ({ sdk }) => {
46
43
  });
47
44
  }
48
45
  // Ensure output directory exists if we're writing files
49
- if (!skipWrite && typesOutputDirectory) {
50
- await mkdir(typesOutputDirectory, { recursive: true });
46
+ if (!skipWrite && resolvedTypesOutput) {
47
+ await mkdir(resolvedTypesOutput, { recursive: true });
51
48
  }
52
49
  // Initialize writtenFiles if we're writing to disk
53
50
  if (!skipWrite) {
@@ -62,17 +59,18 @@ export const generateAppTypesPlugin = ({ sdk }) => {
62
59
  });
63
60
  try {
64
61
  if (!app.version) {
65
- const error = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
66
- result.errors.push({
67
- appKey: app.key,
68
- error,
69
- });
62
+ const errorMessage = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
70
63
  onProgress?.({
71
64
  type: "app_processing_error",
72
65
  appKey: app.key,
73
- error,
66
+ error: errorMessage,
67
+ });
68
+ throw new ZapierValidationError(errorMessage, {
69
+ details: {
70
+ appKey: app.key,
71
+ implementationId: app.implementation_id,
72
+ },
74
73
  });
75
- continue;
76
74
  }
77
75
  // Find matching authentication for this app if authentications were provided
78
76
  let authenticationId;
@@ -98,59 +96,49 @@ export const generateAppTypesPlugin = ({ sdk }) => {
98
96
  }
99
97
  const manifestKey = getManifestKey(app);
100
98
  // Generate type definitions
101
- try {
102
- const generator = new AstTypeGenerator();
103
- const typeDefinitionString = await generator.generateTypes({
104
- app,
105
- authenticationId,
106
- sdk,
107
- });
108
- result.typeDefinitions[manifestKey] = typeDefinitionString;
99
+ const generator = new AstTypeGenerator();
100
+ const typeDefinitionString = await generator.generateTypes({
101
+ app,
102
+ authenticationId,
103
+ sdk,
104
+ });
105
+ result.typeDefinitions[manifestKey] = typeDefinitionString;
106
+ onProgress?.({
107
+ type: "type_generated",
108
+ manifestKey,
109
+ sizeBytes: typeDefinitionString.length,
110
+ });
111
+ // Write to file if skipWrite is false
112
+ if (!skipWrite && resolvedTypesOutput && result.writtenFiles) {
113
+ const filePath = join(resolvedTypesOutput, `${manifestKey}.d.ts`);
114
+ await writeFile(filePath, typeDefinitionString, "utf8");
115
+ result.writtenFiles[manifestKey] = filePath;
109
116
  onProgress?.({
110
- type: "type_generated",
117
+ type: "file_written",
111
118
  manifestKey,
112
- sizeBytes: typeDefinitionString.length,
113
- });
114
- // Write to file if skipWrite is false
115
- if (!skipWrite && typesOutputDirectory && result.writtenFiles) {
116
- const filePath = join(typesOutputDirectory, `${manifestKey}.d.ts`);
117
- await writeFile(filePath, typeDefinitionString, "utf8");
118
- result.writtenFiles[manifestKey] = filePath;
119
- onProgress?.({
120
- type: "file_written",
121
- manifestKey,
122
- filePath,
123
- });
124
- }
125
- onProgress?.({
126
- type: "app_processing_complete",
127
- appKey: app.key,
128
- });
129
- }
130
- catch (error) {
131
- const errorMessage = `Failed to generate types: ${error}`;
132
- result.errors.push({
133
- appKey: app.key,
134
- error: errorMessage,
135
- });
136
- onProgress?.({
137
- type: "app_processing_error",
138
- appKey: app.key,
139
- error: errorMessage,
119
+ filePath,
140
120
  });
141
121
  }
142
- }
143
- catch (error) {
144
- const errorMessage = `Failed to process app: ${error}`;
145
- result.errors.push({
122
+ onProgress?.({
123
+ type: "app_processing_complete",
146
124
  appKey: app.key,
147
- error: errorMessage,
148
125
  });
126
+ }
127
+ catch (error) {
128
+ const errorMessage = `Failed to process app ${app.key}: ${error instanceof Error ? error.message : String(error)}`;
149
129
  onProgress?.({
150
130
  type: "app_processing_error",
151
131
  appKey: app.key,
152
132
  error: errorMessage,
153
133
  });
134
+ if (error instanceof ZapierValidationError) {
135
+ throw error; // Preserve the specific error type
136
+ }
137
+ else {
138
+ throw new ZapierUnknownError(errorMessage, {
139
+ cause: error, // Works for both Error and non-Error
140
+ });
141
+ }
154
142
  }
155
143
  }
156
144
  return result;
@@ -65,8 +65,4 @@ export type AppTypesProgressEvent = {
65
65
  export interface GenerateAppTypesResult {
66
66
  typeDefinitions: Record<string, string>;
67
67
  writtenFiles?: Record<string, string>;
68
- errors: Array<{
69
- appKey: string;
70
- error: string;
71
- }>;
72
68
  }